From fe2b9314ea0e0f0c093fda740075e949866509be Mon Sep 17 00:00:00 2001 From: artunit Date: Wed, 29 Sep 2010 03:51:42 +0000 Subject: [PATCH] adding cocoon opensrf authentication setup git-svn-id: svn://svn.open-ils.org/ILS-Contrib/conifer/branches/rel_1_6_1@1019 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- tools/authcon/README | 80 + tools/authcon/auth/content/auth.xml | 9 + tools/authcon/auth/content/kickoff.xml | 9 + tools/authcon/auth/content/opensrf.xml | 16 + tools/authcon/auth/flow/auth.js | 95 + tools/authcon/auth/flow/md5.js | 206 ++ tools/authcon/auth/flow/opensrf.js | 186 ++ tools/authcon/auth/flow/util.js | 277 +++ tools/authcon/auth/forms/auth.xml | 38 + tools/authcon/auth/forms/auth_template.xml | 44 + tools/authcon/auth/images/Thumbs.db | Bin 0 -> 26112 bytes tools/authcon/auth/images/bback.gif | Bin 0 -> 799 bytes tools/authcon/auth/images/booking.gif | Bin 0 -> 1047 bytes tools/authcon/auth/images/button.jpg | Bin 0 -> 851 bytes tools/authcon/auth/images/cal.gif | Bin 0 -> 950 bytes tools/authcon/auth/images/cancel.gif | Bin 0 -> 1233 bytes tools/authcon/auth/images/delete.gif | Bin 0 -> 842 bytes tools/authcon/auth/images/eiu.jpg | Bin 0 -> 41349 bytes tools/authcon/auth/images/end.gif | Bin 0 -> 862 bytes tools/authcon/auth/images/help.gif | Bin 0 -> 868 bytes tools/authcon/auth/images/loginwin.gif | Bin 0 -> 4304 bytes tools/authcon/auth/images/move_down.gif | Bin 0 -> 842 bytes tools/authcon/auth/images/move_up.gif | Bin 0 -> 842 bytes tools/authcon/auth/images/new.gif | Bin 0 -> 842 bytes tools/authcon/auth/images/ok.gif | Bin 0 -> 1061 bytes tools/authcon/auth/images/start.gif | Bin 0 -> 861 bytes tools/authcon/auth/images/status.gif | Bin 0 -> 1043 bytes tools/authcon/auth/images/update.gif | Bin 0 -> 1078 bytes tools/authcon/auth/images/zap.gif | Bin 0 -> 1053 bytes tools/authcon/auth/resources/blank_btn.gif | Bin 0 -> 824 bytes tools/authcon/auth/resources/cal.gif | Bin 0 -> 950 bytes tools/authcon/auth/resources/close.gif | Bin 0 -> 874 bytes tools/authcon/auth/resources/close.gif.old | Bin 0 -> 51 bytes tools/authcon/auth/resources/def2binding.xsl | 82 + tools/authcon/auth/resources/delete.gif | Bin 0 -> 842 bytes .../resources/forms-advanced-field-styling.xsl | 184 ++ .../auth/resources/forms-calendar-styling.xsl | 99 + tools/authcon/auth/resources/forms-calendar.css | 92 + .../authcon/auth/resources/forms-field-styling.xsl | 554 +++++ .../auth/resources/forms-htmlarea-styling.xsl | 69 + tools/authcon/auth/resources/forms-lib.js | 195 ++ .../authcon/auth/resources/forms-page-styling.xsl | 353 ++++ .../auth/resources/forms-samples-styling.xsl | 47 + tools/authcon/auth/resources/forms.css | 75 + tools/authcon/auth/resources/help.gif | Bin 0 -> 868 bytes tools/authcon/auth/resources/htmlarea/.project | 11 + tools/authcon/auth/resources/htmlarea/ChangeLog | 1185 +++++++++++ tools/authcon/auth/resources/htmlarea/dialog.js | 72 + tools/authcon/auth/resources/htmlarea/htmlarea.css | 180 ++ tools/authcon/auth/resources/htmlarea/htmlarea.js | 2175 ++++++++++++++++++++ .../auth/resources/htmlarea/images/ed_about.gif | Bin 0 -> 87 bytes .../resources/htmlarea/images/ed_align_center.gif | Bin 0 -> 69 bytes .../resources/htmlarea/images/ed_align_justify.gif | Bin 0 -> 69 bytes .../resources/htmlarea/images/ed_align_left.gif | Bin 0 -> 69 bytes .../resources/htmlarea/images/ed_align_right.gif | Bin 0 -> 68 bytes .../auth/resources/htmlarea/images/ed_blank.gif | Bin 0 -> 56 bytes .../auth/resources/htmlarea/images/ed_charmap.gif | Bin 0 -> 143 bytes .../auth/resources/htmlarea/images/ed_color_bg.gif | Bin 0 -> 181 bytes .../auth/resources/htmlarea/images/ed_color_fg.gif | Bin 0 -> 171 bytes .../auth/resources/htmlarea/images/ed_copy.gif | Bin 0 -> 110 bytes .../auth/resources/htmlarea/images/ed_custom.gif | Bin 0 -> 67 bytes .../auth/resources/htmlarea/images/ed_cut.gif | Bin 0 -> 91 bytes .../auth/resources/htmlarea/images/ed_delete.gif | Bin 0 -> 90 bytes .../resources/htmlarea/images/ed_format_bold.gif | Bin 0 -> 74 bytes .../resources/htmlarea/images/ed_format_italic.gif | Bin 0 -> 77 bytes .../resources/htmlarea/images/ed_format_strike.gif | Bin 0 -> 78 bytes .../resources/htmlarea/images/ed_format_sub.gif | Bin 0 -> 78 bytes .../resources/htmlarea/images/ed_format_sup.gif | Bin 0 -> 77 bytes .../htmlarea/images/ed_format_underline.gif | Bin 0 -> 85 bytes .../auth/resources/htmlarea/images/ed_help.gif | Bin 0 -> 70 bytes .../auth/resources/htmlarea/images/ed_hr.gif | Bin 0 -> 70 bytes .../auth/resources/htmlarea/images/ed_html.gif | Bin 0 -> 75 bytes .../auth/resources/htmlarea/images/ed_image.gif | Bin 0 -> 148 bytes .../resources/htmlarea/images/ed_indent_less.gif | Bin 0 -> 87 bytes .../resources/htmlarea/images/ed_indent_more.gif | Bin 0 -> 87 bytes .../resources/htmlarea/images/ed_left_to_right.gif | Bin 0 -> 89 bytes .../auth/resources/htmlarea/images/ed_link.gif | Bin 0 -> 97 bytes .../resources/htmlarea/images/ed_list_bullet.gif | Bin 0 -> 80 bytes .../auth/resources/htmlarea/images/ed_list_num.gif | Bin 0 -> 82 bytes .../auth/resources/htmlarea/images/ed_paste.gif | Bin 0 -> 139 bytes .../auth/resources/htmlarea/images/ed_redo.gif | Bin 0 -> 80 bytes .../resources/htmlarea/images/ed_right_to_left.gif | Bin 0 -> 88 bytes .../auth/resources/htmlarea/images/ed_save.gif | Bin 0 -> 143 bytes .../auth/resources/htmlarea/images/ed_save.png | Bin 0 -> 230 bytes .../resources/htmlarea/images/ed_show_border.gif | Bin 0 -> 104 bytes .../auth/resources/htmlarea/images/ed_splitcel.gif | Bin 0 -> 143 bytes .../auth/resources/htmlarea/images/ed_undo.gif | Bin 0 -> 81 bytes .../htmlarea/images/fullscreen_maximize.gif | Bin 0 -> 97 bytes .../htmlarea/images/fullscreen_minimize.gif | Bin 0 -> 97 bytes .../resources/htmlarea/images/insert_table.gif | Bin 0 -> 121 bytes .../auth/resources/htmlarea/images/makefile.xml | 4 + tools/authcon/auth/resources/htmlarea/index.html | 199 ++ tools/authcon/auth/resources/htmlarea/lang/b5.js | 36 + tools/authcon/auth/resources/htmlarea/lang/cz.js | 63 + tools/authcon/auth/resources/htmlarea/lang/da.js | 38 + tools/authcon/auth/resources/htmlarea/lang/de.js | 54 + tools/authcon/auth/resources/htmlarea/lang/ee.js | 63 + tools/authcon/auth/resources/htmlarea/lang/el.js | 75 + tools/authcon/auth/resources/htmlarea/lang/en.js | 88 + tools/authcon/auth/resources/htmlarea/lang/es.js | 51 + tools/authcon/auth/resources/htmlarea/lang/fi.js | 46 + tools/authcon/auth/resources/htmlarea/lang/fr.js | 61 + tools/authcon/auth/resources/htmlarea/lang/gb.js | 36 + tools/authcon/auth/resources/htmlarea/lang/he.js | 63 + tools/authcon/auth/resources/htmlarea/lang/hu.js | 63 + tools/authcon/auth/resources/htmlarea/lang/it.js | 54 + .../authcon/auth/resources/htmlarea/lang/ja-euc.js | 37 + .../authcon/auth/resources/htmlarea/lang/ja-jis.js | 37 + .../auth/resources/htmlarea/lang/ja-sjis.js | 37 + .../auth/resources/htmlarea/lang/ja-utf8.js | 37 + tools/authcon/auth/resources/htmlarea/lang/lt.js | 55 + tools/authcon/auth/resources/htmlarea/lang/lv.js | 55 + .../auth/resources/htmlarea/lang/makefile.xml | 4 + tools/authcon/auth/resources/htmlarea/lang/nb.js | 36 + tools/authcon/auth/resources/htmlarea/lang/nl.js | 90 + tools/authcon/auth/resources/htmlarea/lang/no.js | 79 + tools/authcon/auth/resources/htmlarea/lang/pl.js | 36 + .../authcon/auth/resources/htmlarea/lang/pt_br.js | 37 + tools/authcon/auth/resources/htmlarea/lang/ro.js | 80 + tools/authcon/auth/resources/htmlarea/lang/ru.js | 63 + tools/authcon/auth/resources/htmlarea/lang/se.js | 38 + tools/authcon/auth/resources/htmlarea/lang/si.js | 63 + tools/authcon/auth/resources/htmlarea/lang/vn.js | 51 + tools/authcon/auth/resources/htmlarea/license.txt | 30 + .../auth/resources/htmlarea/make-release.pl | 263 +++ tools/authcon/auth/resources/htmlarea/makefile.xml | 20 + .../auth/resources/htmlarea/plugins/CSS/css.js | 116 ++ .../auth/resources/htmlarea/plugins/CSS/lang/en.js | 2 + .../htmlarea/plugins/CSS/lang/makefile.xml | 5 + .../resources/htmlarea/plugins/CSS/makefile.xml | 7 + .../resources/htmlarea/plugins/ContextMenu/1.pl | 38 + .../htmlarea/plugins/ContextMenu/context-menu.js | 416 ++++ .../htmlarea/plugins/ContextMenu/lang/de.js | 59 + .../htmlarea/plugins/ContextMenu/lang/el.js | 57 + .../htmlarea/plugins/ContextMenu/lang/en.js | 66 + .../htmlarea/plugins/ContextMenu/lang/makefile.xml | 4 + .../htmlarea/plugins/ContextMenu/lang/nl.js | 66 + .../htmlarea/plugins/ContextMenu/makefile.xml | 7 + .../htmlarea/plugins/ContextMenu/menu.css | 64 + .../htmlarea/plugins/FullPage/full-page.js | 143 ++ .../htmlarea/plugins/FullPage/img/docprop.gif | Bin 0 -> 302 bytes .../htmlarea/plugins/FullPage/img/makefile.xml | 4 + .../resources/htmlarea/plugins/FullPage/lang/en.js | 25 + .../htmlarea/plugins/FullPage/lang/makefile.xml | 4 + .../resources/htmlarea/plugins/FullPage/lang/ro.js | 25 + .../htmlarea/plugins/FullPage/makefile.xml | 9 + .../htmlarea/plugins/FullPage/popups/docprop.html | 131 ++ .../htmlarea/plugins/FullPage/popups/makefile.xml | 5 + .../resources/htmlarea/plugins/FullPage/test.html | 89 + .../htmlarea/plugins/SpellChecker/img/makefile.xml | 4 + .../plugins/SpellChecker/img/spell-check.gif | Bin 0 -> 107 bytes .../htmlarea/plugins/SpellChecker/lang/cz.js | 37 + .../htmlarea/plugins/SpellChecker/lang/da.js | 37 + .../htmlarea/plugins/SpellChecker/lang/de.js | 28 + .../htmlarea/plugins/SpellChecker/lang/en.js | 38 + .../htmlarea/plugins/SpellChecker/lang/hu.js | 37 + .../htmlarea/plugins/SpellChecker/lang/it.js | 28 + .../plugins/SpellChecker/lang/makefile.xml | 4 + .../htmlarea/plugins/SpellChecker/lang/ro.js | 37 + .../htmlarea/plugins/SpellChecker/makefile.xml | 8 + .../htmlarea/plugins/SpellChecker/readme-tech.html | 114 + .../plugins/SpellChecker/spell-check-logic.cgi | 210 ++ .../plugins/SpellChecker/spell-check-style.css | 10 + .../plugins/SpellChecker/spell-check-ui.html | 122 ++ .../plugins/SpellChecker/spell-check-ui.js | 397 ++++ .../htmlarea/plugins/SpellChecker/spell-checker.js | 79 + .../plugins/TableOperations/img/cell-delete.gif | Bin 0 -> 101 bytes .../TableOperations/img/cell-insert-after.gif | Bin 0 -> 118 bytes .../TableOperations/img/cell-insert-before.gif | Bin 0 -> 118 bytes .../plugins/TableOperations/img/cell-merge.gif | Bin 0 -> 896 bytes .../plugins/TableOperations/img/cell-prop.gif | Bin 0 -> 155 bytes .../plugins/TableOperations/img/cell-split.gif | Bin 0 -> 907 bytes .../plugins/TableOperations/img/col-delete.gif | Bin 0 -> 100 bytes .../TableOperations/img/col-insert-after.gif | Bin 0 -> 111 bytes .../TableOperations/img/col-insert-before.gif | Bin 0 -> 110 bytes .../plugins/TableOperations/img/col-split.gif | Bin 0 -> 908 bytes .../plugins/TableOperations/img/makefile.xml | 4 + .../plugins/TableOperations/img/row-delete.gif | Bin 0 -> 104 bytes .../TableOperations/img/row-insert-above.gif | Bin 0 -> 116 bytes .../TableOperations/img/row-insert-under.gif | Bin 0 -> 115 bytes .../plugins/TableOperations/img/row-prop.gif | Bin 0 -> 149 bytes .../plugins/TableOperations/img/row-split.gif | Bin 0 -> 895 bytes .../plugins/TableOperations/img/table-prop.gif | Bin 0 -> 145 bytes .../htmlarea/plugins/TableOperations/lang/cz.js | 90 + .../htmlarea/plugins/TableOperations/lang/da.js | 90 + .../htmlarea/plugins/TableOperations/lang/de.js | 81 + .../htmlarea/plugins/TableOperations/lang/el.js | 81 + .../htmlarea/plugins/TableOperations/lang/en.js | 90 + .../htmlarea/plugins/TableOperations/lang/fi.js | 66 + .../htmlarea/plugins/TableOperations/lang/hu.js | 63 + .../htmlarea/plugins/TableOperations/lang/it.js | 81 + .../plugins/TableOperations/lang/makefile.xml | 4 + .../htmlarea/plugins/TableOperations/lang/nl.js | 90 + .../htmlarea/plugins/TableOperations/lang/no.js | 91 + .../htmlarea/plugins/TableOperations/lang/ro.js | 90 + .../htmlarea/plugins/TableOperations/makefile.xml | 8 + .../plugins/TableOperations/table-operations.js | 1160 +++++++++++ .../auth/resources/htmlarea/plugins/makefile.xml | 8 + tools/authcon/auth/resources/htmlarea/popupdiv.js | 369 ++++ .../auth/resources/htmlarea/popups/about.html | 378 ++++ .../auth/resources/htmlarea/popups/blank.html | 2 + .../auth/resources/htmlarea/popups/custom2.html | 35 + .../resources/htmlarea/popups/editor_help.html | 16 + .../auth/resources/htmlarea/popups/fullscreen.html | 133 ++ .../resources/htmlarea/popups/insert_image.html | 191 ++ .../resources/htmlarea/popups/insert_table.html | 174 ++ .../auth/resources/htmlarea/popups/link.html | 142 ++ .../auth/resources/htmlarea/popups/makefile.xml | 5 + .../resources/htmlarea/popups/old-fullscreen.html | 131 ++ .../htmlarea/popups/old_insert_image.html | 206 ++ .../auth/resources/htmlarea/popups/popup.js | 109 + .../resources/htmlarea/popups/select_color.html | 347 ++++ tools/authcon/auth/resources/htmlarea/popupwin.js | 139 ++ .../auth/resources/htmlarea/project-config.xml | 5 + .../authcon/auth/resources/htmlarea/reference.html | 523 +++++ .../auth/resources/htmlarea/release-notes.html | 165 ++ tools/authcon/auth/resources/mattkruse-lib.js | 124 ++ .../auth/resources/mattkruse-lib/AnchorPosition.js | 147 ++ .../auth/resources/mattkruse-lib/CalendarPopup.js | 688 +++++++ .../auth/resources/mattkruse-lib/OptionTransfer.js | 187 ++ .../auth/resources/mattkruse-lib/PopupWindow.js | 336 +++ .../auth/resources/mattkruse-lib/README.txt | 3 + tools/authcon/auth/resources/mattkruse-lib/date.js | 335 +++ .../auth/resources/mattkruse-lib/selectbox.js | 315 +++ tools/authcon/auth/resources/move_down.gif | Bin 0 -> 842 bytes tools/authcon/auth/resources/move_up.gif | Bin 0 -> 842 bytes tools/authcon/auth/resources/new.gif | Bin 0 -> 842 bytes tools/authcon/auth/scripts/ip_check.xsp | 39 + tools/authcon/auth/sitemap.xmap | 250 +++ tools/authcon/auth/stylesheets/as_is.xsl | 18 + tools/authcon/auth/stylesheets/opensrf.xsl | 41 + tools/authcon/auth/stylesheets/reportstatus.xsl | 152 ++ tools/authcon/auth/stylesheets/response2json.xsl | 29 + tools/authcon/auth/stylesheets/seth1.xsl | 38 + tools/authcon/auth/stylesheets/seth2.xsl | 55 + tools/authcon/auth/stylesheets/seth3.xsl | 139 ++ tools/authcon/auth/stylesheets/sethfinal.xsl | 146 ++ .../authcon/auth/stylesheets/simple-page2html.xsl | 103 + tools/authcon/auth/stylesheets/xml2html.xslt | 254 +++ tools/authcon/seth/build.xml | 256 +++ .../seth/src/EasySSLProtocolSocketFactory.java | 238 +++ tools/authcon/seth/src/EasyX509TrustManager.java | 121 ++ tools/authcon/seth/src/sethTransformer.java | 1517 ++++++++++++++ 243 files changed, 21705 insertions(+) create mode 100644 tools/authcon/README create mode 100644 tools/authcon/auth/content/auth.xml create mode 100644 tools/authcon/auth/content/kickoff.xml create mode 100644 tools/authcon/auth/content/opensrf.xml create mode 100644 tools/authcon/auth/flow/auth.js create mode 100644 tools/authcon/auth/flow/md5.js create mode 100644 tools/authcon/auth/flow/opensrf.js create mode 100644 tools/authcon/auth/flow/util.js create mode 100644 tools/authcon/auth/forms/auth.xml create mode 100644 tools/authcon/auth/forms/auth_template.xml create mode 100644 tools/authcon/auth/images/Thumbs.db create mode 100644 tools/authcon/auth/images/bback.gif create mode 100644 tools/authcon/auth/images/booking.gif create mode 100644 tools/authcon/auth/images/button.jpg create mode 100644 tools/authcon/auth/images/cal.gif create mode 100644 tools/authcon/auth/images/cancel.gif create mode 100644 tools/authcon/auth/images/delete.gif create mode 100644 tools/authcon/auth/images/eiu.jpg create mode 100644 tools/authcon/auth/images/end.gif create mode 100644 tools/authcon/auth/images/help.gif create mode 100644 tools/authcon/auth/images/loginwin.gif create mode 100644 tools/authcon/auth/images/move_down.gif create mode 100644 tools/authcon/auth/images/move_up.gif create mode 100644 tools/authcon/auth/images/new.gif create mode 100644 tools/authcon/auth/images/ok.gif create mode 100644 tools/authcon/auth/images/start.gif create mode 100644 tools/authcon/auth/images/status.gif create mode 100644 tools/authcon/auth/images/update.gif create mode 100644 tools/authcon/auth/images/zap.gif create mode 100644 tools/authcon/auth/resources/blank_btn.gif create mode 100644 tools/authcon/auth/resources/cal.gif create mode 100644 tools/authcon/auth/resources/close.gif create mode 100644 tools/authcon/auth/resources/close.gif.old create mode 100644 tools/authcon/auth/resources/def2binding.xsl create mode 100644 tools/authcon/auth/resources/delete.gif create mode 100644 tools/authcon/auth/resources/forms-advanced-field-styling.xsl create mode 100644 tools/authcon/auth/resources/forms-calendar-styling.xsl create mode 100644 tools/authcon/auth/resources/forms-calendar.css create mode 100644 tools/authcon/auth/resources/forms-field-styling.xsl create mode 100644 tools/authcon/auth/resources/forms-htmlarea-styling.xsl create mode 100644 tools/authcon/auth/resources/forms-lib.js create mode 100644 tools/authcon/auth/resources/forms-page-styling.xsl create mode 100644 tools/authcon/auth/resources/forms-samples-styling.xsl create mode 100644 tools/authcon/auth/resources/forms.css create mode 100644 tools/authcon/auth/resources/help.gif create mode 100644 tools/authcon/auth/resources/htmlarea/.project create mode 100644 tools/authcon/auth/resources/htmlarea/ChangeLog create mode 100644 tools/authcon/auth/resources/htmlarea/dialog.js create mode 100644 tools/authcon/auth/resources/htmlarea/htmlarea.css create mode 100644 tools/authcon/auth/resources/htmlarea/htmlarea.js create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_about.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_align_center.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_align_justify.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_align_left.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_align_right.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_blank.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_charmap.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_color_bg.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_color_fg.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_copy.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_custom.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_cut.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_delete.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_bold.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_italic.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_strike.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_sub.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_sup.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_format_underline.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_help.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_hr.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_html.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_image.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_indent_less.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_indent_more.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_left_to_right.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_link.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_list_bullet.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_list_num.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_paste.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_redo.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_right_to_left.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_save.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_save.png create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_show_border.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_splitcel.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/ed_undo.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/fullscreen_maximize.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/fullscreen_minimize.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/insert_table.gif create mode 100644 tools/authcon/auth/resources/htmlarea/images/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/index.html create mode 100644 tools/authcon/auth/resources/htmlarea/lang/b5.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/cz.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/da.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/de.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ee.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/el.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/es.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/fi.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/fr.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/gb.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/he.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/hu.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/it.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ja-euc.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ja-jis.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ja-sjis.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ja-utf8.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/lt.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/lv.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/lang/nb.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/nl.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/no.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/pl.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/pt_br.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ro.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/ru.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/se.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/si.js create mode 100644 tools/authcon/auth/resources/htmlarea/lang/vn.js create mode 100644 tools/authcon/auth/resources/htmlarea/license.txt create mode 100644 tools/authcon/auth/resources/htmlarea/make-release.pl create mode 100644 tools/authcon/auth/resources/htmlarea/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/CSS/css.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/CSS/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/CSS/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/CSS/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/1.pl create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/context-menu.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/lang/de.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/lang/el.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/lang/nl.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/ContextMenu/menu.css create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/full-page.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/img/docprop.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/img/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/lang/ro.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/popups/docprop.html create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/popups/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/FullPage/test.html create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/spell-check.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/cz.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/da.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/de.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/hu.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/it.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/ro.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/readme-tech.html create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-logic.cgi create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-style.css create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.html create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-checker.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-delete.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-insert-after.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-insert-before.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-merge.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-prop.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-split.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-delete.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-insert-after.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-insert-before.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-split.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-delete.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-insert-above.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-insert-under.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-prop.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-split.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/table-prop.gif create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/cz.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/da.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/de.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/el.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/en.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/fi.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/hu.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/it.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/nl.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/no.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/ro.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/TableOperations/table-operations.js create mode 100644 tools/authcon/auth/resources/htmlarea/plugins/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/popupdiv.js create mode 100644 tools/authcon/auth/resources/htmlarea/popups/about.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/blank.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/custom2.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/editor_help.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/fullscreen.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/insert_image.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/insert_table.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/link.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/makefile.xml create mode 100644 tools/authcon/auth/resources/htmlarea/popups/old-fullscreen.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/old_insert_image.html create mode 100644 tools/authcon/auth/resources/htmlarea/popups/popup.js create mode 100644 tools/authcon/auth/resources/htmlarea/popups/select_color.html create mode 100644 tools/authcon/auth/resources/htmlarea/popupwin.js create mode 100644 tools/authcon/auth/resources/htmlarea/project-config.xml create mode 100644 tools/authcon/auth/resources/htmlarea/reference.html create mode 100644 tools/authcon/auth/resources/htmlarea/release-notes.html create mode 100644 tools/authcon/auth/resources/mattkruse-lib.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/AnchorPosition.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/CalendarPopup.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/OptionTransfer.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/PopupWindow.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/README.txt create mode 100644 tools/authcon/auth/resources/mattkruse-lib/date.js create mode 100644 tools/authcon/auth/resources/mattkruse-lib/selectbox.js create mode 100644 tools/authcon/auth/resources/move_down.gif create mode 100644 tools/authcon/auth/resources/move_up.gif create mode 100644 tools/authcon/auth/resources/new.gif create mode 100644 tools/authcon/auth/scripts/ip_check.xsp create mode 100644 tools/authcon/auth/sitemap.xmap create mode 100644 tools/authcon/auth/stylesheets/as_is.xsl create mode 100644 tools/authcon/auth/stylesheets/opensrf.xsl create mode 100644 tools/authcon/auth/stylesheets/reportstatus.xsl create mode 100644 tools/authcon/auth/stylesheets/response2json.xsl create mode 100644 tools/authcon/auth/stylesheets/seth1.xsl create mode 100644 tools/authcon/auth/stylesheets/seth2.xsl create mode 100644 tools/authcon/auth/stylesheets/seth3.xsl create mode 100644 tools/authcon/auth/stylesheets/sethfinal.xsl create mode 100644 tools/authcon/auth/stylesheets/simple-page2html.xsl create mode 100644 tools/authcon/auth/stylesheets/xml2html.xslt create mode 100644 tools/authcon/seth/build.xml create mode 100644 tools/authcon/seth/src/EasySSLProtocolSocketFactory.java create mode 100644 tools/authcon/seth/src/EasyX509TrustManager.java create mode 100644 tools/authcon/seth/src/sethTransformer.java diff --git a/tools/authcon/README b/tools/authcon/README new file mode 100644 index 0000000000..6fa2838a2c --- /dev/null +++ b/tools/authcon/README @@ -0,0 +1,80 @@ +README - Sept. 2010 + +This is an implementation of OpenSRF support for authentication using +Cocoon. You have to get Cocoon directly at: + + http://cocoon.apache.org/mirror.cgi + +The version we have worked with is 2.1.11, Cocoon must be compiled directly +for the target machine and for that you need the JDK. Once the JDK is +installed, set an environmental variable called JAVA_HOME to the root of +the directory for the JDK. You can usually tell what this is by the location +of "lib/tools.jar", for example, on my version of ubuntu, JAVA_HOME is set to: + + /usr/lib/jvm/java-6-sun + +and this is verified by the existence of tools.jar: + + /usr/lib/jvm/java-6-sun/lib/tools.jar + +While you are setting the JAVA_HOME variable, it is a good time to set 2 +other variables: + + JAVA_OPTIONS="-Xms512M -Xmx512M" + JETTY_PORT=8080 + +Jetty has a weird port by default, and "JETTY_PORT" should be set to +whatever port is ok with your firewall setup. Both Jetty and Tomcat +typically are set to max out at 64M of memory so the "JAVA_OPTIONS" bumps +this up quite a bit. Reduce the numbers if your machine is very tight for +RAM but this will help ensure that Jetty won't fall over. + +Cocoon uses a very old version of httpclient, so replace it with version +3.1, it can be found here, for example: + + http://apache.parentinginformed.com/httpcomponents/commons-httpclient/binary/commons-httpclient-3.1.zip + +Unzip it and copy it to the lib directory of Cocoon, located at: + + cocoon-2.1.11/build/webapp/WEB-INF/lib + +also remove the older version: + + rm commons-httpclient-2.0.2.jar + +OpenSRF requires https and we use some special workarounds in case OpenSRF is on +a machine that has a temporary certificate. The component that pulls in +httpclient to do the network interactions is called "seth" and it is installed +by going into the "seth" directory and editing "build.xml". Look for this line: + + + +Adjust the path to reflect where Cocoon has been installed. The application is +compiled with Ant so go into the "seth" directory and issue a: + + ant deploy + +This should compile and install the component. Now copy the "auth" directory to +"build/webapp" directory of Cocoon. The "sitemap.xmap" file in "auth" contains +the parameters for an ezproxy installation. Modify these to reflect your environment +and start Cocoon by going to the "cocoon-2.1.11" directory and using either "cocoon.sh" +or "cocoon.bat". Note that the files won't be set to be executable by default: + + chmod +x *.sh + ./cocoon.sh + +If it looks like Cocoon started ok, try out the setup with a URL like: + + http://test.library.org:8080/auth/check?url=http://www.jstor.org + +You should see an authentication form, and be able to use a valid opac account +to be passed on to ezproxy. The form can be modified and styled in the "auth/forms" +directory. Cocoon featured an early implementation of XForms, and it's kind +of quirky. + +If all of this seems to work, specify the network location of Cocoon in the "ezproxy.usr" +file that EZproxy uses. + +And that's it! Feel free to contact me with any questions. + +Art Rhyno diff --git a/tools/authcon/auth/content/auth.xml b/tools/authcon/auth/content/auth.xml new file mode 100644 index 0000000000..c004df7649 --- /dev/null +++ b/tools/authcon/auth/content/auth.xml @@ -0,0 +1,9 @@ + + + + ${barcode} + + + ${pin} + + diff --git a/tools/authcon/auth/content/kickoff.xml b/tools/authcon/auth/content/kickoff.xml new file mode 100644 index 0000000000..8cc7d0ca6e --- /dev/null +++ b/tools/authcon/auth/content/kickoff.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/tools/authcon/auth/content/opensrf.xml b/tools/authcon/auth/content/opensrf.xml new file mode 100644 index 0000000000..b94c589d7f --- /dev/null +++ b/tools/authcon/auth/content/opensrf.xml @@ -0,0 +1,16 @@ + + + + ${service} + + + ${method} + + + + + ${parm} + + + + \ No newline at end of file diff --git a/tools/authcon/auth/flow/auth.js b/tools/authcon/auth/flow/auth.js new file mode 100644 index 0000000000..deac0e23a5 --- /dev/null +++ b/tools/authcon/auth/flow/auth.js @@ -0,0 +1,95 @@ +/* + auth.js - basic authentication support + + (c) Copyright GNU General Public License (GPL) + @author art rhyno + + Revised: +*/ +cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js"); + +function authorization() { + + var barcode; + var upassword; + + var theurl = cocoon.parameters["thisurl"]; + if (theurl.indexOf("url=") != -1) { + if (theurl.length > 4) + theurl = theurl.substring(4); + } + + var referer = cocoon.request.getHeader('Referer'); + + var theIP = cocoon.request.getRemoteAddr(); + var theDomain = cocoon.parameters["ipdomain"]; + var theOrg = cocoon.parameters["coniferorg"]; + + var probList = cocoon.parameters["problist"]; + var banList = cocoon.parameters["banlist"]; + if (banList == null) + banList="zipnada"; + if (probList == null) + probList="zipnada"; + + var ezHost = cocoon.parameters["ezhost"]; + var ezUser = cocoon.parameters["ezuser"]; + var ezPassword = cocoon.parameters["ezpassword"]; + var localAddr = false; + + if (theIP.startsWith(theDomain)) + localAddr = true; + + //basic cleanup of urls + var jsurl= new String(theurl); + jsurl = jsurl.replace(/\&/gi,'%26'); + jsurl = jsurl.replace(/%3F/gi,'?'); + + if (jsurl.length <= 1) { + print("zero length - redirecting"); + cocoon.sendPage("willnotmatchsoredirect"); + return; + } + + if (!localAddr) { + var form = new Form("forms/auth.xml"); + form.showForm("auth-display-pipeline"); + + var model = form.getModel(); + barcode = model.barcode.replace(' ',''); + barcode = barcode.replace('-',''); + + upassword = model.pin.replace(' ',''); + if (probList.indexOf(theIP) != -1 || banList.indexOf(barcode) != -1) { + cocoon.sendPage("willnotmatchsoredirect"); + return; + }//if + } else { + cocoon.sendPage("pass-on?url=" + theurl); + return; + }//if + + /* + OpenSRF support + */ + var authToken = setUpSession(barcode, upassword, "opac", + theOrg, ""); + + var authFlag = false; + if (authToken != null) { + authFlag = true; + //clean up connection + sessionDelete(authToken); + } + + if (!authFlag) { + cocoon.sendPage("authenticate.jx?flag=" + + authFlag + "&url=" + + theurl); + } else { + var passedUrl = ezHost + "/login%3Fuser=" + ezUser + + "%26pass=" + ezPassword + "%26url=" + jsurl; + cocoon.sendPage("pass-on?url=" + passedUrl); + + }//if +} diff --git a/tools/authcon/auth/flow/md5.js b/tools/authcon/auth/flow/md5.js new file mode 100644 index 0000000000..9d1ad2452b --- /dev/null +++ b/tools/authcon/auth/flow/md5.js @@ -0,0 +1,206 @@ +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ +function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} +function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} +function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} +function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } +function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } +function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} +function core_hmac_md5(key, data) +{ + var bkey = str2binl(key); + if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} +function str2binl(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + return bin; +} +function binl2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); + return str; +} +function binl2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); + } + return str; +} +function binl2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} + diff --git a/tools/authcon/auth/flow/opensrf.js b/tools/authcon/auth/flow/opensrf.js new file mode 100644 index 0000000000..e1aa4d6804 --- /dev/null +++ b/tools/authcon/auth/flow/opensrf.js @@ -0,0 +1,186 @@ +/* + opensrf.js - opensrf convenience functions + + (c) Copyright GNU General Public License (GPL) + @author art rhyno + + Revised: +*/ + + +function setUpSession(userid, password, sessionType, org, workstation) +{ + var parms = []; + var authToken=null; + var osrfdata; + + parms[0] = "\"" + userid +"\""; + osrfdata = { + "service" : "open-ils.auth", + "method" : "open-ils.auth.authenticate.init", + "parms" : parms } + + var osrf = jsonify("opensrf",osrfdata); + print("init: " + osrf.status); + + if (parseInt(osrf.status) == 200) { + print("-> " + osrf.payload); + var md5Password = hex_md5(osrf.payload + hex_md5(password)); + print("-> " + md5Password); + parms[0] = "{\"password\":\"" + md5Password + "\",\"type\":\"" + sessionType + "\",\"org\":"; + if (sessionType == 'opac') { + parms[0] += ("\"" + org + "\",\"username\":\"" + userid + "\"}"); + } else { + parms[0] += ( + "\"" + org + "\",\"username\":\"" + userid +"\",\"workstation\":\"" + + workstation + "\"}"); + } + print("-> " + parms[0]); + osrfdata = { + "service" : "open-ils.auth", + "method" : "open-ils.auth.authenticate.complete", + "parms" : parms } + + osrf = jsonify("opensrf",osrfdata); + try { + authToken = osrf.payload[0].payload.authtoken; + } catch (er) { + //print("error " + er); + } + }//if + + return authToken; +}//setUpSession + +function patronUpdate(authToken, patronInfo) { + var parms = []; + var osrfdata; + + try { + parms[0] = "\"" + authToken + "\""; + parms[1] = patronInfo; + osrfdata = { + "service" : "open-ils.actor", + "method" : "open-ils.actor.patron.update", + "parms" : parms } + var osrf = jsonify("opensrf",osrfdata); + if (parseInt(osrf.status) == 200) + return true; + } catch (ex) { + print("problem with patron update: " + ex); + }//try + + return false; +}//patronUpdate + +function retrieveUsrByBarcode(authToken, barcode) { + var osrfstr = ""; + var parms = []; + + //check barcode + print(authToken + " - about to search"); + parms[0] = "\"" + authToken + "\""; + parms[1] = "\"" + barcode + "\""; + var osrfdata = { + "service" : "open-ils.actor", + "method" : "open-ils.actor.user.fleshed.retrieve_by_barcode", + "parms" : parms } + + //we don't want a json object in this case + osrfstr = dejsonify("opensrf",osrfdata); + + return osrfstr; +}//retrieveByBarcode + +/* + checkBarcode + + - return true if barcode is found, false if not +*/ +function checkBarcode(authToken, barcode) { + var found = true; + var parms = []; + + //check barcode + print(authToken + " - about to search"); + parms[0] = "\"" + authToken + "\""; + parms[1] = "\"" + barcode + "\""; + var osrfdata = { + "service" : "open-ils.actor", + "method" : "open-ils.actor.user.retrieve_id_by_barcode_or_username", + "parms" : parms } + var osrf = jsonify("opensrf",osrfdata); + + //this will be a string if found + if(typeof(osrf.payload[0].textcode) != "undefined") + found = false; + + //print("-> " + typeof(osrf.payload[0].textcode)); + + return found; +}//checkBarcode + +/* + checkOrgId + + - return true if ord id is found, false if not +*/ +function checkOrgId(authToken, orgId) { + var found = true; + var parms = []; + + parms[0] = "\"" + authToken + "\""; + //Group 2 are phone numbers and ID values. + parms[1] = "{\"ident\":{\"value\":\"" + orgId + "\",\"group\":2}}"; + + var osrfdata = { + "service" : "open-ils.actor", + "method" : "open-ils.actor.patron.search.advanced", + "parms" : parms } + var osrf = jsonify("opensrf",osrfdata); + + //this will be the db id if found + if((osrf.payload[0] + "").length == 0) + found = false; + + return found; +}//checkOrgId + +/* + sortOutVal + + - put value in opensrf-friendly syntax, e.g., "foo", null, "fee" +*/ +function sortOutVal(theVal) { + var newVal = theVal; + newVal = newVal.replace (/^\s+|\s+$/g,''); + if (newVal.length == 0) + return "null"; + + return "\"" + newVal + "\""; +}//sortOutVal + +/* + sessionDelete + + - delete existing session +*/ +function sessionDelete(authToken) { + var parms = []; + + try { + parms[0] = authToken; + var osrfdata = { + "service" : "open-ils.auth", + "method" : "open-ils.auth.session.delete", + "parms" : parms } + var osrf = jsonify("opensrf",osrfdata); + print("delete: " + osrf.status); + if (parseInt(osrf.status) == 200) + return true; + } catch (ex) { + print("problem with session delete: " + ex); + } + + return false; +}//sessionDelete diff --git a/tools/authcon/auth/flow/util.js b/tools/authcon/auth/flow/util.js new file mode 100644 index 0000000000..cd171efd8e --- /dev/null +++ b/tools/authcon/auth/flow/util.js @@ -0,0 +1,277 @@ +/* + * util.js - generic help functions + * + * Art Rhyno (arhyno@uwindsor.ca), August 2006 + * (c) Copyright GNU General Public License (GPL) + * + * Revised: +*/ + +var prob1 = ", {}]}{}"; +var prob2 = "{}"; +var prob3 = "\",{\"url"; + +/* + sleep() - the rhino implementation doesn't have a setTimeout + function, but this is a better approach anyway since + javascript still consumes CPU. Java has a true sleep + function and that is what we use here. +*/ + +function sleep (secs) +{ + //bump up to seconds + var theSecs = secs * 1000; + java.lang.Thread.sleep(theSecs); +}//sleep + +function endsWith(theStr, theEnd) { + var theStrEnd = theStr.substring(theStr.length - theEnd.length); + print("comparing " + theStrEnd + " to " + theEnd); + if (theStrEnd == theEnd) + return true; + + return false; +} + + +function extractAttribute(attribute, attrStr) { + var attrVal = attrStr.replace(/\s+=/,'=') + ""; + attrVal = attrVal.replace(/=\s+/,'='); + var attrLoc = attribute + "="; + var attrPos = attrVal.indexOf(attrLoc); + + if (attrPos != -1) { + attrVal = attrVal.substring(attrPos + + attrLoc.length); + attrPos = attrVal.indexOf(","); + + if (attrPos != -1) { + attrVal = attrVal.substring(0, + attrPos); + + }//if attrPos + + }//if + + return attrVal; +} + + +function figureOutPath(theBase, theApp, theFile) { + var fullFile = theFile; + var fullBase = theBase; + if (!endsWith(fullBase,'/')) + fullBase = fullBase + "/"; + + if (theFile.indexOf("/") != 0) + fullFile = fullBase + theApp + "/" + + fullFile; + + print("returning " + fullFile); + + return fullFile; +} + +function fixQuote(theVal) { + var retVal = theVal.replace(/\'/g,"\\\'"); + + return retVal; +} + +function countInstances(theVal, theChar) { + var substrings = theVal.split(theChar); + return substrings.length - 1; +} + +function fixCollection(theStr,theProb) { + var collStr = "collection\":{"; + var newStr = theStr; + + var thispos = theStr.indexOf(collStr); + + if (thispos != -1) { + newStr = theStr.substring(0,thispos) + "collection\":" + + "[{" + theStr.substring(thispos+collStr.length); + } + + thispos = newStr.indexOf(theProb); + if (thispos != -1) + newStr = newStr.substring(0,thispos) + "]}]}"; + + + return newStr; +} + +function sortOutDate(dateStr, dashed) { + print("dateStr - " + dateStr); + var theDate = new Date(); + if (dashed) + dateStr.match(/(\d{4})\-(\d{2})\-(\d{2})/); + else + dateStr.match(/(\d{4})\.(\d{2})\.(\d{2})/); + + print(RegExp.$1 + " - " + RegExp.$2 + " - " + RegExp.$3) + theDate.setYear(RegExp.$1); + theDate.setMonth(RegExp.$2); + theDate.setDate(RegExp.$3); + + print("returning " + theDate); + + return theDate; +}//sortOutDate + +function jsonEval(inStr) { + //print("starts " + inStr + " - " + countInstances(inStr,"}") + " - " + countInstances(inStr,"{")); + var theStr = inStr; + if (countInstances(theStr,"}") < countInstances(theStr,"{")) { + //theStr = theStr.substring(0,theStr.length - 1); + theStr += "}"; + //print("modified"); + } + + var evalObj = null; + try { + evalObj = eval('(' + theStr + ')'); + } catch (evalProb) { + print("jsonify can't convert: " + evalObj); + print("jsonify can't convert - " + evalProb); + } + + + return evalObj; +} + +//jsonify - put results of pipeline into JSON format +function jsonify(pipeline, pipeinfo) { + + //print("json pipeline is " + pipeline); + var stream = new java.io.ByteArrayOutputStream(); + cocoon.processPipelineTo( pipeline, pipeinfo, stream ); + var theVal = stream.toString() + ""; + //print("serviceVal is " + theVal); + var checkpos = -1; + /* this probably doesn't have to be in a try/catch block + but i had a problem with one range where it was an odd + character. i couldn't replicate it again. + */ + try { + checkpos = theVal.indexOf(prob1); + if (checkpos != -1) + theVal = fixCollection(theVal,prob1); + checkpos = theVal.indexOf(prob2); + if (checkpos != -1) + theVal = theVal.substring(0,checkpos); + checkpos = theVal.indexOf(prob3); + if (checkpos != -1) { + theVal = theVal.replace(/,\{\"url/g,'},{\"url') + ""; + theVal = theVal.replace(/\"\]/g,'\"}]'); + //print("now -> " + theVal + "<-"); + } + } catch (problem) { + print("nasty char issue " + problem); + } + + var theEval = jsonEval(theVal); + + //cocoon.dispose(stream); + + return theEval; + +}//jsonify + +//jsonify - get json results but leave in string format +function dejsonify(pipeline, pipeinfo) { + + //print("json pipeline is " + pipeline); + var stream = new java.io.ByteArrayOutputStream(); + cocoon.processPipelineTo( pipeline, pipeinfo, stream ); + return stream.toString() + ""; + +}//dejsonify + +//reportStatus - send message to status pipeline +function reportStatus(theReason) { + print("thereason is " + theReason); + var reason = { + "reason" : theReason + } + cocoon.sendPage("wagger-status-pipeline", reason); +}//reportStatus + +function reportStatusInJson(theReason) { + //print("sending " + theReason); + var reason = { + "reason" : theReason + } + cocoon.sendPage("wagger-status-pipeline-json", reason); +}//reportStatusInJson + +function Mod10(ccNumb) { // v2.0 +var valid = "0123456789" // Valid digits in a credit card number +var len = ccNumb.length; // The length of the submitted cc number +var iCCN = parseInt(ccNumb); // integer of ccNumb +var sCCN = ccNumb.toString(); // string of ccNumb +sCCN = sCCN.replace (/^\s+|\s+$/g,''); // strip spaces +var iTotal = 0; // integer total set at zero +var bNum = true; // by default assume it is a number +var bResult = false; // by default assume it is NOT a valid cc +var temp; // temp variable for parsing string +var calc; // used for calculation of each digit + +// Determine if the ccNumb is in fact all numbers +for (var j=0; j0;i--){ // LOOP throught the digits of the card + calc = parseInt(iCCN) % 10; // right most digit + calc = parseInt(calc); // assure it is an integer + iTotal += calc; // running total of the card number as we loop - Do Nothing to first digit + i--; // decrement the count - move to the next digit in the card + iCCN = iCCN / 10; // subtracts right most digit from ccNumb + calc = parseInt(iCCN) % 10 ; // NEXT right most digit + calc = calc *2; // multiply the digit by two + // Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7, + // I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple. + switch(calc){ + case 10: calc = 1; break; //5*2=10 & 1+0 = 1 + case 12: calc = 3; break; //6*2=12 & 1+2 = 3 + case 14: calc = 5; break; //7*2=14 & 1+4 = 5 + case 16: calc = 7; break; //8*2=16 & 1+6 = 7 + case 18: calc = 9; break; //9*2=18 & 1+8 = 9 + default: calc = calc; //4*2= 8 & 8 = 8 -same for all lower numbers + } + iCCN = iCCN / 10; // subtracts right most digit from ccNum + iTotal += calc; // running total of the card number as we loop + } // END OF LOOP + if ((iTotal%10)==0){ // check to see if the sum Mod 10 is zero + bResult = true; // This IS (or could be) a valid credit card number. + } else { + bResult = false; // This could NOT be a valid credit card number + } + } +} + return bResult; // Return the results +} + +function listProperties(obj) { + var propList = ""; + for(var propName in obj) { + if(typeof(obj[propName]) != "undefined") { + propList += (propName + ", " + typeof(obj[propName])); + } + } + print("--> " + propList); +} \ No newline at end of file diff --git a/tools/authcon/auth/forms/auth.xml b/tools/authcon/auth/forms/auth.xml new file mode 100644 index 0000000000..4c82da6a29 --- /dev/null +++ b/tools/authcon/auth/forms/auth.xml @@ -0,0 +1,38 @@ + + + + + + + Username or Barcode: + + + + + + + + + + + + Barcodes can be entered in any of these formats: +
    + 21862000111222 + 21862-000-111-222 +
+
+ Password: + +
+
+ +
diff --git a/tools/authcon/auth/forms/auth_template.xml b/tools/authcon/auth/forms/auth_template.xml new file mode 100644 index 0000000000..52d143c763 --- /dev/null +++ b/tools/authcon/auth/forms/auth_template.xml @@ -0,0 +1,44 @@ + + + + + Library E-Resources + + + + + + + + + + + + +
+ + + + + Authorization Information + + + + + + +
+
* - MUST be filled out.
+
+ + Login + + +
+
+
+
diff --git a/tools/authcon/auth/images/Thumbs.db b/tools/authcon/auth/images/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..aaecadc8edb173cefb9ac074403613652d0f03fd GIT binary patch literal 26112 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 literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/bback.gif b/tools/authcon/auth/images/bback.gif new file mode 100644 index 0000000000000000000000000000000000000000..7bd57699a1239eb0e9ce253f848c2dfd37048879 GIT binary patch literal 799 zcmZ?wbhEHbWMp7u_|Cw<(7s{EzRRCKeLjEw;moziZ{K+N=-xYq={sIN`OFZo>hqh= s3{C49O4c#7Z+ZXnGeh?VppH>68Un*61av??0p$e-4i*Ms78V9;0Eb~B&j0`b literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/booking.gif b/tools/authcon/auth/images/booking.gif new file mode 100644 index 0000000000000000000000000000000000000000..3aef2e77d59000635cc2321a770569af73f35337 GIT binary patch literal 1047 zcmZ?wbhEHboXsH2@STByp?$-SeV0Ff`h5QU!# z8JgBJl&oWD-}3(DXNK+#KpmrCGz5lC2v9Df*CIdlXR8V@#e2y4Zh*s$<$ zyMVIS9FM?746Ll$S$9rsTztHrpOuHfbJLQOljV6A#GKredU_%^>nV{9feB8t<TS`jdj=L$LAL-R%`8zEXicMHj$4$%qR z5Ow~NOZJ4-S65i=-uBh2TrYA<_UmQ3+G1<&?5=vf?`_9by@bPg{Mz$oS*(cOmi(Ph zZI0;1ggsNmxzlEBGk9`-l6tt#nwv#0FY`Li4zszwCZl_1sQk3EW+pc;uiENV=Np(F vf3lZ(eczj?x9_hlIjr>j?3|*{&o5a1@Ab2-di3hX=Is0D_Ew*4V6X-N?lqlN literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/button.jpg b/tools/authcon/auth/images/button.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aebe00a75686bc794df430009ab1496aaf4e8e7d GIT binary patch literal 851 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<ECr+Na zbot8FYu9hwy!G(W<0ns_J%91?)yGetzkL1n{m0K=Ab&A3Fhjfr_ZgbM1cClyVqsxs zVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3wxht_K0{lgDIq<=B2K^;%TD4 zrT4@EQ45=%Caa5qFRgN{%zBfT-rmy7I(1Lk$1N>lT3sT-4QvIrtfHq%rfV$fVgTX) FHv#RqG~xgN literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/cal.gif b/tools/authcon/auth/images/cal.gif new file mode 100644 index 0000000000000000000000000000000000000000..681cd5dc7656bc843e814c6d46996cdf586b2cf3 GIT binary patch literal 950 zcmchWzi-ZQ5XTQ~;zu;J!hnPzl|GH-7RsWcXf#1|Xlh_NLk$uGHHk&agi3n47$l;J zq`_W|FvyKfh>+09B$5(L=XGEH2A|=1a=FjveXsZXp6AH1fxY|AbxNoFl)pzsOvFV( zB!x;<)I?o0M6;TvVkYKdA(nO5Roui~JjAn}hDw-(ON2zCB&m`n>5?Hyfi}`;@tE6L zbLyC?tA=XUSSm9$R|~Z)3Yu=}t{&=HP}~jEaE;JN7znet-Pe?P|m_{GrezuT6T&E6VY{|Q-nS8~;sqqE!Q z$5wXroVhY|_Q8#HI|e5|f4h0Br4Qpp=a&_?pXiy z&atKUF}5MwXU3m(_fPeWtlHYMVfy5S{!3qiEl3ulnwtAKKV4F*7{Y-a9KTdCYGC$Y8V!7=91K+rc0RR91 literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/cancel.gif b/tools/authcon/auth/images/cancel.gif new file mode 100644 index 0000000000000000000000000000000000000000..b022e0693d7cd379df614bc268a51ac29033ad37 GIT binary patch literal 1233 zcmZ8geK6E%9DlY|h-vn^jm+rAPMz7_oH$3J)m>}7?iY~92&DWvpN-}60_EEeDB%4=Ki?vJb!%V`+Q!$-)H98@5-^;9q5EM zAT>g}h+NCS9P8kGD{kI*{@E6OSv!3)w;#K19h7f*GRMLxF8!mrGv2XLqRIsEn%+WVlq`lGmB^>i5eN1&qva3Mte?;KE&hzWFb zT0tj}5)x#v9&s^;xfq3J-Y=5LMk={R$yLvjZ%gLoy4b-Eo4_dMYq2qc0~Cx&6p6K( zX5<&`d((flwsR`-@~5|Q4M#)B#F*O#BqE%&S(3C^Y`C02ASbP-hLcP|#LOs(*k3#) z5QX&bO_58qDeXKv;Vt>l%SFrK!Vsy^nqgrkFr`YrE-r1NKpOwBixRO%(LT)q?1m#& zAz}*#W_ZEAa~6Fe!5EM2(_9flGC;oXHkT{=^l7FRDWN=h2Mcf7!; zX!9Wh14Hkww4U7of(<6&J}JC1>l?mJ{P8z&+m-xM>4k9lvsQJe2cnJ%yt5b<{yHgN zHM^%r*SvB_-NXttEIQBawWsQg%(AcOQ1VSSTbiox`$-)RfAY+*Mv3M>9+3>cZ#wPY zc4xWvk#Exv{8F@b#x5|ap5M}(_32KANbP~v>X|VpoiS%#HjHmm^9xm>$lwyYQ9n?n z{yf?qOQ@v|j=XL=6U(XD@ucv_3)>Hl^|RnLeAEvUY~=F<&eZe|Ha;ii1GnY=GUwg^ zzHS+VYGmYT`$Fi(uyjJYZj4M*P8jdi!EaUtAX=0mSGX>6^R7@$ z{&~Y`P3p+iHMCu8+^m|zS0f5ia&rz@Z4JsTb`SYB&+U{rh+^pJteZ`(>Ado_BU71N a#48mC7ysN?WPbBp%T%&)NC%yU?Ee9eo>>I| literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/delete.gif b/tools/authcon/auth/images/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0f48916e3be33d0233ef7862ae1702bfdbfe704 GIT binary patch literal 842 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[r<8ZJGL2^VH+Nr1rle<<0-^ z^nH0v(DH{DH{};t4K9GHBsMB!jRwG2Asgs{q$Y1~S&x!=s2{<>>C&ed47L1aq+l

3vB6KzDeuialtiWfd2Mqfj z%0ND2Xu8E7G+p}zQr!O4rC{K*+SV3B6r~GY5%6^{L1IlVOcOjbYJww=v2iWLUvmO( zZbFM*tS)W|uR(3l=kg-6(ZH=Kkio>`&ss?Od@wq^P3-BVmlmFScWJn}ra$GnMxLOn zNvJi7ucAEZDy^)l^2JYDqr-EtN@BHEKAo2#3ja%is3^lIRo-u?X>U=T#apIpZj?2C zuQi_r@DOhnO;MZiMtzn1fjKL(%=D@e5_limF235wt8N{?sP<*~4^0bLOSBQl z)MZEF?UOf%`*FAT#8J2D;%9ORP^{hNhv}Xz-(p9PN2CCC%n7I)d70FllShY zjb-Y2O`Aj3|}E)f(QBQ&y6-t4QDg zKLJ9uz+FPQ=UJsrc!Nm>v!gl&yP#NLpn8(D@X7mKAk~>C2J2UciNJaypCt?S@zK#@ zoQ4UkJ%DwguL=T%>8`M+Jile@0t?6N;Ib`ts4my;+;ENVCq{~ucm^gW8S%tc>8XrP zKSQM(mD;5(m8`~K2aQM8_SCwj32Y(^Cwe)^_V&2=)hUm3@a7liJLi{ruwdmVt~W5- zdonKUeG*Q>POy)fGy?1bZuUzjm^7opAgnpz6)y84OQIiDN*y$40Vpk)@dqFQh`UNU z%3g9&@-g(dKO1~gtk7SV7F`WV(BjV+m66h=Fu*YrnpU39beE%h@H8U22eDUil{_M2 zQ5k+}P)zDz!^Wc{5`*2t=_-5ZP-vPr?P%zpuL0TTH&9RcmOCcaj!&fc(d{*Y<=K#^yKNL|jjfA`|T% zq=7E+xzDTXU7QQPKj3*|oAl#3PXjgYS9b#rzBPj=d<4`qA+vgI=j0X(N5w{(Jou>6bDkljbZ!j}FkB zPUp(N;IYL)hNrWC2^9duKMX~w{2C!>GS3?iO z*)I@&d$9&LU20v{M>;^fw2a~sA=tu@OcBoqrSt;@bw8J5nb&gHP$_^)5i~N065!?q zS7|6Xf*NbhIpdgvJd6hw*5F^|<)4co&V772g)@i=*}2EeLGPZ7&rzS8Bu*lZJs~K= z%nUp|Q=e#Qi8qVpP+C+C=I{|h{|z-VRcVjmUFZG=IAby;Ru@NgHjw)U*@!^l<6j)s zklUEg(N4}V3Pr?^+n)BCvl9S6y=4%At#1a|D!M-4bSIlk3B6DkzQDGAWX}2qNPXU7 zK$y2Fh79u!)paQYB#u-pZJbVlgj1%PpWo9o-$aVjlTYqjhTsDd5cx_q?5DJ)+A=it zJMKe2H0cWT_YX^V)}xX3cBF>tpzYVv^N-SYNyM-sK*2Xv>D&DIG-sExPNJ-oaPCtQ zLvbg5sLz~`qbjB;yKiQ|MueRQV>Q~IqjTvM$8y$0x1`0Lx4C42*&%~g!83b6uO+w< z2_szDkWG_^MB%z)p;lCwYJxa|ib($SIax)=_73cThEv~)y0)>OT;$~dmF`KCxeYbO z2S5*2b>>HT@zl2|;>n|W5{sFbna^kAy(=Dm6psuW*eJV+o;gr6rVZ=vXgN*Hv5m798L;+S z1%Y!nz|PN4I2*VCSuUvrdbx3hVmHITr>B*c)|@soNHg&|+fI_QAl$#%v{`EK1`+wS z@pL9f#*VedPFpH=>}sd&qqMM}8Px#baGtX1VWu29<;!P^Z0mI%LY!(Gx0~!sy?2rw z4t>t%O?CRW+0vcT5-w6g5ow!ixb-It{}*#_9TnHIw+%M#?m-gVo!}uzkPc383GVLh zf#A}F#vuvr)^y|U?u2e6_`xlZ5afJ)?#z7exocjzYwoOB^GB_&KU((QUA1f1^LxYw zPOl9=qU~@F;4!lz2t>o~92<`zRM`|{p&+9Z8xk+H#sYFaRbpixFK4?1 z3s2+NHo9jvc$V8A+DJ8akGwaGhe%!Z9>>yT4_nXhsqD7V=)X}*!7(B2&>X9)CcIS_ z-gCBO@)&KdeCt9ENR8Km_Zz4;&iszH&!ZGNMiyV zhOb2~pn-Q!3yYxbC(-%a;U{^;gFE%6m!$X*k2<3`89T|QwBy>a0E;%tFji>$!rW(e zZSeLgT{DjA0NKfvS_I1*Zo-sR%S>(r!nn^KPZ8Bc2?SIbdoA4NC;hvb?APKV%7Nr? zR{(GQcJNpUQVFOAQnpj<7^A-D^jev1a#P|7|G3Lil_q?x)3u2I{`m?oudh3#v&reu zx7?2Ho+tc}ho!&5cLICZF#UegI&-9Q?(KK)TUby{A)_mw@*S@YXy53frz`S$w`>#1 zDoctk`r%S^6V>GAX1CyLPBO+&a-q(<-Vs{xAwbnn)nT^-P)P`%Wrc3 z72``lB2V4;u2ZUZ-AMhhYB|jQHgtF>yk(oh^Qi_Se1l3eji@8#bMC?UjbX{6&&{8J z55YXExl@(CMu_wBzsr2tb|W>>0iKFQI54XG zbc)A^8FJw6AttUif7;4jqYTeuSgi+?zf<9(@HL@5#qq8<&7|imx>?Md5RK z!o;n?j18~eBf(3mx1ciuw|mvruG||&Xw(*40W&EY^V`xeMLoFmXJwi(=|aI4Me<=J zm+l4b-%FtejVpiG<9%QYR-gI3ht%UCrQx3wV$1$kCY?n=GUNWS1*pOC>45~mf=VVF z(uce~um|61lrA%23QS_E+NW8=n9r6U$$NLm`r&!TjT-p7(5VxVq~^4H-ht(ucU;TG^+-1@v;L^5xh9=)~!ESKcXd z$BlxgpNNQ|UmWQnvuk|>oyR;=v~LNL!9#6}#7nW>N6 z9`EbBg?K{vYYZLz+O0xk4b^U`sK{v6jYT6Z^mWZX1~6^D0QCe@@32F^X7+B?gi!c9 zW8|}sO{K0Dr`UJ5W{;=O;3vty9wU77+EW2PO$^W@3JGF;geBN5Gm6gFG`D9LD#3$ z6HQ~$DjF?HbB6nVuVq(EG4b@acbHX~oN8!n1``qrC(olTlm%a!#gLog<8|R4g;T+g zj#-#C_}RTc{srmlmA%7~YwTfDr}8p zsOG`+0SANTceJI*c>;W>khlM@6|8@;*wJt~zDD5oW(|sI9T{l1B(ZBkyJE)?hQa2aA!pPVEXhde-3UO=+&3sJA3S~4d$cX z+TveT^Y`lW@FVpsfBjh?X9|sU_HH^w6per$^%=FkOTom7$JELtW*%J@$pp`AC(ZbT zD-(^3MNbEQ@zh;HYKEUG#}i{duT-z!@6e(Aypu8k-tN1y27^|9e23_Xw2Zw(W@vK6Q!gi~**Pf;4j@K;i-QVw`r^DB8?!xSNPgUh;>$lDLSmH}T`vS*Z zu+_;j@-f;yjBuYe{Q;R-`HXy2r%(l>rUmvWydnr>p}Nx(fl!sA(D{~^gmx$ke z)fVMI2S06vHG(w<_W^xQ;#>n}Z-H#U{}uY>n@Ef|Qi?6Sy?uq_uT7-6Vuv4SkiR~+6w;Gu3j0Lo@TF*UdB z%i5c21>1df@2mtB*M0ZqF-o>HWr&MQ)4`Mmq2F1b^s||j5Dg#LQtelmUmIk8>W2_@ z!H(VFh;t^j+=L5@f-Y55Z6p<`cbw!c6;njCTX(t2hk#>$mC_wXUH1QQ}H%m_+Zi zGCEj-1+`@*@zk}R*NXBdKix@!EHqyu66}TZabiu$b(H!5qyj))cK7`Smzpr+xr65_ zbHQuUB?m-~O75%_KG>lX>xwEZPmAVjee4&bTo~}DthsvM+jysA#;n${xaPK=wKf6W zi;7w`s|LGyzx*Go`fU!FEzoL5|4`l%O#6W5b~*GyeYrkV^$t9=J^%=txp7b@AX+tn zhBX*ODt>0`y$8c{+hTk5Iwp?cv02OUH|?skK~Q`lIS{tJF;5vQ%F~wws=GDFiV%w^ ziSjNKoo~O;OI|_v%g8KvvCxT)k!Dm8_!FF#KpW^h}tYec+x_0o6dmrJS=RxEyJ(i#-{sUN#Bk)V+%GU1Mr` z+xKO~nTXT<3~i2ELA;?hg!sbZ+Q)ox*ZGWV4k1yb4GKBs3wpR9k`|v)H@15O$UOY?!JGqVBb=>jboR?2sc!8W$xgnLUGZ&D_2zj&G^$s2dB*pqJ;pu{_hlob?*CQBK z<|O6?Uo|Tooa5>&)Z#&^lgIs0l7w2Bi}DDPPF*agzV}FuXuv>blE?R=qR%{d6U2rW$nEx7d(7Vlo*uoJ#YX3|2rXPq`~`3 z7D>I7^1Y8#;APMhcHxF%g0kU6456%nIC`f3G+GdynzU+Z_A>?6@usHwv|DeU6BQQM zxVl?(?)(_$UH7wm%cBjnr-k-H^On`}yxZu5mXzb-{UMfMW7i!o{=BQYxtKSmm$|bU z1F&neWDT>oYe(r2I~vj@FrcETf`BHiQM@%PZRc0O_cLRZ&(dkRMx4-$a(;)oYb)M?z_wFWeAPJ8>_)U696zZv3la>Bm|0xST z!%~^FW;tfw&y4^h)Ipvd(B8V5=U9&uqm(Dt!vOa+{}i~_E(6JITZKF#sU?!3B~bk% zMy`!_)PCnuDTdgAF97~Nrrzm95gPkocM4h$OSsfBbp_s$~(xWhp|Cg4UwcPNb&|@z8aEq z-r}h72~L*WIK9m|EsxxleJg^4TXsUyYKOs2>qQ-z0_kPDbggm%dn#p-noMB~ysfmA znxTuEJtd$v8^s;hoGh-&|DH7FzMZJl+HJ&2I+(>xU;k|zw6&MihaYo0Or1H|x`rvC zy_nS7O}DtUI9%;sWmNZt9XV`R6Gha!EVLWZKi6Tj``V511boL;-nyx=5~KrXF=&vo zEY`$KIu)vscy(m)Kc$p=yZ}rJuJHm^-6qql%k zUO}izox+Nq=-z!ys`v@?EK2w_B{sy$T8frNzsz{*Tz6BBIWdmbxdOR5d5cz~9$K{* z`~if$gf0Gx^9S=ht}gJOGcagV)GFCH-nA08{WS0{c0miVCtAlr&lHVaj;k2YSzW zFA^8;X8cZcn#NBMZ4v;naFyViRJQf^$4IVTTk9Uppm{+GWCs8w>{ucIV=NIu>M}I? z0n9mQG3g3`KeQv5r7Ho^CrXNewcSN^W~()lF~eV^n}CkDe<-#LTC!4Ufw`Ggl*iG_ z1u)c515mjAwrNLSf@7JhXtU2w!J~H>(wLLjAG)n=hE1MiB+|~MtqVTYU|A{#?!cY3 z1N>#FsNi2~z=gIyQYj{{5~I@5bs8j9KBK&NI#V*?Q!tRLrdJH%v?njyt79<)o$WDY zOvc5Gh4ZZskeXs}(^|N*v&u~%spqYsgsO+E&5{VGDbfe9I=PrOrfqAsot|mKJ8IbL z9(HDSmUA{7%&)%*no8Os2E!^n(Dx4YEPy-rj&WUE){ym{%QM+w;VaL#z5X}28^*9K z=swxL%4`{3$aDvcuZehyNEu@(X(-sgD z7xn;>e|R`URaaWkX`ZkDy0DI^|8S*>+k& zq9&lU%u$~jp1F8=tQqT2hx8R>0a~Ujl*ILAeoBhMKEkdOB9L+5<8P6oSfW%~JOPui zWNe*I`c*QExOt2?rcqiLQm~{M#0GfZ8{8`Z@7-@>7JIBe&Rjn&03b}rr>dfLQ(*~- znd#D=IR4QZEN?|G<5WZs#5bJ#UitprMEFT6|J1#x%(P(7^S1T`!49RTakU$ z)T?~FN~bAH*6nyxlQl%9IaBC&$dz;l@G3S;56e;hIg5al(MxV@i|f5EsEWU2U@}+C zT4Z9ZHQi@fy<0>ZIyx*;A{@`REGjPzbx^lEG7d^&@oBe?I0F+;h%qkGlM zwUwY~)4^`$cJFrOI7i~2A$Quz)!HmbOV zfnDjHU7{zGzhk;GJ6A|m;yMz~-zTULWFuaXVk+U(aF;A^?C3Wy)D^&o?AxGeKyct* zQuY_GO-}3?W*71P$L#AV0V!PW_*j!X*SECQB(?OoI6IE|TYNU38WXn6chhLhyq4Dh zx(v!nOh>?A&+i?T#{0kL9o-IW(ogn5mN@OM#p9+bD5(Hz3^{a?qzJ-fx9`D+E=$** zR7t(H8K&e-ivYgr+7d3)L^;)SNuSj$EzPu zr@Ph!k<10G7_UB!ATRA6{!)+jrRmzLW441g(b|ub&bQXDO47b+-a2okv1&;|USy1L z5jg*Hqox{^thx0(ids75)dE)VPVakMgK_Qe;!v{6>F#rRu-++pJmWF$SCl#u3+imn zv%Jmz49&q^cUSLVFnT6B;QqWr8;6Gf1DtF6t1tWfR_tN@*H*{%b3UttBR!+23f*|# zb=q-TE4}8(WPI#!;pX#97D`pv%6YZxQ#dEdkrk);xK3x!(eN?3;FW zxl{9Ju6|5E2@z1D&2rUl6x&;4EUr*tCpx0E<`dy;CzAN2D|)4T#E+bW@;r z#o^CqG3!6Xc%Vs)lW4iqY(dnf*G40SmpEpIWNeX0Qev4q%x4?tqSp?;CzLpK;ycu%RhZn@w z@roQ5=x_t7`QbzbfqNZt0n`sei4hZSA)PyZYxpp+AC`X7{Nd65jvUwMR637e_m%qr ztcG@ziP!cdbXT2}_|y%OIQ6`)B`ODPvFsUV+^ssBLiK=~y8^7Gh%+vyYonSQDTGNt z_e5nPt6iY!jL($Nh^O7KY}0d5QFya!Dr>j?HxmiT_xcqZtTEdii`Gz5lgAV`Xj|wq zf-F4ylxeU=GnXj0OncGhguDjJ*4`iEF}Z86`VRb)q^3~@d#y%@kcc^YqpZ%Dx*T@- z$wQ8Q66#s;CYdtWfyc_Q0f6>XIBMi^Z+(q_jG_4U{FL5&{AuoK@oMv)dEz>3Dz!Pu zedNqPu-pFkblABor1#jVCO7kgK;YE|f<>x8dN@=5Om=A4dr4jHMa_OCSG!06OIlZ3PM4|fLK|Yl%-+x%lsRQ@o^hKN~3%A8`8DZmtRSji|=8r-UZsz^r*`1L1K#+&3g| zdk>i+(4+6$Xk6L|kZU|=g^6l~sx__D4Cz^hi;K2oNa-a+l$yS6J&I7kTfKA1#f9%h z)KNH}(dAy(v7LVD1*>a-Xb&>zrz+=a5TQUKdoBLH`r;4vZTyT_On>U z!~s!OTl2}$e^mKbhgbhfJWV%tB65IL?&j2%s>iV{0Q=jcsz2qlqg=I}s8gcNIcBI+ zbdqXH$CC?I`lo;6s)_^wUjZm49fi#irF%nzSz=(gG%5T|gRsiaq;gN|LY6eH;T-D6 zgF;EG`hY5_`vRGb@%|;gXGdoupWdFN$7KnLdr@>7klfibV@>wW$oH=Pr)z!r3fb4y z(cYc;ni10FH z-kPyzYqnv>W6a#vKO+KhiBmK%`()`0C`Q)Vpg*6r6c+fLEpxw`f<&n`&+ym`;eqc| zlmcljhpA3R3Z1BJ+n|eI+8dwE&3-Nv&2%H(2dYxnQ9J=rGFNzAdokp8eXJ-VPAh7P z2vwzjE2w+$DFFR_M)|bU2kip!0}W6jR$+h?Om5@In7<>b)!&Z)z7>!sdsX)LC;oS) z|KStp@E58}jU)pB^j@Eu@VA6!%{=}IfQL=Mtix-sI#1h%UoSnZ9wO=~yc+l)xG_#o zAK_|Dt*yywL=afII7i5uJ;9{tCg;x2*QZcJniU3NA#-E4eAm*Jf?@`1tTnyeCcyU? zxSv_$$SbPCYU7~rM4ygJx331IZyViwqpVRosqeN(MMP7)IY?MG@ zVd|YaZ|3Coz~3rdE;Euth=sIuRoaE z9~X-Gk8sO90|!0jRhZ+cI@&oJi{^?tJCaIhzl|C_`C=C4y9Y!UU{0uZ-Ol5zJ+m#8 z$~MMpbM@oxY@#t@@nLvR_VYvB1aTfT>EO%DqR)?-wtp9;Cce?r9oqU$iHfzstG79{ z9%1YdUnO5JO(3mJq3602QcV^TLAh3%@{YEt)Pq3f<)ir85DM5f&=0=_k`OnIqU*;E z6_d)s9u%AG3>gpzw?JBqCf>h3WuLy+L`a|W?_ED2eNUx?3kvNo&ZalS?Ds2Z2Vgqu zQmWxN$asdRt3%3f9|N~Zz8AYQ5@)~TQh45V?S&1P>*;Bj-#1At34q(ef8w~DRmA}x zcN0pOl25#LQNS`Sw8y`lfF7|%jqYhzc#inC(HP(AsGPfZU{)YRlVF;nT|jZa`9=C& zQBO02Ya`OYT&?+DIlW+0`nBYpo4;4!^xz>ZXLA6igqJAN^TDWPtTR%*QHbR!AfM9p z7ZQH`#8ps2uuAiSsApM3s`_QLcKjYR$A64sDyh_3c7#Z%DeTm%BsPuX4u}Ov#~4ZQ zDG*cZqV((*`NdA6a2xm{9**HUr?e+ZDk{)_fC3ywsqlS{En4eOzy6SGJ2W8+y&mJs zWx-9D9=9Ys-GkEYLN8R_!J_bqe`#E6Ls}tAZrVJ_>kkbB=!Tzga((b^c*f;`*^v<9 zw+CO)(VYGSypNrEqpt0G_MWnkqZ1aTvO6%|n6a0+p|YMPy4N7M_^j4)J2CLa1R)iZ zOPnP*Bsm&2LhER`ghFZh86ajLfe|S!fC$gL#uK>diP6 zyPKXIZIhCRQb0|}Yo0W-_;Y5*y82UhGZ1OjGZIW))R9<$pv#VK2|$+mB>}jEmy|7# ztu>OB4civPvKHAZK+BXTcYit&8Q_OllMtvk1pB}S^a zT)(OszU?bumbX09q?cQNa>Yjs+WhO$UNpo|khEvDx~B;KJT{o~)HX%ms%9MB$&LKPEsd%Tq3Q6dKvvt-}!V@*^TYFfM`PgyE&D`dR&GJ6(q zV6cX`=oQ(E1@xNI9r*GBV2<13AbQyKdA3q&T#bE#5nktK6t}*j614yx6@4oTS+@IQ zeeD@n@*c;ewJL}^YfVM8XMeSXS;gRYS1Vc;e4B*wihwYa0_S^U_$6a|vL$gmqYzUQ z&LSA)Qv?y^keTtbZYEMqEccaBv+uhG5 zJq+WRKNATy(>#HRUYl1VqT%W`yE(1!gnBd2pL*%{uRJ*i9Leg-$Oc69HH1H6P%v8ab*ddUr-&vE_9H#mIJ-0>;I3YC~(qSH=$ zuYMXgiSjOR#};CP_qD{^Rh>`vNV2r<>D*{j7?>)z*e6JaWO7^hpkl=c0ScNyP&;Tk@Kx zzlUnI<+o2}ln#&%t>vbbXCKFY_F%!Z-Lc9kOC@ z3#%K$(Idc)=0dR^pneswzDd`&wTWZ$E68KEHqP+-y|g+;!Vq_vvM>;2}YH@3+-&bI*=0m zoSfb0$tWv8Xw+E=Km*Crt6Yo+;k4RMtp)3YP0PZtoe% z-X`If1uA3ksjJ%rj2>k)Ku@j%Ab%T#i6z0?ux`cU{txI zy)UPp{TFU%m`j_n?)(qOiPc>)&WF;aq%RZiJbA(_^%cq7fpVEW0na0o0D+~SpGBK5 zBu{G5*coJ5Oqi%tBz>n)w(79j}6uN(O8qg@PY|mMOo_nQr)Br(ZqvP1g z0q!}Y&$+#?@~wuxR|ohy)Jsn|M?Irq*uI*w@8Bn8LTx6yielCY)A2Hm!ohHJW?;yA zS9mfMkfspsz*A4L#WzLFpUQJaOH10rB5>d7;nf=!U87#T=A<}0T6^{$d*@yxF&QLn zb60ycR*=&l2@{u)UXpk)cfX~VQ8nLKGXvVuPQ)59$_Wo+3%R10Snp!N19c422&Z$9 z!_wXuh?TeR-c}fj@Jtmo$e<5)9}eD;)+eZsu5)p5b>Y1c4;uv;t9!7tumKs?CvL z&&LNgEovTTpi+v%0KLjfBjIqJf}ljtMb>l>p&-5~(`j`jsiMj40Wk|3CzupPyuyB~ zflfj`3yCH*la@!k#QM1R(LBQt)}fedw3@^6q3KSY4*N)8V1KGTZ5?TgPzZsbf-|>w zdpgtid=jQ8*QsnF(@j93{?UFb)CjdLKMI23oygwV&P&k(>!90f^`~lX4wcsMz1CXv0HBY05`82^(mgDtF^1=7+y?`{pObA8E)I(#w2 z+^Qe5r%zG^miUG#IP4Xq?^j;p^en7YrlsV(wX4wYaW;}(M=XKDB{o+&AHj&_e@Ozl zp*)2kEkUKe81qgF9z9d@bV(bwjcf0>a;ej8+CtD(P7_(-0Tx2uIeNfw!r51CWA~3< z3#pVOkTwEeP^ZTZyT-Rhj1aczF1j84?oFRxQDEGAD6PV zkysdM!cSFo8Rs_2=PetiQcQp$H%ebFAq{M@n**sJ@1X)TS#_#YeCCDXz}u+y&?xvw z%rp*-9q%=RDl$rd4unEco=|J|G;^;KyK+jY>Fv3%fwgMpnO*cEWKDeqJ&@G%Dqq!h z+XT4NtXh&ge-^MU)IX=9v!Sf@Mw4y5>Q8_GieZ#L(r{r)svg5|Jrw4>b1KFpHxQCe z|Kt)LT<{dSGPM+PCbPYDjnwp-lXO=@2XpLGwl0PWg z;eMtS7b~`2wy?FsD>*DT>V)4^AL}494UbK~X^SoGZ@Jysz71SG=V!e-ZR_#L9-ftP zBUE}3j?)RdUdtP`0PPc(`FX1@p7GWT@~^0XQSqmr3Iiw$`ouLe1~1I(J-;t|(p4Wc`K5)OnLZGBhS z`9gK_wuUrfKYZSy<*&S)_*GZS^Fv(cEO6Q1kwix;itUXpe11^4?Ly-us>D@d{9q#> z)%aQHaJh}o0SvZ~d$mo(Gy1}vIcVgdCeOwSfppRw^->vkJFN2w6}nwCUO!y+M#SUy zBNfu>yC4&EYfqlR!pdF9nl_doxgr0jL?-?Dx}9GnCCpbtGkWr@a%>RjAqB;Loi8+UyyG>6HBa(p@lB)o*x)MNbAV_%EMFPkKZ;~ z22`5mMlC~=b~JkeoPk;qxQ)X`9)P}`NLlKJ0MJn|N!4kynGE-**gb1+W~FS#(#_sg zaB|-ZA{MHr7u8nBrfram%#BhZ1&UuytzA)YExjlXp2*q!Gr;h3ER=Y_k6P|iz7?%l z!#(wGe{i!90KX!&W5PN$htQBhn)pO&sTf~fQo~w7h?{9t*G-Rw6y*d*Z)O%LT#%>< z03QQa)O%J#j>UIkfk@AxxBj)u6oF{o(t=FUi`|k9!+e$7r~30`%<%r^RizF038pV? zs=>pa5d&V&+1Rz#PBKj@b)@jr@l+a=RbO!puiM!88@i^W3DJ*gV6kd4&;F<^TX5k+ zj|%2?e3N80Fj(7`5NMO10@TcU+>q45L~kFicdZ)v3gk`7YKACDwLpE7Ddx8ttgdma zWG0pTQ*WYEv-W4^ZeFQsCScnO4B7oop7h#CRLW$_Ikz?E;TmhFyNtCszK&3N;dXom zLE!CX@}1PyQQGQe+QyqoR`Pslk^q2|f=HccL$Q=0g*c~>JZd|bPTClK6Ze}EkbIgr zdb7{d<;`b8+XsUhW$SX&8hv5WT68hdIf{Tmu4}}wwf}^>c64JL|Arf~>KLig;% z_oBUUb{U)kT~6(^O_ezNkAx2{MZ-=Ut7AK&LNrGJv~#F?;Bpm zk;msyz>m*ZbBg4#|4*D0|GUrpyK3rp*qDQMxgr}vCc(*zL~wZfG!WXJCClwdM7}-o34Nzkc0G zpOTY%9VvyX;i~6W<@&5>rKf6hfrE~J^J11+VJ!72%uc!_Gfo3-ICsXGF4Hp7U6Ma}$0 zTpX}^WsOX5$?jo8W+giOt?w+PZmpJh5@uIySL8af>aS5eGcDL$lqZ!{7L;oIk^smP z(uy=`t1F$!bj92h>>b{@CjO$Nq)IF#do+%VruiSo`1iw2uYtb-M{D^kxVe2R5rugx zHA$f*5!5I!D9eXkoDa!`Z@WI%2*8+nY~pD~a#Vyc;u{(7#$Izw^7WkK`-xk)-3cOt zWG2lska;VC|GWEgLUa3G#aFEPxg91oYoYebU5B%Z`TDciw~dp$9o}rcN`a%#W@;SM z*G-MPi|t^Pb2;U4(_gk_QFsO<^!l*aQxpM?|M@q^hNzc>*7aj7^5(cNE4WKe#!48` zkbi{+TA5nl|8RfX=3Hs`e#R4{^t5Ggd8#R3JJal|OL{Eeq5Q?o4-u3vyCX>0NH9zt z2`A0{t-mOuLt{Mrn_g+0KFS5D|;Z;a5s?HuM<93Q|cHdvg-O?W>5IeanTXNj@nDhdQ<3+B} zYpVV1MYnO31H%i3JKu7Tz}$12Gcwfdwk0JYaWCr^c=({Bh#9Y zl-6y>$i%V$Wi4owUapC+BU?+B(;AR(j{X70gVz*m-6V@54aO2berNbg<7s73+lh#` zF@|r$t7@vlF?gT8ef#M3SQn5k5me`}8LO>GL%>i}}8KtK-q?^sLSTO5pDV z%_1%<_edYCny3Gk#9oM<@yRtCF8f-LX)%nUy}2dU#P9@uMX!IL&0#p4aaU%GlF!K) z^|tf$wFke3V(mYj!arXx2Q;1lod?5!6e7`0zj8+r;)1Cd`@$o+jucEjva&#e)4b}^ zV`3w7$JFPBQA zjg6*W-3%UcTY3yppT+=_fp69q0ZN;B@BZn(cG%pmzuPJf-#iTel?&+ceJp>*yNcn-{mk{+D^QhJ-V`7^-W=S-vPuqA=%!9etN^sbpFmS{P#`WP-)q&#xU(olY zr2Fp+PW^546dxV8RmvC7PtTZComD86qYn3I?G5v6`(8xu#jVBMrB3CiV5o%v%Xx4( zO}?Au=rfnE1=dCg^}os+Paem!c2l7l8v;0M8-<#S$3Sjkc!)Y>`9@WZ-if86Kv_y&5?H-aQA zz~t7%HP4 zrOtaii<%le^qlpphir#cLgn#qNY{gxE#{PW{OFV_hpYoiRrBB0fGn0D4tU)tOrvkT zFbM;BWC3paB#U!K!~wD6Mx?0I*PU02O>i1J9H@R06{C#oTQT04aVQ=J+tdi)lE@$b(E0w5*PQu$kTbGP(JuMFw-p=96B`67Ac_OxtVj!aQa^3gZg#zEcT@~@|oLXu}Nn{Qsz44^+tYl`0k zZK^r{VIwd)YKqeYvQ!4^4n$E`vSju$Wq$A#(Gyv6vAGh}AS&`^tqJE2nIGv1`mw|C z?kYfhr($aSzqITBzdt&SjzLWoh zx~7mV^VEAj1(@oAbO!_(_%}UFA0=?qrgHq9gZS@q4Zn1>B;3xMI3gcAD)rIP`hG7i zYGM33AJlgQ1jgxMfS`q+m*|f0?|w2d#Zgj2t}b#(HkMY}=GDbkG`gxitjhotO~n z)+@LE>CK3SqJko4g|c4G{?UEE<5_-tX4?|8!=w;vH4lomt=2PPMk`NGe#ViD%f9u$ zEIVd87fSPVn-+P`NI7elwroK{N0(B};?$P0lg_cbgkI&+HbvO`GxE`=n^(Bd1cD9C z-|Ha6SW(y2!O5?Y*Ws_)4lBwqMWerTC*DTce~9;sfk9$EL*w`YRT5kES>vrr&>}qZ zGm7{>*cK^6<`3E$+n@`%!d6+7n2NX+bCE(hf{gIh@sk07X9{=a*9eITcWlIveTA{~ zXoI;S9w+JYx`pBJVNL={8rJzJAWCTtG?<}7L}aE~2X|V@x)_s|d4Ci8Z8){jP1l0T zO1zDJ2AMJEocx;u4RvH-Mbhkk-Dp$cDV;elGxr;GS9n4|mvMNRA-Iy=L;PK26rqjG zzu-ybr>oOSH+GQ#tRv8|E+3NyDN0{K^J~Sj6B6$$X;Q%-tsY7QXL@ zrx|U*7Th6!xU%yS-m%b@ZxDZ^rRIqS>(f~F^-(M!ZNqlXLa^LLa^sa7nU2sm3_6d{5+k*$Z8+vnZ#XH87Y%t)!PydLUshYHWUg(HW; zuv0hc(;TD~DOOEAc>L_v*?9esDr&^CPBh(Z^7Ipe~M4QYBy?YFOuiyGFoYnlx|8f1&UNR^7r;d-jRg2|KY;&KsjI*lUmnq{-wm zkVGLykbmHzo!qjB98|-N^U#1Soh6p&@%6Z^yPxjk%KN~TMT-F)?MNi z3C8N|%y4n;MLU=B)1yZwIld2q{jN{BLHNYmv@}9}(?57wk0Zx|pF~(kz|OVEy0H9W zr)w};Ldf~>`me*^Hii1nH7dPb)F<)J<}%@97~>`Xd@Z;hLXc=)}-bx?QqBXvLc zD!`?XPY`l^vZ>;@(D4LWol>+m3#gZCUfn-R6Fu1(XM11R;hoZTOnSbpkwrSn>*{8o zu0h^_ojPN>n?CaDH5Xj(a3qjHkFJ{5{FhJBy6w*{!uf=2@11&LCs*-#NU2~1rgi*& zz?CFO{0N8Uc>(IkNPDx~fvLJH4f@AxeL5TaeVl8*VeB15?#!`vII7FpQ*X7Vsk-62 z8*mSjCoMc%=XP3COloGTfNpb2z#W7B+vbtL((KoPY>ScTI^>FRc+{HRU;KMM=gqWp zA>^0Mp0)E7Q1{?x`T%9XjO<{_=E>!`33LN6`y#0(P2CGPeP{b3)jbRCM{yAe@7Jt~ zr}~W9@Xl(kqAh)7O<&38{e$`kTNjbT=bQu6TOP<6hdr&Vv2#&XJjfurWQ<~OwY=45 z8*ti?f<4MwGJ3d>p8s>ZcKWq9`{uA$B6GizK zwasRrjQfD~RQMLjrGCqFb?Dx(-P+ugL`XQKs_p#&8uJCk7w3!dDY3_T?LyNX_fJvM zK?hRJi205x&KllV8{H+k+jKrzyrQ2w6j`6#F9m8k=|6w_URFd`N9O1_mf^4A5rCD_ zt3OG30q<`>4A2Skud6I_r97bMXqzaJr1sYY`Zm5i?pVsps&+vxC&mAyDg5`ffm17I ze6AvRho{7lLlO=E%VWU72BeZkZ??F?)-novlqo{OIh5Z&nfc->KndqTzy*C^P{z*A zJ9)#t@RiB#)rk0A_W{Mq8i3vX6Q9T1l)Ez$9nT;r zkmYCD`e1tRw_j(APC=Q2@Yr7jIJAi`qs;$`{!wpT1!Eb_1SXa?CRJrQGa~4ry zmW|mVtH)YJ1cy_oZ;XF^va|hkM8)8=i(iouc2VvGYD1(E3JJ?n|0@}ds++{l+DFi5 zPDVx}6||p(WV_0E0iL)a?fyz^@XHH@J4HD znFdWPtlOGo(a&6pviG(B`>>`x2Q**2Q+a-JM?b%KeDJl2DbNEn){OEVK%=718sXP} zK^Q2Fd+;Nbs~51Y{N7`B zIB;hDr-X&V=i}7c(9fO32E@MtUp5gLbztkS#4TpWti=ngqi1 zz$05*(%vfIwFuCc%1ml%;@VJ?jzU2j9|-%yGGR+Jxtw17GrrV0CDLQ|Sx(FReskf< z+u-3sZ`io|X4STs))e@I(3y57OIitrowG5x-m?nsDDzfXdI~2Oy9FynR9_X^Kbek0 z{_1_5soJp>S^qn#ECQ6=qD*UDcb=aRy z{(-)gR%xFlce3ZQ05N(C)&HZp^P(lccWlq}jhkh1(>XD{>4XrvfWR#5XW)lY zQbgkgBUOK;p2Nfx0zCSr(qD`JE7=24+h(3YI8Q z@*@G&$5B%NBGY4~cbpKi3$?Zhx(SZ#37Rk23ip8}Sk|9u3*x!ZQ)AcxjW2BWD@}hX zsOLcDhzeZ5?~RGr0!iQ;JDJR~M}1ig-gMC!vj@_=fT}0{tkL$uR}wTLzZgQ5efuyd zSiquJ-3t43eSBgrqlg7|myy90ERD`iO6)?jMKE-(b8^b-a{P}Weew0i7CeuVi&YeZ z!1kwS^EQTy2mw8_q-v1_Hd8Q@sn~fW&){8NlUei6JYnEh$E(%HPyNTw3xDFyP5yDn z+$=2Ao;D8j|3evHSs}r~J9S3_>9wKc94hKCR93*cxIiOMy=ojVUe!+45kluC*T))_ zMp9(I4RmqkXKIZ<$e;0ZfxY$i*uGVHBhmK_CD<4JG9JrT9R6{@SdG%(FWzOJw)Gia z^0mq-6J>fF&!mQ`I^(qWweNS!oi~yEHG6R*4)00-1YO zTHSTh%{k}t{jPS>+jO$XDFEph@HVaxKoUj{H^8NWc6k3Wp@(p0<%14+kztPcwapb!?-y?Sc#wU||Kd$HNVmIL1FZ!i~l zqeaA#zqORjAW0Wl=i`r6mR68qS6+0ho0s|62KZ65Jo!AX*>TkddggqVGdbdt{~?`AHO)Gg++)lMU8)Fpz=PG*5gOm zL9a+R$2(#vl=Dj`D%(<+p57_R#hr=!TBjo`fKooGu|Cj9Mu#(FfywFGKqUMDcrM0^ zgg@{;BH<68?NUk1{1xQA?wvaKXwzBlK2Ve*-3CQW@LR_mj$W^nF0m{*1dXE8+J~2y z{h1B>y^?s@!s2>*7lWbo<2f>H+;3neY0E!_+CH*ionH(5!%WfJEzQh$W>+nJ)JA=X zRIVkVlG!D3Nm+t!hpqE}$OGb5`Y%#w%CKJTXcC({h-%St=;lmt7A&SSU{TWxd8Zeh z6%qv6mJXJ`OYw_zw{sNUo1}SIVQO{RJZQ&NLK^|1ZhF4C?H6e8agNnA`rUtP67b|kq$422uSa}NR84$2tiRpuhL0E z5kU|FqV&$qJ9B3a-qAT{?)h*(-1A}2to_VdvuD;`d+oi~`ai$_vB6yXU*FbW_47Bp z1qU6W>$8v@m!qEo}tb`+{gC%M}{YSpj7h-z`=(3GtM?$e+GMTXy`%17L~c?Jcw; z*^+o!Mu>Fxkq}sx!DL)}`jO1J)Rcu=id2#-YjJEa?A4oAk{#p3?_^OOY*4RqQH+pU z=-DNS-mu?JZ8Ww4}!BldPBj=Y{uHjgSOmuArTjyHz z@dB>qudmGq`Ml#CrJ3Gdz2w@88yC}J>0>|deo1}0Iy!Nz{bO7VNu?ey!(8ZO$q#nXhPMIvj4qqK@Ol%~ z3Fh(U=nd6b=pirF3-`%3WLB{?_;?8L)nv$8zDFqTXKOTc%bIO?gW4F0bjw8=)3*bM zmgozdu_ZS3i$=~}45Iy;Bo!hE&x-Oc+(dc+@I#Ca-E>Hic~Gg{q2@5UgPZ66z}-N6 zEt2HLIqcA*kO~4WRz~{gavoQG-lX|?$oJP!-mB1*ZZ7AKouvMF-vTUi$9`>+3BCEl zF%Kyk3FErPv8(zmxd@><4Q(cw@Glxo^fiY1T(a8f!rDqs6&B3YdC7muIP#XmX!(5Z zT0oAo?a=#paF3=I*_I=?r!whb)9^ z%{1-#9{}5w<`Cfvv|6u0;A|SA1_UcX^|qrbERFk=&%1e1;u+VWHKaU|qX^ z7noDP?Y-%|BG*2}7XO-eRNBg{V@Y?|xAP>2yvg%Wd-Lj&NGtET!xkT!r1w54#`((! zjYxmR(vqj!IYSnYszI)ei6UJT=cgy0VmJbxrL&TfRmi$mk;`WFMd2~HT+~~JzKQ1i zOeaD0`;`qc1Cg53gch4Hz6DODhbqEX6s3nZ#!tpXs=wQykb$ddS7_rRBEoMggo7?* zHRWn<5bjQ}4O^OiLEgdUle7DMo|VubL_w|kk&9Vg*)crql}o>8B0jn#YB|ZRq!;y4xSH!; z3N|N+WWjbF-@g>Im4X@z8Q~p+8ZMhg`|DTB2olZd76ZHJ>r5gR?JqKYu$DJhRl7Z2qN+SVI^=)sIQeFHw;MEmK z9?B;oi3v@5*Uud$hNJp0`I(+3bgD%)3Tox-I)v*2V-X8_L#O9q@r>#GdfD&y)5$}( zE(paoqsEAaL$AY|$L8+XN8(o7DRW5Meecpuui~>GgZvbbiej05UlgC{)@qfT;`ce- zJrRB35&?XEj2cMm$Ub;0@-!#&p^4D~RZ-Z0^_OFfO*qc1&MQz_{ODAYO z&1k|sXyP=hj?78HFvc}?TcovKv8LZjUzuQ8knq=ti|o2__{E(nSkL*Pr=o zKrhlt9S_Na*ZF*4OwU07j>}Hu#nN~drh&Wmmo&XKLe~j-qb*EDuI75!cRhrcSrg|I z2g&S!2lEQFZX}1sqY$3}v`RU)3ah1XC#c-tGq-G2L`R#^6}g^sQDj&Z3htEGT4S3C zJ0f^A>iL3(A;H+MLjA%I*I&S1(x*6Te0X?Hl}cgpmEk)DXId0S+Rvj|no24UpccDOoVSobS;5m}eg!?ctzGP# zfL+WJ9(}8Z#xS7tSJ8n zb@}gV|MCI%^MzzhGvLghJ0)~-z%EmAvv%`im08qgGIy#@0S6?Or-0A*-<$$Ci$03z z8=j1XoC1_}T93{nP66|yK}3z{Noab=9-|v^L%F=>%Js?+*H$7}j(_%q3`g8DUQznB zfeCer5eQ*L^dB0OYm~`vW)8b*NXsHY+U$`vq zp~4z;t|vbemcztHKls48hV8OpqQ>I){V|fbw#Fdkwe7NhXk8>PM#W_RR$Nm+;@Yw@v)kDWxBpw%#Rb2R4W?lb;fvKV ze_r8;uzPF0FctzC;Et^#GZ-=;<3R2*=5~I6BLEnkI8!sfO!`=S2nn6O0K_AmzH%&i zI}uRt%HTjU>N3-7(~Z6aBs+{D)($Gx33+}B2z*me_?W_>@_!BeR&M>LV>lhi(dBczj4dba}ldBO2G9iXDG zRD&^jO9}~1FFTJI@T#*~SPt1kSV|xB0dT_<`)xSeVYu3iBE}~%cB5Jt&Q?dHehZ>A z#0EwpEiraS0)>`O+_dY4kGdX>%R9`RlZ_9SS>p@r>N7=sFvu$ijn!;k9>0TxE zq0?97CZvAso~W3mAOGb*9QhCPRe&X+mDeBwaRh!!E36;_LX2QUO6UkDm5R>>jr z4}6>9G`!J zeT1kGisI{fxx{3Mu+P4#q~s2Qu$;{Z)B5%=LTK4FdmR>bXFSZqho@oECKX>VM)?5a zg%)?>g|WUO&kWQm#JG`k=33g>Q1^~H2~bhoKExgnCIoEevYQa*imE1akzY{8iT97&=j((e3fhw9_sR|n zm09eP6DUoU$!+%3PBh9vglgg>CQIOb=$-V7$c;Elsz!U~xavUicTeOx&7jp_81ruVlklPImn}rKekP zj0iJVOWJ|FFp82Driwu59R)iMA3_H$_*aqAIMJi**{?z+k269mC~?~r zb5;a(R=9?|Ui8`K&$2A@6n)QIyJv)MaA#)5hn5QE3t8cc=6v3cGj8uaa^_bDJq|CbXDz||jV zdl4t$6QJF(Gex3@`7iZ;Ir&ec|L)5Fbj1Icj&O99i=0008T66wy`fAkV|KlO?iBl9 DMPjOt literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/end.gif b/tools/authcon/auth/images/end.gif new file mode 100644 index 0000000000000000000000000000000000000000..99a2c30a97d9cf34638e28dd286462a5220846e2 GIT binary patch literal 862 zcmZ?wbhEHbv}6!w_|Cw<(7s{EzRRCKeLjEw;moziZ{K+N=-xYq={sIN`OFZo>hqh= z3{C49O4c#7Z+ZXnGeh?VppH>68Un*61av??0p$e-4rc~o4jGRP3l27O2&?fdaA-Kx zE}*O?^B`c+(QYo@ggYk!A2jqSICsf-Zd!73vPST#n3J29o}O-yd}@y8=4EGRTZpo; HFjxZs(KtWi literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/help.gif b/tools/authcon/auth/images/help.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a16b0bb6b3c069c421ca8cbb2a261a3bc09a0fd GIT binary patch literal 868 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 IT13R?f6#bG!vFvP literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/move_down.gif b/tools/authcon/auth/images/move_down.gif new file mode 100644 index 0000000000000000000000000000000000000000..82ac5bf37de11f532a847858b8409473fa716eea GIT binary patch literal 842 zcmZ?wbhEHb9xwF!^|okhR#7j*Ur&n;01xtO4x97yQa1XF6m{4{e^E?=I#cVs zMbXeC)2S^tLA63nx}X+zZ7S`#NG*5sT5L8AEvxUIU*`75zW4m`x$pCN`F@|fCnPM` z?_iPxazN_{c@wo>Ni{yax_7za{hw5O##ed7Rqi`=*(bTq>(d&~(^Vd^mG04B`=-?U z^6C$!OAe$o9!_ue&yWUY$pbUwA7r&0`TW~pep}diMR;y|#0BNCyp9tE-BDlMiWc=I zl&TZUG^v-zGOBf1wd2`!j|GjBd6KDuW>c|z_RH3#+8@@h-rQ>F{9D=s-}HjwE_9E; z;5g`v@MIQdmSFi$_{$8>H{j(KY-~bcru4njVs@G|Fy$JHkOc6W{m(QN%cd*Zmg_rT z1Q1O}$+n0KisSi8LE}W%J?I>QmOhBi?Me`-;_`2a+gCs4EAu52ms;n!!v5PMkd)t> zBOc4H*5*kbmdK4AgHS3n2pb;NDCYT>wAZ@Lt$kbF!%!gBm0vY#bWqXsF6Ovy1_*Vo9orZs~#cJRX{Fp2pV{04$h8pb5z zV=dL>Z)+EK|EoQ)Y9>qmm@`luicpC$_YRPVU|X`3<$2ifWg&ss7Eg*(Ohd%VB#AiN zo=V6;w%;$1n|2G9c|2f_9Ed(*;c!7uQd%c0tOQq;DPF_1o4%qd7|_tN4;lNHf&shX z2s$G6V&H@q)Mk2WQ+XIqeMnsq`Y}Kc`j{9q3H|dNWQB9DY}ykmWk3oF%_Q{(hsuG} z<6MekgLj$1_}(2o-s``yEr0_Y1Tjp4wUmqIv1eClC_(8de=u-}=@=4aZ*$xcF6u8J z8$ii6yL(*5s^5C2DD;J#C)J3^8%kGNk>=vgH(7#_hbyuQpQDjk0ux&pW^Lyj?ssPR zx1Fy!gli?KCqh0Fov)Tk*racReA48?orX5kZ_S^&rFQGc1)18Kxj&V) I!wMb#2N|LShqh= z3{C49O4c#7Z+ZXnGeh?VppH>68Un*61av??0p$e-4krdy4UP#5794Em5Y~!0F=1f? zBd@a8oD&xqj&@5ZJDoYPaq;nf1?Mgq&rM5CPSyxs6?1aa($muol26U?+`R1UY(Zuw G25SJx%s|5c literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/status.gif b/tools/authcon/auth/images/status.gif new file mode 100644 index 0000000000000000000000000000000000000000..f202cc1f5df67076ad8b0efbc44958d3e86c2c12 GIT binary patch literal 1043 zcmZ?wbhEHboXsH2@STByp?$-SeV0Ff`h5QU!# z8JgBJl&oWD-}3(DXNK+#KpmrCGz5lC2v96uOXIdlXR8V@#e2y4Zh*s$<$ zyMVIS9FM?746Ll$S$9rsTztHrpOuHfbJLQOljV6A#GKredU_%sD_6nFz-11zEPPL$ z*;$ZwXf|7;+J~DHG|n$JZ&fmtnv!{WhF||BpR6m-99R3cGTpVBy!z6@_>En6Pnu?j ztTf#%qK3Vxt{HAZ$&;myON^0d7ehp s$6Lob9xj{qX17+tgP#8QduR9T{QUgFV(a1poj5 literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/images/update.gif b/tools/authcon/auth/images/update.gif new file mode 100644 index 0000000000000000000000000000000000000000..e5f294a34d4ea7fcd98ab9261c376d9e7f50533d GIT binary patch literal 1078 zcmZ8geK6Z+9DkB{U2RfJO*enUuDhijX3P~;;;6A}cP%#6>b(52jMb@|q`zn=8q{zW zuMI*&jk4UDdTUV1LYbFM+ITtAp51v}wX?dQjPIUgZh!21&mW)rKA)HG_qlsM3G{b! zkFr5FXak{-h+?OxA{TC{GpFRkFAE*R3mndgKlmcw<*QPsh$6@H1rA|i`_S)QVM@Aw*@gj(Nk>->2QftTeclkS|lqWDaBHz=hw_-b2dddG#V zp2%!fZ2m}mp*o@XaboF&pnOIseVS4=E2>%eu70KXr;Uo1-Lj^?WlFf!0rFmG9fZEe zpw_~Z1(;uf=YPRV9c*sF&Ms_igZCxb$LCAf-^jdUZh8_@FK*TG=t@!bTwcR-Nz*GY zqViL+;nWrRnPi2ae5!c>n);!(6GD@kFQm7hOKvNz6obUH1kdD!GGS zGLl$0B$PhNsL|f-gRJW5w6gIc`4TU8=w_>~zH_(rA*7V3b1JkdHRM%3`JsKSUk#1- z)}^=q=oy9K2~c!xcML-NLs0eu?(~g8_b_w~LACrvLyK;B9DbXEo*ux35b?hgpd}Ft z80c#)gFv&8Is#URgE_1%K3aXYMT)F-(|RRmW1U>AT%R_@4sO^4W-#A?-$D>T!I(rm ztkpMpd)jBV|7wq}>Bx*f7pL_cJwc2y=RS~#U>mX&IYMl>lS&}A!Bfu>Q4p~@Ln6OD zPX+Li`H#!wHhtMJj{_`{4?=wn91dtmy_SiEVqmq;hO0RAxf|^%4^)&y4{g_qKVUZ; zK}EzN448Pqp-YZKv0RLwp3q+rnh`)_oeYc_gl3bEjBxIaZ7X6m8%RN_j?}+_M-Gr0 zoU7-U;a%o29=NZ;d;K@I0r-I*g0l?5b0rBaVbA8Q079?V`@^&!F?W_kiF+J-giHSy zkQty!bK3xgtXD*v%m{Nnbb@|3Lc_EdTz@Usis=@vRP>6j+grU~b>`YN70r|yre??PFp~fBD^vg7A`uz6^3%2YRw%y^{XjkF593f+Yg=bWaeVCF< zVKJTP=H_PEuNN6BW(Rs$c2{%eh5Tk@a?<4Ts|35)N3>{@Hg%d$<8p=R7`-o=^75h) zjcO|iI-OrINllO7Y{ni^hkJbzO&gVBdjCD{e{*fJFiUn>*xVQLD}zEie*T2 bgr~IRsQLpfjlE=oz+2tjJKH8SDmwNLu5elY-1H1tf(rKy(Z$;Rn}Iw>nlpn7lh*NA_cH&W|VWc`omJlJh}C z7<)f&3)+H~5ZXhO`0|SV1*Lv``MYO|d}0c{qh;@WcFq5bQs1-1KBo%3qhwx@*Z0Mh z?Gu#kzn}<+t2lU}>QKBgC{Yy@uX;aG9rD$8VWQfIuQeZ~)E~L1J(_y=M0)ebms%pF zZKreevAKqG*ZSg%1`|sj2}_?OSB#}9#?z}NvQ*P~HRh7G zm)0hh_X&%PsfwY?D%0Ig$f+Kcls_)k%!&$(x0%XyWfD2p%Cz(W`IR(vP&&Hf^g3?p|Fv=w+Pm)Nu&hbLH zsK0<1fPQgwYxV3adh_kf@E0n9(jX;oYgx2RL$>qwz~r7GOEt%X#STn#SE}g@S5LR+ ztO0IzkuOo27WY;jr=0DuwS4C>XJ=YKQh!W9tVAwOiq3s)_g~Wp(Z?lGg*3sjy7|}* z4DD2&ljENH4WaJtNa`7UVy`SkXht;TWMT7EbDx$WrVA(7F1WwlgXXpD>S6ED5=C>4 z)vJ52IP)6)ydxGRW$$hC)i~^ay$;zYY*I#D>B>CYrPyfC_6=3K?WAX4+QCrwbNuaG zWpc-D620G!0;cz!?M>(D+-|K%=)gf}fWC{RS312>O8+%6X(&XxiFIZu+3pnvI`|J2 CE%|W( literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/blank_btn.gif b/tools/authcon/auth/resources/blank_btn.gif new file mode 100644 index 0000000000000000000000000000000000000000..b41bab9ded408ba3f01a6672c589f5ff961d5ed1 GIT binary patch literal 824 zcmZ?wbhEHb+09B$5(L=XGEH2A|=1a=FjveXsZXp6AH1fxY|AbxNoFl)pzsOvFV( zB!x;<)I?o0M6;TvVkYKdA(nO5Roui~JjAn}hDw-(ON2zCB&m`n>5?Hyfi}`;@tE6L zbLyC?tA=XUSSm9$R|~Z)3Yu=}t{&=HP}~jEaE;JN7znet-Pe?P|m_{GrezuT6T&E6VY{|Q-nS8~;sqqE!Q z$5wXroVhY|_Q8#HI|e5|f4h0Br4Qpp=a&_?pXiy z&atKUF}5MwXU3m(_fPeWtlHYMVfy5S{!3qiEl3ulnwtAKKV4F*7{Y-a9KTdCYGC$Y8V!7=91K+rc0RR91 literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/close.gif b/tools/authcon/auth/resources/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..807d354b4ca6d96c0a71be348e518c18d507943d GIT binary patch literal 874 zcmW+#JBwCP3>>gH6#&|-Lmv>vw6eh7(u_2^QN}Q)v5Z~Y=?*7F2AO2_0H^t6 z-6>}{(^<|YX_`_OC5D({iOt+%`aP&%1T$E{mcw#}dQ! z)J|Ba`FN*75z0`7+8#?aN$kP zWJQBFPLJ&FF6>+`{_aG)leFl|vcO{Z=(FEC&U6y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/authcon/auth/resources/delete.gif b/tools/authcon/auth/resources/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0f48916e3be33d0233ef7862ae1702bfdbfe704 GIT binary patch literal 842 zcmZ?wbhEHb + + + + + + + + + resources + + + + + + + helppopup + + + + + + + + +

+ + + + + + + + + + + + + +
+ + + +
+ + + + + +   + + + disabled + + +   +
+   + + + disabled + + +   +
+   + + + disabled + + +   +
+   + + + disabled + + +   +
+ +
+ + +
+ +
+ + + + + diff --git a/tools/authcon/auth/resources/forms-calendar-styling.xsl b/tools/authcon/auth/resources/forms-calendar-styling.xsl new file mode 100644 index 0000000000..43b0a7ec2d --- /dev/null +++ b/tools/authcon/auth/resources/forms-calendar-styling.xsl @@ -0,0 +1,99 @@ + + + + + + + resources + + + + + + + +
+ + + + + + + + + + + + yyyy-MM-dd + + + + + + + + + + + + + Calendar + + + + + Calendar + + + + + + + + + diff --git a/tools/authcon/auth/resources/forms-calendar.css b/tools/authcon/auth/resources/forms-calendar.css new file mode 100644 index 0000000000..50703e9cd7 --- /dev/null +++ b/tools/authcon/auth/resources/forms-calendar.css @@ -0,0 +1,92 @@ +/* +* Copyright 1999-2004 The Apache Software Foundation +* +* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#forms_calendarDiv { + position: absolute; + visibility: hidden; + background-color: white; + layer-background-color: white; +} + +.forms_cpYearNavigation, .forms_cpMonthNavigation { + background-color:#C0C0C0; + text-align:center; + vertical-align:center; + text-decoration:none; + color:#000000; + font-weight:bold; +} + +.forms_cpDayColumnHeader, .forms_cpYearNavigation, .forms_cpMonthNavigation, .forms_cpCurrentMonthDate, .forms_cpCurrentMonthDateDisabled, .forms_cpOtherMonthDate, .forms_cpOtherMonthDateDisabled, .forms_cpCurrentDate, .forms_cpCurrentDateDisabled, .forms_cpTodayText, .forms_cpTodayTextDisabled, .forms_cpText { + font-family:arial; + font-size:8pt; +} + +TD.forms_cpDayColumnHeader { + text-align:right; + border:solid thin #C0C0C0; + border-width:0 0 19 0; +} + +.forms_cpCurrentMonthDate, .forms_cpOtherMonthDate, .forms_cpCurrentDate { + text-align:right; + text-decoration:none; +} + +.forms_cpCurrentMonthDateDisabled, .forms_cpOtherMonthDateDisabled, .forms_cpCurrentDateDisabled { + color:#D0D0D0; + text-align:right; + text-decoration:line-through; +} + +.forms_cpCurrentMonthDate, .forms_cpCurrentDate { + color:#000000; +} + +.forms_cpOtherMonthDate { + color:#808080; +} + +TD.forms_cpCurrentDate { + color:white; background-color: #C0C0C0; + border-width:1; + border:solid thin #800000; +} + +TD.forms_cpCurrentDateDisabled { + border-width:1; + border:solid thin #FFAAAA; +} + +TD.forms_cpTodayText, TD.forms_cpTodayTextDisabled { + border:solid thin #C0C0C0; + border-width:1 0 0 0; +} + +A.forms_cpTodayText, SPAN.forms_cpTodayTextDisabled { + height:20px; +} + +A.forms_cpTodayText { + color:black; +} + +.forms_cpTodayTextDisabled { + color:#D0D0D0; +} + +.forms_cpBorder { + border:solid thin #808080; +} diff --git a/tools/authcon/auth/resources/forms-field-styling.xsl b/tools/authcon/auth/resources/forms-field-styling.xsl new file mode 100644 index 0000000000..408967ad5d --- /dev/null +++ b/tools/authcon/auth/resources/forms-field-styling.xsl @@ -0,0 +1,554 @@ + + + + + + + resources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/authcon/auth/resources/forms-lib.js b/tools/authcon/auth/resources/forms-lib.js new file mode 100644 index 0000000000..6b7340a3cf --- /dev/null +++ b/tools/authcon/auth/resources/forms-lib.js @@ -0,0 +1,195 @@ +/* +* Copyright 1999-2004 The Apache Software Foundation +* +* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + * Runtime JavaScript library for Cocoon forms. + * + * @author Sylvain Wallez + * @version CVS $Id: forms-lib.js 57536 2004-11-12 18:33:30Z sylvain $ + */ + +// Handlers that are to be called in the document's "onload" event +var forms_onloadHandlers = new Array(); + +function forms_onload() { + for (var i = 0; i < forms_onloadHandlers.length; i++) { + forms_onloadHandlers[i].forms_onload(); + } + // Clear it (we no more need them) + forms_onloadHandlers = null; +} + +// Handlers that are to be called in form's "onsubmit" event +//FIXME: this single var implies only one form per page, and needs to be +// visited if we decide to support several forms per page. +var forms_onsubmitHandlers = new Array(); + +function forms_onsubmit() { + if (forms_onsubmitHandlers == null) { + //alert("onsubmit called twice!"); + } + + for (var i = 0; i < forms_onsubmitHandlers.length; i++) { + forms_onsubmitHandlers[i].forms_onsubmit(); + } + // clear it + forms_onsubmitHandlers = null; +} + +/** + * Submit the form containing an element, also storing in the hidden + * 'forms_submit_id' field the name of the element which triggered the submit. + */ +function forms_submitForm(element, name) { + if (name == undefined) { + name = element.name; + } + + var form = forms_getForm(element); + if (form == null) { + alert("Cannot find form for " + element); + } else { + form["forms_submit_id"].value = name; + // FIXME: programmatically submitting the form doesn't trigger onsubmit ? (both in IE and Moz) + forms_onsubmit(); + form.submit(); + } +} + +/** + * Crawl the parents of an element up to finding a form. + */ +function forms_getForm(element) { + while(element != null && element.tagName != "FORM") { + element = element.parentNode; + } + return element; +} + +/** + * Move a named element as an immediate child of the element. + * This is required for help popups inside tabs. The reason is that CSS positioning + * properties ("left" and "top") on a block with a "position: absolute" are actually relative to + * the nearest ancestor that has a position of "absolute", "relative" or "fixed". + * See http://www.w3.org/TR/CSS21/visudet.html#containing-block-details $4 + */ + +function forms_moveInBody(element) { + element.parentNode.removeChild(element); + document.body.appendChild(element); +} + +/** + * Create a popup window for a named element. + * + * @param id the ID of the element to make a popup with. + */ +function forms_createPopupWindow(id) { + var result = new PopupWindow(id); + result.autoHide(); + // add to onload handlers + result.forms_id = id; + result.forms_onload = function() { + forms_moveInBody(document.getElementById(this.forms_id)); + } + forms_onloadHandlers.push(result); + return result; +} + + +function forms_createOptionTransfer(id, submitOnChange) { + var result = new OptionTransfer(id + ".unselected", id); + result.setAutoSort(true); + // add to onload handlers + result.forms_id = id; + result.forms_onload = function() { + var form = forms_getForm(document.getElementById(this.forms_id)); + this.init(form); + sortSelect(this.left); + sortSelect(this.right); + } + result.submitOnChange = submitOnChange; + result.forms_transferLeft = function() { + this.transferLeft(); + if (this.submitOnChange) { + forms_submitForm(document.getElementById(this.forms_id)); + } + } + result.forms_transferRight = function() { + this.transferRight(); + if (this.submitOnChange) { + forms_submitForm(document.getElementById(this.forms_id)); + } + } + result.forms_transferAllLeft = function() { + this.transferAllLeft(); + if (this.submitOnChange) { + forms_submitForm(document.getElementById(this.forms_id)); + } + }; + result.forms_transferAllRight = function() { + this.transferAllRight(); + if (this.submitOnChange) { + forms_submitForm(document.getElementById(this.forms_id)); + } + }; + forms_onloadHandlers.push(result); + + // add to onsubmit handlers + result.forms_onsubmit = function() { + // Select all options in the "selected" list to that + // its values are sent. + selectAllOptions(this.right); + } + forms_onsubmitHandlers.push(result); + return result; +} + + +/** + * Show a tab in a + * + * @param tabgroup (string) name of the + * @param idx (integer) index of the selected tab + * @param length (integer) total number of tabs + * @param state (string, optional) name of the input storing the tabgroup state + */ +function forms_showTab(tabgroup, idx, length, state) { + // Change state value + if (state.length > 0) { + document.forms[0][state].value = idx; + } + for (var i = 0; i < length; i++) { + // Change tab status (selected/unselected) + var tab = document.getElementById(tabgroup + "_tab_" + i); + if (tab != null) { + tab.className = (i == idx) ? 'forms-tab forms-activeTab': 'forms-tab'; + } + // Change tab content visibilty + var tabitems = document.getElementById(tabgroup + "_items_" + i); + if (tabitems != null) { + tabitems.style.display = (i == idx) ? '' : 'none'; + // execute event handler if any + if (i == idx && + window.onTabShownHandlers != null && + window.onTabShownHandlers[tabgroup] != null) { + var onShowHandler = window.onTabShownHandlers[tabgroup][tabgroup + "_items_" + i]; + if (onShowHandler != null) { + eval(onShowHandler); + } + } + } + } +} \ No newline at end of file diff --git a/tools/authcon/auth/resources/forms-page-styling.xsl b/tools/authcon/auth/resources/forms-page-styling.xsl new file mode 100644 index 0000000000..de66576b8e --- /dev/null +++ b/tools/authcon/auth/resources/forms-page-styling.xsl @@ -0,0 +1,353 @@ + + + + + + + + + + + + +
+ + +
+
+ + + + + + + + + + + 0 + + + + + + +
+ + + + + +
+ + + + + forms-tab + forms-activeTab + + + +  !  + + + +
+ + + +
+ + display:none + + +
+
+
+ + +
+ + + + + + + + + + + 0 + + + + + + +
+ + + + +  !  + + + + + +
+ + display:none + + +
+
+
+
+ + + +
+ + + +
+
+ + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/tools/authcon/auth/resources/forms-samples-styling.xsl b/tools/authcon/auth/resources/forms-samples-styling.xsl new file mode 100644 index 0000000000..67d8ec1d3a --- /dev/null +++ b/tools/authcon/auth/resources/forms-samples-styling.xsl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/authcon/auth/resources/forms.css b/tools/authcon/auth/resources/forms.css new file mode 100644 index 0000000000..3a23ade32d --- /dev/null +++ b/tools/authcon/auth/resources/forms.css @@ -0,0 +1,75 @@ +/* +* Copyright 1999-2004 The Apache Software Foundation +* +* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +.forms-tab { + background-color: white; + border: 1px solid black; + border-bottom-width: 0px; + padding: 2px 1em 2px 1em; + margin-right: 5px; + position: relative; + text-decoration: none; + top: -1px; + z-index: 1; + cursor: pointer; +} + +.forms-tab.forms-activeTab { + font-weight: bold; + padding-top: 5px; + cursor: default; + z-index: 3; +} + +.forms-tabContent { + background-color: white; + border: 1px solid black; + padding: 1em; + position: relative; + z-index: 2; +} + +.forms-validation-message, a.forms-validation-message:link { + color: red; + font-weight: bold; +} + +.forms-validation-errors { +} + +.forms-validation-error { +} + +.forms-field-required { + color:blue; + font-weight: bold; +} + +.forms-help { + border-style: dotted; + border-width: 1px; + padding: 5px; + background-color:#FFFFC0; /* light yellow */ + width: 200px; /* otherwise IE does a weird layout */ + z-index:1000; /* must be higher than forms-tabContent */ +} + +.forms-doubleList select { + width: 150px; +} + +.forms-doubleList input { + width: 40px; +} diff --git a/tools/authcon/auth/resources/help.gif b/tools/authcon/auth/resources/help.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a16b0bb6b3c069c421ca8cbb2a261a3bc09a0fd GIT binary patch literal 868 zcmb`G&1zI}48_w`2N9uufKXv56&Iol2}q^jq7|)WHmxt9B3auvxKdDXsjIB?G3;)@ zQo6{(M-cH51efXW{GXwL;Z7#W$vG!?Uc7w1_2kV}yJr7QF^$hO9uwK5ST2{%?`=IE zJo!fO+vSCug;|=FHj%lThk2Tpd8-(15f*7t7OmcN%dkw#vTTi(TZL6xm6e!UyLDKn zbwOLef(DCWx?6h`;hyg0-dal*;gKHY(PBX{!!te0vqg&D3a|7kuZAO|-r=3z<;_-D z0|seWLW>%U!3G*EhFgM^6B$tvEq$yd%Z#kZmRwj+tcxi(w@CSW8ypC6lk?-YSk0%I0wu^$w%u z`tVMp!wwx`C=}8lt(y!U0v^!34qOTI(8Q_-dYkoMu-Rjq&+hEK|NiZGcH_#wSHFJm z9IwuwzTP_8*!_I-;eOpd+I;ru*80c4=LdgIzih0(U7R1j`#IV6+R3BMv# + + htmlarea + + + + + + + + diff --git a/tools/authcon/auth/resources/htmlarea/ChangeLog b/tools/authcon/auth/resources/htmlarea/ChangeLog new file mode 100644 index 0000000000..8e185779ed --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/ChangeLog @@ -0,0 +1,1185 @@ +2004-02-17 Mihai Bazon + + * lang/el.js, plugins/ContextMenu/lang/el.js, plugins/TableOperations/lang/el.js: + updated headers + + * lang/no.js: updated (thanks havardw) + +2004-02-09 Mihai Bazon + + * plugins/EnterParagraphs/enter-paragraphs.js: + Plugin that enables Mozilla to create a

instead of
at ENTER. + Code contributed by Adam Wright. + + * htmlarea.js: code to call onKeyPress for plugins that define it + code that keeps single spaces as   + (thanks to hipikat @ IT forums (Adam Wright)) + + * ChangeLog: + ChangeLog is acutally automatically generated so there's no point keep it in CVS + +2004-02-08 Mihai Bazon + + * htmlarea.js: fixed possible bug + + * images/ed_align_center.gif, images/ed_align_justify.gif, images/ed_align_left.gif, images/ed_align_right.gif, images/ed_blank.gif, images/ed_charmap.gif, images/ed_color_bg.gif, images/ed_color_fg.gif, images/ed_copy.gif, images/ed_custom.gif, images/ed_cut.gif, images/ed_delete.gif, images/ed_format_bold.gif, images/ed_format_italic.gif, images/ed_format_strike.gif, images/ed_format_sub.gif, images/ed_format_sup.gif, images/ed_format_underline.gif, images/ed_help.gif, images/ed_hr.gif, images/ed_html.gif, images/ed_image.gif, images/ed_indent_less.gif, images/ed_indent_more.gif, images/ed_left_to_right.gif, images/ed_link.gif, images/ed_list_bullet.gif, images/ed_list_num.gif, images/ed_paste.gif, images/ed_redo.gif, images/ed_right_to_left.gif, images/ed_save.gif, images/ed_show_border.gif, images/ed_splitcel.gif, images/ed_undo.gif, images/fullscreen_maximize.gif, images/fullscreen_minimize.gif, images/insert_table.gif, images/ed_about.gif: + optimized images (thanks to Alexander Kandzior and OpenCMS group) + +2004-02-01 Mihai Bazon + + * project-config.xml: release candidate 1 + + * release-notes.html: updated release notes + + * examples/index.html, examples/makefile.xml: + added examples directory index + + * release-notes.html: fix + +2004-01-31 Mihai Bazon + + * makefile.xml: ensure correct file permissions + + * plugins/SpellChecker/spell-check-logic.cgi, plugins/SpellChecker/spell-check-ui.html, plugins/SpellChecker/spell-check-ui.js: + spell checker now reports some document information (such as total number of + words, number of mispelled words, number of suggestions, etc) + + * htmlarea.js: removed some custom attributes + + * plugins/SpellChecker/spell-check-ui.js: + fixed bug (frame scroll in IE) + +2004-01-30 Mihai Bazon + + * ChangeLog, release-notes.html: updated release notes, changelog + + * plugins/SpellChecker/readme-tech.html: + updated text about Aspell Unicode support + + * plugins/SpellChecker/spell-check-style.css: - lorem ipsum + + * plugins/SpellChecker/spell-check-logic.cgi: - optimization + + * plugins/SpellChecker/spell-check-logic.cgi: + - bugfix (removed tags) + + * plugins/SpellChecker/spell-check-logic.cgi: + bleah.. this version seems to be safer; no mo' HTML::Parser; DOM rulz. + + * plugins/SpellChecker/spell-check-logic.cgi: + seems to be better now :-\ hell knows how perl & unicode works :-/ + + * plugins/SpellChecker/spell-check-logic.cgi, plugins/SpellChecker/spell-check-ui.js: + - big performance improvement (suggestion is now passed only once for each + mispelled word) + - bugs fixed (text already corrected in Unicode is now correctly decoded) + + * plugins/SpellChecker/lang/en.js: - added word "Revert" + + * plugins/SpellChecker/spell-checker.js: - lorem ipsum + - window is a bit higher now (450px) + + * plugins/SpellChecker/spell-check-ui.js: + - fixed IE bug ("undefined is undefined or undefined", or something..) + - the highlighted word will now remain in view (window scrolls if necessary) + - functionality for "Revert" + - (tried to) eliminate some of the screen blinking in Mozilla + - select the current dictionary on first display + + * plugins/SpellChecker/spell-check-ui.html: + added "Revert" button (reverts the current word to the mispelled original) + + * plugins/SpellChecker/spell-check-style.css: *** empty log message *** + + * plugins/SpellChecker/spell-check-logic.cgi: + - fixed (hopefully) unicode support (by the way, it seems that Aspell _does_ + in fact know Unicode!!) + - remembers the selected dictionary in a cookie + - removed debug code + +2004-01-28 Mihai Bazon + + * index.html: updated main page + + * release-notes.html: updated release notes + + * htmlarea.js: jscrunch-safe + + * popups/about.html: + stop tab click event so that they don't get selected + + * reference.html: some parts updated + + * popups/about.html, examples/2-areas.html, examples/context-menu.html, examples/core.html, examples/css.html, examples/full-page.html, examples/fully-loaded.html, examples/spell-checker.html, examples/table-operations.html, plugins/SpellChecker/readme-tech.html, ChangeLog, dialog.js, htmlarea.js, index.html, license.txt, popupwin.js, release-notes.html: + ChangeLog updated; copyright years/info updated + +2004-01-27 Mihai Bazon + + * htmlarea.js: + Included an workaround for a strange IE problem: IE's getElementById can + return a field having the _name_ attribute equal to the searched ID, even if + it's not having any ID at all. This can sometimes lead to taking a + different field (even if it's not a textarea) as the replacement field which + trashes the whole layout, look, feel, and functionality :-( Need to say it + again, IE SUCKS. + + Thanks goes to Mike Dick for the bug report and for the patch ;-) + +2004-01-18 Mihai Bazon + + * plugins/SpellChecker/spell-check-ui.js: + fixed bug (thanks Bill Sechrist for report): + when you "ignore"-ed the last mispelled word, no changes were applied + +2004-01-16 Mihai Bazon + + * htmlarea.js: border: 0px on body,html in pageStyle + + * popups/about.html: report userAgent in plugins tab + +2004-01-12 Mihai Bazon + + * lang/ru.js: updated (thanks to Yulya Shtyryakova) + +2004-01-03 Mihai Bazon + + * plugins/ContextMenu/lang/de.js: updated + +2004-01-02 Mihai Bazon + + * plugins/ContextMenu/lang/de.js: + DE translation, thanks to Martin Jaggi + +2003-12-22 Mihai Bazon + + * lang/ee.js: Estonian translation + +2003-12-05 Mihai Bazon + + * htmlarea.js: word cleaner: now it actually works ;-) + + * plugins/ContextMenu/lang/el.js, lang/el.js, plugins/TableOperations/lang/el.js: + added Greek translation (thanks to Dimitris Glezos) + + * htmlarea.js: + call an onGenerate handler, if found on the editor object + + * popups/about.html, popups/popup.js: updated about box + + * plugins/SpellChecker/spell-check-ui.js: *** empty log message *** + + * plugins/ContextMenu/context-menu.js: + open the normal insert_link dialog on modify link + +2003-11-28 Mihai Bazon + + * htmlarea.css: -moz-opacity got back + + * popups/about.html: *** empty log message *** + + * htmlarea.js: added Word cleaner code (thanks weeezl) + fixed the bug concerning the url of relative link/images + +2003-11-24 Mihai Bazon + + * plugins/CSS/css.js: + allows updation of parent element's class (no span). thanks goes to Michael (pepl @ IT forums) + +2003-11-22 Mihai Bazon + + * plugins/ContextMenu/lang/nl.js, plugins/TableOperations/lang/nl.js: + translation thanks to mmcw /IT forums + + * lang/nl.js: updated (thanks to mmcw /IT forums) + +2003-11-21 Mihai Bazon + + * makefile.xml: added ChangeLog to project dist + + * ChangeLog: Updated ChangeLog + + * examples/context-menu.html, examples/fully-loaded.html, examples/pieng.png, index.html, plugins/ContextMenu/1.pl, plugins/ContextMenu/context-menu.js, plugins/ContextMenu/lang/en.js, plugins/ContextMenu/lang/makefile.xml, plugins/ContextMenu/makefile.xml, plugins/ContextMenu/menu.css, plugins/makefile.xml: + Added ContextMenu plugin (work sponsored by American Bible Society) + +2003-11-11 Mihai Bazon + + * lang/en.js, lang/ro.js: support for the link dialog + + * plugins/FullPage/popups/docprop.html, popups/popup.js: + support for I18N of core dialogs, added function to select a value in a + +


+
Mihai Bazon
+ + +Last modified on Sat Oct 25 01:06:59 2003 + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/makefile.xml b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/makefile.xml new file mode 100644 index 0000000000..19e075f892 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/makefile.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/spell-check.gif b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/img/spell-check.gif new file mode 100644 index 0000000000000000000000000000000000000000..29bd11ae9865647f02b6b05e2088b511650d1924 GIT binary patch literal 107 zcmZ?wbhEHb6k-r!SjYeZ|NsAIU}y%Cia%KxxfqxkbU>mYc?Kq%IsGe7_cF-zD6>^9 zSolCs+ShSw@9Y!36C%T|XR+km<~34!(rzjJOUdI;!{LQW?J^RQCzdL|6mVM};?Brm F4FDL!B)9+o literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/cz.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/cz.js new file mode 100644 index 0000000000..108c037d11 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/cz.js @@ -0,0 +1,37 @@ +// I18N constants + +// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2 +// Author: Jiri Löw, + +// 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.) + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Prosím potvrďte otevření tohoto odkazu", + "Cancel" : "Zrušit", + "Dictionary" : "Slovník", + "Finished list of mispelled words" : "Dokončen seznam chybných slov", + "I will open it in a new page." : "Bude otevřen jej v nové stránce.", + "Ignore all" : "Ignorovat vše", + "Ignore" : "Ignorovat", + "NO_ERRORS" : "Podle zvoleného slovníku nebyla nalezena žádná chybná slova.", + "NO_ERRORS_CLOSING" : "Kontrola správnosti slov dokončena, nebyla nalezena žádná chybná slova. Ukončování ...", + "OK" : "OK", + "Original word" : "Původní slovo", + "Please wait. Calling spell checker." : "Prosím čekejte. Komunikuace s kontrolou správnosti slov.", + "Please wait: changing dictionary to" : "Prosím čekejte: změna adresáře na", + "QUIT_CONFIRMATION" : "Změny budou zrušeny a kontrola správnosti slov ukončena. Prosím potvrďte.", + "Re-check" : "Překontrolovat", + "Replace all" : "Zaměnit všechno", + "Replace with" : "Zaměnit za", + "Replace" : "Zaměnit", + "SC-spell-check" : "Kontrola správnosti slov", + "Suggestions" : "Doporučení", + "pliz weit ;-)" : "strpení prosím ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/da.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/da.js new file mode 100644 index 0000000000..690293ec01 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/da.js @@ -0,0 +1,37 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 | ISO-8859-1 +// Author: Steen Sønderup, + +// 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.) + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Vil du følge dette link?", + "Cancel" : "Anuler", + "Dictionary" : "Ordbog", + "Finished list of mispelled words" : "Listen med stavefejl er gennemgået", + "I will open it in a new page." : "Jeg vil åbne det i en ny side.", + "Ignore all" : "Ignorer alle", + "Ignore" : "Ignorer", + "NO_ERRORS" : "Der blev ikke fundet nogle stavefejl med den valgte ordbog.", + "NO_ERRORS_CLOSING" : "Stavekontrollen er gennemført, der blev ikke fundet nogle stavefejl. Lukker...", + "OK" : "OK", + "Original word" : "Oprindeligt ord", + "Please wait. Calling spell checker." : "Vent venligst. Henter stavekontrol.", + "Please wait: changing dictionary to" : "Vent venligst: skifter ordbog til", + "QUIT_CONFIRMATION" : "Alle dine ændringer vil gå tabt, vil du fortsætte?", + "Re-check" : "Tjek igen", + "Replace all" : "Erstat alle", + "Replace with" : "Erstat med", + "Replace" : "Erstat", + "SC-spell-check" : "Stavekontrol", + "Suggestions" : "Forslag", + "pliz weit ;-)" : "Vent venligst" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/de.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/de.js new file mode 100644 index 0000000000..1a8f4b5287 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/de.js @@ -0,0 +1,28 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 | ISO-8859-1 +// Author: Broxx, + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Wollen Sie diesen Link oeffnen", + "Cancel" : "Abbrechen", + "Dictionary" : "Woerterbuch", + "Finished list of mispelled words" : "Liste der nicht bekannten Woerter", + "I will open it in a new page." : "Wird auf neuer Seite geoeffnet", + "Ignore all" : "Alle ignorieren", + "Ignore" : "Ignorieren", + "NO_ERRORS" : "Keine falschen Woerter mit gewaehlten Woerterbuch gefunden", + "NO_ERRORS_CLOSING" : "Rechtsschreibpruefung wurde ohne Fehler fertiggestellt. Wird nun geschlossen...", + "OK" : "OK", + "Original word" : "Original Wort", + "Please wait. Calling spell checker." : "Bitte warten. Woerterbuch wird durchsucht.", + "Please wait: changing dictionary to" : "Bitte warten: Woerterbuch wechseln zu", + "QUIT_CONFIRMATION" : "Aenderungen werden nicht uebernommen. Bitte bestaettigen.", + "Re-check" : "Neuueberpruefung", + "Replace all" : "Alle ersetzen", + "Replace with" : "Ersetzen mit", + "Replace" : "Ersetzen", + "SC-spell-check" : "Ueberpruefung", + "Suggestions" : "Vorschlag", + "pliz weit ;-)" : "bittsche wartn ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/en.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/en.js new file mode 100644 index 0000000000..529cc6c450 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/en.js @@ -0,0 +1,38 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 | ISO-8859-1 +// Author: Mihai Bazon, http://dynarch.com/mishoo + +// 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.) + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Please confirm that you want to open this link", + "Cancel" : "Cancel", + "Dictionary" : "Dictionary", + "Finished list of mispelled words" : "Finished list of mispelled words", + "I will open it in a new page." : "I will open it in a new page.", + "Ignore all" : "Ignore all", + "Ignore" : "Ignore", + "NO_ERRORS" : "No mispelled words found with the selected dictionary.", + "NO_ERRORS_CLOSING" : "Spell check complete, didn't find any mispelled words. Closing now...", + "OK" : "OK", + "Original word" : "Original word", + "Please wait. Calling spell checker." : "Please wait. Calling spell checker.", + "Please wait: changing dictionary to" : "Please wait: changing dictionary to", + "QUIT_CONFIRMATION" : "This will drop changes and quit spell checker. Please confirm.", + "Re-check" : "Re-check", + "Replace all" : "Replace all", + "Replace with" : "Replace with", + "Replace" : "Replace", + "Revert" : "Revert", + "SC-spell-check" : "Spell-check", + "Suggestions" : "Suggestions", + "pliz weit ;-)" : "pliz weit ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/hu.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/hu.js new file mode 100644 index 0000000000..64102c558e --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/hu.js @@ -0,0 +1,37 @@ +// I18N constants + +// LANG: "hu", ENCODING: UTF-8 +// Author: Miklós Somogyi, + +// 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.) + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Megerősítés", + "Cancel" : "Mégsem", + "Dictionary" : "Szótár", + "Finished list of mispelled words" : "A tévesztett szavak listájának vége", + "I will open it in a new page." : "Megnyitás új lapon", + "Ignore all" : "Minden elvetése", + "Ignore" : "Elvetés", + "NO_ERRORS" : "A választott szótár szerint nincs tévesztett szó.", + "NO_ERRORS_CLOSING" : "A helyesírásellenőrzés kész, tévesztett szó nem fordult elő. Bezárás...", + "OK" : "Rendben", + "Original word" : "Eredeti szó", + "Please wait. Calling spell checker." : "Kis türelmet, a helyesírásellenőrző hívása folyamatban.", + "Please wait: changing dictionary to" : "Kis türelmet, szótár cseréje", + "QUIT_CONFIRMATION" : "Kilépés a változások eldobásával. Jóváhagyja?", + "Re-check" : "Újraellenőrzés", + "Replace all" : "Mind cseréje", + "Replace with" : "Csere a következőre:", + "Replace" : "Csere", + "SC-spell-check" : "Helyesírásellenőrzés", + "Suggestions" : "Tippek", + "pliz weit ;-)" : "Kis türelmet ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/it.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/it.js new file mode 100644 index 0000000000..0af5f7705f --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/it.js @@ -0,0 +1,28 @@ +// I18N constants + +// LANG: "it", ENCODING: UTF-8 | ISO-8859-1 +// Author: Fabio Rotondo, + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Devi confermare l'apertura di questo link", + "Cancel" : "Annulla", + "Dictionary" : "Dizionario", + "Finished list of mispelled words" : "La lista delle parole scritte male è terminata", + "I will open it in a new page." : "Lo aprirò in una nuova pagina.", + "Ignore all" : "Ignora sempre", + "Ignore" : "Ignora", + "NO_ERRORS" : "Non sono state trovate parole scritte male con il dizionario selezionato.", + "NO_ERRORS_CLOSING" : "Controllo completato, non sono state trovate parole scritte male. Sto chiudendo...", + "OK" : "OK", + "Original word" : "Parola originale", + "Please wait. Calling spell checker." : "Attendere. Sto invocando lo Spell Checker.", + "Please wait: changing dictionary to" : "Attendere. Cambio il dizionario in", + "QUIT_CONFIRMATION" : "Questo annullerà le modifiche e chiuderà lo Spell Checker. Conferma.", + "Re-check" : "Ricontrolla", + "Replace all" : "Sostituisci sempre", + "Replace with" : "Stostituisci con", + "Replace" : "Sostituisci", + "SC-spell-check" : "Spell-check", + "Suggestions" : "Suggerimenti", + "pliz weit ;-)" : "Attendere Prego ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/makefile.xml b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/makefile.xml new file mode 100644 index 0000000000..0d645c96b3 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/makefile.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/ro.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/ro.js new file mode 100644 index 0000000000..d8e96b9be2 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/lang/ro.js @@ -0,0 +1,37 @@ +// I18N constants + +// LANG: "ro", ENCODING: UTF-8 +// Author: Mihai Bazon, http://dynarch.com/mishoo + +// 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.) + +SpellChecker.I18N = { + "CONFIRM_LINK_CLICK" : "Vă rog confirmaţi că vreţi să deschideţi acest link", + "Cancel" : "Anulează", + "Dictionary" : "Dicţionar", + "Finished list of mispelled words" : "Am terminat lista de cuvinte greşite", + "I will open it in a new page." : "O voi deschide într-o altă fereastră.", + "Ignore all" : "Ignoră toate", + "Ignore" : "Ignoră", + "NO_ERRORS" : "Nu am găsit nici un cuvânt greşit cu acest dicţionar.", + "NO_ERRORS_CLOSING" : "Am terminat, nu am detectat nici o greşeală. Acum închid fereastra...", + "OK" : "OK", + "Original word" : "Cuvântul original", + "Please wait. Calling spell checker." : "Vă rog aşteptaţi. Apelez spell-checker-ul.", + "Please wait: changing dictionary to" : "Vă rog aşteptaţi. Schimb dicţionarul cu", + "QUIT_CONFIRMATION" : "Doriţi să renunţaţi la modificări şi să închid spell-checker-ul?", + "Re-check" : "Scanează", + "Replace all" : "Înlocuieşte toate", + "Replace with" : "Înlocuieşte cu", + "Replace" : "Înlocuieşte", + "SC-spell-check" : "Detectează greşeli", + "Suggestions" : "Sugestii", + "pliz weit ;-)" : "va rog ashteptatzi ;-)" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/makefile.xml b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/makefile.xml new file mode 100644 index 0000000000..cf040f5d78 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/makefile.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/readme-tech.html b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/readme-tech.html new file mode 100644 index 0000000000..1afdf6d3f8 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/readme-tech.html @@ -0,0 +1,114 @@ + + + + HTMLArea Spell Checker + + + +

HTMLArea Spell Checker

+ +

The HTMLArea Spell Checker subsystem consists of the following + files:

+ +
    + +
  • spell-checker.js — the spell checker plugin interface for + HTMLArea
  • + +
  • spell-checker-ui.html — the HTML code for the user + interface
  • + +
  • spell-checker-ui.js — functionality of the user + interface
  • + +
  • spell-checker-logic.cgi — Perl CGI script that checks a text + given through POST for spelling errors
  • + +
  • spell-checker-style.css — style for mispelled words
  • + +
  • lang/en.js — main language file (English).
  • + +
+ +

Process overview

+ +

+ When an end-user clicks the "spell-check" button in the HTMLArea + editor, a new window is opened with the URL of "spell-check-ui.html". + This window initializes itself with the text found in the editor (uses + window.opener.SpellChecker.editor global variable) and it + submits the text to the server-side script "spell-check-logic.cgi". + The target of the FORM is an inline frame which is used both to + display the text and correcting. +

+ +

+ Further, spell-check-logic.cgi calls Aspell for each portion of plain + text found in the given HTML. It rebuilds an HTML file that contains + clear marks of which words are incorrect, along with suggestions for + each of them. This file is then loaded in the inline frame. Upon + loading, a JavaScript function from "spell-check-ui.js" is called. + This function will retrieve all mispelled words from the HTML of the + iframe and will setup the user interface so that it allows correction. +

+ +

The server-side script (spell-check-logic.cgi)

+ +

+ Unicode safety — the program is + Unicode safe. HTML entities are expanded into their corresponding + Unicode characters. These characters will be matched as part of the + word passed to Aspell. All texts passed to Aspell are in Unicode + (when appropriate). However, Aspell seems to not support Unicode + yet (thread concerning Aspell and Unicode). + This mean that words containing Unicode + characters that are not in 0..255 are likely to be reported as "mispelled" by Aspell. +

+ +

+ Update: though I've never seen it mentioned + anywhere, it looks that Aspell does, in fact, speak + Unicode. Or else, maybe Text::Aspell does + transparent conversion; anyway, this new version of our + SpellChecker plugin is, as tests show so far, fully + Unicode-safe... well, probably the only freeware + Web-based spell-checker which happens to have Unicode support. +

+ +

+ The Perl Unicode manual (man perluniintro) states: +

+ +
+ + Starting from Perl 5.6.0, Perl has had the capacity to handle Unicode + natively. Perl 5.8.0, however, is the first recommended release for + serious Unicode work. The maintenance release 5.6.1 fixed many of the + problems of the initial Unicode implementation, but for example regular + expressions still do not work with Unicode in 5.6.1. + +
+ +

In other words, do not assume that this script is + Unicode-safe on Perl interpreters older than 5.8.0.

+ +

The following Perl modules are required:

+ + + +

Of these, only Text::Aspell might need to be installed manually. The + others are likely to be available by default in most Perl distributions.

+ +
+
Mihai Bazon
+ + Last modified: Fri Jan 30 19:14:11 EET 2004 + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-logic.cgi b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-logic.cgi new file mode 100644 index 0000000000..4a1256ba08 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-logic.cgi @@ -0,0 +1,210 @@ +#! /usr/bin/perl -w + +# Spell Checker Plugin for HTMLArea-3.0 +# Sponsored by www.americanbible.org +# Implementation by Mihai Bazon, http://dynarch.com/mishoo/ +# +# (c) dynarch.com 2003. +# Distributed under the same terms as HTMLArea itself. +# This notice MUST stay intact for use (see license.txt). +# +# $Id: spell-check-logic.cgi,v 1.10 2004/01/31 13:47:05 mishoo Exp $ + +use strict; +use utf8; +use Encode; +use Text::Aspell; +use XML::DOM; +use CGI; + +my $TIMER_start = undef; +eval { + use Time::HiRes qw( gettimeofday tv_interval ); + $TIMER_start = [gettimeofday()]; +}; +# use POSIX qw( locale_h ); + +binmode STDIN, ':utf8'; +binmode STDOUT, ':utf8'; + +my $debug = 0; + +my $speller = new Text::Aspell; +my $cgi = new CGI; + +my $total_words = 0; +my $total_mispelled = 0; +my $total_suggestions = 0; +my $total_words_suggested = 0; + +# FIXME: report a nice error... +die "Can't create speller!" unless $speller; + +my $dict = $cgi->param('dictionary') || $cgi->cookie('dictionary') || 'en'; + +# add configurable option for this +$speller->set_option('lang', $dict); +$speller->set_option('encoding', 'UTF-8'); +#setlocale(LC_CTYPE, $dict); + +# ultra, fast, normal, bad-spellers +# bad-spellers seems to cause segmentation fault +$speller->set_option('sug-mode', 'normal'); + +my %suggested_words = (); +keys %suggested_words = 128; + +my $file_content = decode('UTF-8', $cgi->param('content')); +$file_content = parse_with_dom($file_content); + +my $ck_dictionary = $cgi->cookie(-name => 'dictionary', + -value => $dict, + -expires => '+30d'); + +print $cgi->header(-type => 'text/html; charset: utf-8', + -cookie => $ck_dictionary); + +my $js_suggested_words = make_js_hash(\%suggested_words); +my $js_spellcheck_info = make_js_hash_from_array + ([ + [ 'Total words' , $total_words ], + [ 'Mispelled words' , $total_mispelled . ' in dictionary \"'.$dict.'\"' ], + [ 'Total suggestions' , $total_suggestions ], + [ 'Total words suggested' , $total_words_suggested ], + [ 'Spell-checked in' , defined $TIMER_start ? (tv_interval($TIMER_start) . ' seconds') : 'n/a' ] + ]); + +print qq^ + + + + + + +^; + +print $file_content; +if ($cgi->param('init') eq '1') { + my @dicts = $speller->dictionary_info(); + my $dictionaries = ''; + foreach my $i (@dicts) { + next if $i->{jargon}; + my $name = $i->{name}; + if ($name eq $dict) { + $name = '@'.$name; + } + $dictionaries .= ',' . $name; + } + $dictionaries =~ s/^,//; + print qq^
$dictionaries
^; +} + +print ''; + +# Perl is beautiful. +sub spellcheck { + my $node = shift; + my $doc = $node->getOwnerDocument; + my $check = sub { # called for each word in the text + # input is in UTF-8 + my $word = shift; + my $already_suggested = defined $suggested_words{$word}; + ++$total_words; + if (!$already_suggested && $speller->check($word)) { + return undef; + } else { + # we should have suggestions; give them back to browser in UTF-8 + ++$total_mispelled; + if (!$already_suggested) { + # compute suggestions for this word + my @suggestions = $speller->suggest($word); + my $suggestions = decode($speller->get_option('encoding'), join(',', @suggestions)); + $suggested_words{$word} = $suggestions; + ++$total_suggestions; + $total_words_suggested += scalar @suggestions; + } + # HA-spellcheck-error + my $err = $doc->createElement('span'); + $err->setAttribute('class', 'HA-spellcheck-error'); + my $tmp = $doc->createTextNode; + $tmp->setNodeValue($word); + $err->appendChild($tmp); + return $err; + } + }; + while ($node->getNodeValue =~ /([\p{IsWord}']+)/) { + my $word = $1; + my $before = $`; + my $after = $'; + my $df = &$check($word); + if (!$df) { + $before .= $word; + } + { + my $parent = $node->getParentNode; + my $n1 = $doc->createTextNode; + $n1->setNodeValue($before); + $parent->insertBefore($n1, $node); + $parent->insertBefore($df, $node) if $df; + $node->setNodeValue($after); + } + } +}; + +sub check_inner_text { + my $node = shift; + my $text = ''; + for (my $i = $node->getFirstChild; defined $i; $i = $i->getNextSibling) { + if ($i->getNodeType == TEXT_NODE) { + spellcheck($i); + } + } +}; + +sub parse_with_dom { + my ($text) = @_; + $text = ''.$text.''; + + my $parser = new XML::DOM::Parser; + if ($debug) { + open(FOO, '>:utf8', '/tmp/foo'); + print FOO $text; + close FOO; + } + my $doc = $parser->parse($text); + my $nodes = $doc->getElementsByTagName('*'); + my $n = $nodes->getLength; + + for (my $i = 0; $i < $n; ++$i) { + my $node = $nodes->item($i); + if ($node->getNodeType == ELEMENT_NODE) { + check_inner_text($node); + } + } + + my $ret = $doc->toString; + $ret =~ s{(.*)}{$1}sg; + return $ret; +}; + +sub make_js_hash { + my ($hash) = @_; + my $js_hash = ''; + while (my ($key, $val) = each %$hash) { + $js_hash .= ',' if $js_hash; + $js_hash .= '"'.$key.'":"'.$val.'"'; + } + return $js_hash; +}; + +sub make_js_hash_from_array { + my ($array) = @_; + my $js_hash = ''; + foreach my $i (@$array) { + $js_hash .= ',' if $js_hash; + $js_hash .= '"'.$i->[0].'":"'.$i->[1].'"'; + } + return $js_hash; +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-style.css b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-style.css new file mode 100644 index 0000000000..1408ba0626 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-style.css @@ -0,0 +1,10 @@ +.HA-spellcheck-error { border-bottom: 1px dashed #f00; cursor: default; } +.HA-spellcheck-same { background-color: #cef; color: #000; } +.HA-spellcheck-hover { background-color: #433; color: white; } +.HA-spellcheck-fixed { border-bottom: 1px dashed #0b8; } +.HA-spellcheck-current { background-color: #9be; color: #000; } +.HA-spellcheck-suggestions { display: none; } + +#HA-spellcheck-dictionaries { display: none; } + +a:link, a:visited { color: #55e; } diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.html b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.html new file mode 100644 index 0000000000..a008bf47d9 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.html @@ -0,0 +1,122 @@ + + + + + Spell Checker + + + + + + + + + +
+ + + + + + + + + + + + + +
+
Dictionary + + +
+ Please wait. Calling spell checker. +
+
+ +
+
Original word
+
pliz weit ;-)
+
+ +
+
Replace with
+
+
+
+
+
+
+
Suggestions
+
+ +
+
+ +
+
+ + +
+
+
+ + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.js new file mode 100644 index 0000000000..7bea11f307 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-check-ui.js @@ -0,0 +1,397 @@ +// Spell Checker Plugin for HTMLArea-3.0 +// Sponsored by www.americanbible.org +// Implementation by Mihai Bazon, http://dynarch.com/mishoo/ +// +// (c) dynarch.com 2003. +// Distributed under the same terms as HTMLArea itself. +// This notice MUST stay intact for use (see license.txt). +// +// $Id: spell-check-ui.js 30938 2004-07-29 19:08:16Z vgritsenko $ + +// internationalization file was already loaded in parent ;-) +var SpellChecker = window.opener.SpellChecker; +var i18n = SpellChecker.I18N; + +var HTMLArea = window.opener.HTMLArea; +var is_ie = HTMLArea.is_ie; +var editor = SpellChecker.editor; +var frame = null; +var currentElement = null; +var wrongWords = null; +var modified = false; +var allWords = {}; +var fixedWords = []; +var suggested_words = {}; + +function makeCleanDoc(leaveFixed) { + // document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML'; + var words = wrongWords.concat(fixedWords); + for (var i = words.length; --i >= 0;) { + var el = words[i]; + if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) { + el.parentNode.insertBefore(el.firstChild, el); + el.parentNode.removeChild(el); + } else + el.className = "HA-spellcheck-fixed"; + } + // we should use innerHTML here, but IE6's implementation fucks up the + // HTML to such extent that our poor Perl parser doesn't understand it + // anymore. + return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, editor); +}; + +function recheckClicked() { + document.getElementById("status").innerHTML = i18n["Please wait: changing dictionary to"] + ': "' + document.getElementById("f_dictionary").value + '".'; + var field = document.getElementById("f_content"); + field.value = makeCleanDoc(true); + field.form.submit(); +}; + +function saveClicked() { + if (modified) { + editor.setHTML(makeCleanDoc(false)); + } + window.close(); + return false; +}; + +function cancelClicked() { + var ok = true; + if (modified) { + ok = confirm(i18n["QUIT_CONFIRMATION"]); + } + if (ok) { + window.close(); + } + return false; +}; + +function replaceWord(el) { + var replacement = document.getElementById("v_replacement").value; + var this_word_modified = (el.innerHTML != replacement); + if (this_word_modified) + modified = true; + if (el) { + el.className = el.className.replace(/\s*HA-spellcheck-(hover|fixed)\s*/g, " "); + } + el.className += " HA-spellcheck-fixed"; + el.__msh_fixed = true; + if (!this_word_modified) { + return false; + } + el.innerHTML = replacement; +}; + +function replaceClicked() { + replaceWord(currentElement); + var start = currentElement.__msh_id; + var index = start; + do { + ++index; + if (index == wrongWords.length) { + index = 0; + } + } while ((index != start) && wrongWords[index].__msh_fixed); + if (index == start) { + index = 0; + alert(i18n["Finished list of mispelled words"]); + } + wrongWords[index].__msh_wordClicked(true); + return false; +}; + +function revertClicked() { + document.getElementById("v_replacement").value = currentElement.__msh_origWord; + replaceWord(currentElement); + currentElement.className = "HA-spellcheck-error HA-spellcheck-current"; + return false; +}; + +function replaceAllClicked() { + var replacement = document.getElementById("v_replacement").value; + var ok = true; + var spans = allWords[currentElement.__msh_origWord]; + if (spans.length == 0) { + alert("An impossible condition just happened. Call FBI. ;-)"); + } else if (spans.length == 1) { + replaceClicked(); + return false; + } + /* + var message = "The word \"" + currentElement.__msh_origWord + "\" occurs " + spans.length + " times.\n"; + if (replacement == currentElement.__msh_origWord) { + ok = confirm(message + "Ignore all occurrences?"); + } else { + ok = confirm(message + "Replace all occurrences with \"" + replacement + "\"?"); + } + */ + if (ok) { + for (var i in spans) { + if (spans[i] != currentElement) { + replaceWord(spans[i]); + } + } + // replace current element the last, so that we jump to the next word ;-) + replaceClicked(); + } + return false; +}; + +function ignoreClicked() { + document.getElementById("v_replacement").value = currentElement.__msh_origWord; + replaceClicked(); + return false; +}; + +function ignoreAllClicked() { + document.getElementById("v_replacement").value = currentElement.__msh_origWord; + replaceAllClicked(); + return false; +}; + +function learnClicked() { + alert("Not [yet] implemented"); + return false; +}; + +function internationalizeWindow() { + var types = ["div", "span", "button"]; + for (var i in types) { + var tag = types[i]; + var els = document.getElementsByTagName(tag); + for (var j = els.length; --j >= 0;) { + var el = els[j]; + if (el.childNodes.length == 1 && /\S/.test(el.innerHTML)) { + var txt = el.innerHTML; + if (typeof i18n[txt] != "undefined") { + el.innerHTML = i18n[txt]; + } + } + } + } +}; + +function initDocument() { + internationalizeWindow(); + modified = false; + frame = document.getElementById("i_framecontent"); + var field = document.getElementById("f_content"); + field.value = HTMLArea.getHTML(editor._doc.body, false, editor); + field.form.submit(); + document.getElementById("f_init").value = "0"; + + // assign some global event handlers + + var select = document.getElementById("v_suggestions"); + select.onchange = function() { + document.getElementById("v_replacement").value = this.value; + }; + if (is_ie) { + select.attachEvent("ondblclick", replaceClicked); + } else { + select.addEventListener("dblclick", replaceClicked, true); + } + + document.getElementById("b_replace").onclick = replaceClicked; + // document.getElementById("b_learn").onclick = learnClicked; + document.getElementById("b_replall").onclick = replaceAllClicked; + document.getElementById("b_ignore").onclick = ignoreClicked; + document.getElementById("b_ignall").onclick = ignoreAllClicked; + document.getElementById("b_recheck").onclick = recheckClicked; + document.getElementById("b_revert").onclick = revertClicked; + document.getElementById("b_info").onclick = displayInfo; + + document.getElementById("b_ok").onclick = saveClicked; + document.getElementById("b_cancel").onclick = cancelClicked; + + select = document.getElementById("v_dictionaries"); + select.onchange = function() { + document.getElementById("f_dictionary").value = this.value; + }; +}; + +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 wordClicked(scroll) { + var self = this; + if (scroll) (function() { + var pos = getAbsolutePos(self); + var ws = { x: frame.offsetWidth - 4, + y: frame.offsetHeight - 4 }; + var wp = { x: frame.contentWindow.document.body.scrollLeft, + y: frame.contentWindow.document.body.scrollTop }; + pos.x -= Math.round(ws.x/2); + if (pos.x < 0) pos.x = 0; + pos.y -= Math.round(ws.y/2); + if (pos.y < 0) pos.y = 0; + frame.contentWindow.scrollTo(pos.x, pos.y); + })(); + if (currentElement) { + var a = allWords[currentElement.__msh_origWord]; + currentElement.className = currentElement.className.replace(/\s*HA-spellcheck-current\s*/g, " "); + for (var i in a) { + var el = a[i]; + if (el != currentElement) { + el.className = el.className.replace(/\s*HA-spellcheck-same\s*/g, " "); + } + } + } + currentElement = this; + this.className += " HA-spellcheck-current"; + var a = allWords[currentElement.__msh_origWord]; + for (var i in a) { + var el = a[i]; + if (el != currentElement) { + el.className += " HA-spellcheck-same"; + } + } + // document.getElementById("b_replall").disabled = (a.length <= 1); + // document.getElementById("b_ignall").disabled = (a.length <= 1); + var txt; + if (a.length == 1) { + txt = "one occurrence"; + } else if (a.length == 2) { + txt = "two occurrences"; + } else { + txt = a.length + " occurrences"; + } + var suggestions = suggested_words[this.__msh_origWord]; + if (suggestions) + suggestions = suggestions.split(/,/); + else + suggestions = []; + var select = document.getElementById("v_suggestions"); + document.getElementById("statusbar").innerHTML = "Found " + txt + + ' for word "' + currentElement.__msh_origWord + '"'; + for (var i = select.length; --i >= 0;) { + select.remove(i); + } + for (var i = 0; i < suggestions.length; ++i) { + var txt = suggestions[i]; + var option = document.createElement("option"); + option.value = txt; + option.appendChild(document.createTextNode(txt)); + select.appendChild(option); + } + document.getElementById("v_currentWord").innerHTML = this.__msh_origWord; + if (suggestions.length > 0) { + select.selectedIndex = 0; + select.onchange(); + } else { + document.getElementById("v_replacement").value = this.innerHTML; + } + select.style.display = "none"; + select.style.display = "block"; + return false; +}; + +function wordMouseOver() { + this.className += " HA-spellcheck-hover"; +}; + +function wordMouseOut() { + this.className = this.className.replace(/\s*HA-spellcheck-hover\s*/g, " "); +}; + +function displayInfo() { + var info = frame.contentWindow.spellcheck_info; + if (!info) + alert("No information available"); + else { + var txt = "** Document information **"; + for (var i in info) { + txt += "\n" + i + " : " + info[i]; + } + alert(txt); + } + return false; +}; + +function finishedSpellChecking() { + // initialization of global variables + currentElement = null; + wrongWords = null; + allWords = {}; + fixedWords = []; + suggested_words = frame.contentWindow.suggested_words; + + document.getElementById("status").innerHTML = "HTMLArea Spell Checker (info)"; + var doc = frame.contentWindow.document; + var spans = doc.getElementsByTagName("span"); + var sps = []; + var id = 0; + for (var i = 0; i < spans.length; ++i) { + var el = spans[i]; + if (/HA-spellcheck-error/.test(el.className)) { + sps.push(el); + el.__msh_wordClicked = wordClicked; + el.onclick = function(ev) { + ev || (ev = window.event); + ev && HTMLArea._stopEvent(ev); + return this.__msh_wordClicked(false); + }; + el.onmouseover = wordMouseOver; + el.onmouseout = wordMouseOut; + el.__msh_id = id++; + var txt = (el.__msh_origWord = el.firstChild.data); + el.__msh_fixed = false; + if (typeof allWords[txt] == "undefined") { + allWords[txt] = [el]; + } else { + allWords[txt].push(el); + } + } else if (/HA-spellcheck-fixed/.test(el.className)) { + fixedWords.push(el); + } + } + wrongWords = sps; + if (sps.length == 0) { + if (!modified) { + alert(i18n["NO_ERRORS_CLOSING"]); + window.close(); + } else { + alert(i18n["NO_ERRORS"]); + } + return false; + } + (currentElement = sps[0]).__msh_wordClicked(true); + var as = doc.getElementsByTagName("a"); + for (var i = as.length; --i >= 0;) { + var a = as[i]; + a.onclick = function() { + if (confirm(i18n["CONFIRM_LINK_CLICK"] + ":\n" + + this.href + "\n" + i18n["I will open it in a new page."])) { + window.open(this.href); + } + return false; + }; + } + var dicts = doc.getElementById("HA-spellcheck-dictionaries"); + if (dicts) { + dicts.parentNode.removeChild(dicts); + dicts = dicts.innerHTML.split(/,/); + var select = document.getElementById("v_dictionaries"); + for (var i = select.length; --i >= 0;) { + select.remove(i); + } + for (var i = 0; i < dicts.length; ++i) { + var txt = dicts[i]; + var option = document.createElement("option"); + if (/^@(.*)$/.test(txt)) { + txt = RegExp.$1; + option.selected = true; + } + option.value = txt; + option.appendChild(document.createTextNode(txt)); + select.appendChild(option); + } + } +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-checker.js b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-checker.js new file mode 100644 index 0000000000..646969e383 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/SpellChecker/spell-checker.js @@ -0,0 +1,79 @@ +// Spell Checker Plugin for HTMLArea-3.0 +// Sponsored by www.americanbible.org +// Implementation by Mihai Bazon, http://dynarch.com/mishoo/ +// +// (c) dynarch.com 2003. +// Distributed under the same terms as HTMLArea itself. +// This notice MUST stay intact for use (see license.txt). +// +// $Id: spell-checker.js 30938 2004-07-29 19:08:16Z vgritsenko $ + +function SpellChecker(editor) { + this.editor = editor; + + var cfg = editor.config; + var tt = SpellChecker.I18N; + var bl = SpellChecker.btnList; + var self = this; + + // register the toolbar buttons provided by this plugin + var toolbar = []; + for (var i in bl) { + var btn = bl[i]; + if (!btn) { + toolbar.push("separator"); + } else { + var id = "SC-" + btn[0]; + cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "SpellChecker"), false, + function(editor, id) { + // dispatch button press event + self.buttonPress(editor, id); + }, btn[1]); + toolbar.push(id); + } + } + + for (var i in toolbar) { + cfg.toolbar[0].push(toolbar[i]); + } +}; + +SpellChecker._pluginInfo = { + name : "SpellChecker", + version : "1.0", + developer : "Mihai Bazon", + developer_url : "http://dynarch.com/mishoo/", + c_owner : "Mihai Bazon", + sponsor : "American Bible Society", + sponsor_url : "http://www.americanbible.org", + license : "htmlArea" +}; + +SpellChecker.btnList = [ + null, // separator + ["spell-check"] + ]; + +SpellChecker.prototype.buttonPress = function(editor, id) { + switch (id) { + case "SC-spell-check": + SpellChecker.editor = editor; + SpellChecker.init = true; + var uiurl = _editor_url + "plugins/SpellChecker/spell-check-ui.html"; + var win; + if (HTMLArea.is_ie) { + win = window.open(uiurl, "SC_spell_checker", + "toolbar=no,location=no,directories=no,status=no,menubar=no," + + "scrollbars=no,resizable=yes,width=600,height=450"); + } else { + win = window.open(uiurl, "SC_spell_checker", + "toolbar=no,menubar=no,personalbar=no,width=600,height=450," + + "scrollbars=no,resizable=yes"); + } + win.focus(); + break; + } +}; + +// this needs to be global, it's accessed from spell-check-ui.html +SpellChecker.editor = null; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-delete.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..df9594f44f8dbf6b910b66ae2ff5cb35495fbcd6 GIT binary patch literal 101 zcmZ?wbhEHb6k-r!SjYeZ|A7EZD*j|)WME)s&;f~ppn)TKkU`Oy~SG?aZxx}>{(YF> z`B+JrKS}gjjC*KO0^35@IT`A`iVut$c$WLdCLdCGU>Ut$e3xd9L4VrgUnvdzk8`|I IRTvno0nX7beExx}>-aR()r=UupZ`P|&?8O&f4BeeTy_fY?nvg1dtY;4is z1{uPThBAOKf`k(yf=HqWILtwZJLCvQI?B=WOrYTE!3ZIRYOH_-81R4s5y(IVkgx<3 zo=_qZnWzK`R$##kDnua*RRCyX9r^%aj8+!dTbhwZH_8~sG?uYzJKf==$RLxf9^f<| zS$E1A&UBWuNt#BfixNXjvBYL>G5S5IU<5N*!Ir~v4E3avk<4TzTO%trk{4BsViv22 zp>B_p4|x=Wvr#=*RHfQ8D>ZZP=2DchR3(gi(e&EwE@}_ku6Aa) zXg0KP8xzAaEz8=R_F)L*956BDX(fi==0i32fgPUdS>9qa@21#n#zLV?HS)L_7DHc; zv1LSNWJQBFPLJ&FF6>gdJAeM_tFzQ4V(XA2zyLFu%*@RH|Nj600RR90A^8LW000L7 zEC2ui01^Na000AEc)Hx~Cdw1SJ4Wbj>dV=tc?~Fpnh%_>bN&{gfC0MUhg`r>oc(+HWmg@z8pGoa>g~b}i&Uo{^l!w!pw*E?| J`l$yA06RU|K-&NS literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-split.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/cell-split.gif new file mode 100644 index 0000000000000000000000000000000000000000..8bd011e1941e0b7293404abf1692a0f59ef590d0 GIT binary patch literal 907 zcmW+#J!qC;47`>O?I1!yCx_IfA`V&{6hRLKwc?=Q&@rNe=p-VzdEzE@u$#EVA6#4t zIy$7{pl-Seg26#?6E~^ynWur5=lk*|x!m3Jo?1S6=~H2_+(tiAtbg1s1%ZLKL!41%Nizp$`zoXk~%Dr5R~-ql{rpV;Q@)(;ZHV3^K{; z0Z#Lgb*G%+OlLWpq-m78C^5toOKj#Aqu+xHMlgdFY&k5)P){lu$xK$VHL_wOc~QkE zX0eJG>h?JKkVi2{tDsiRY+$=drZALzO|RYVqV}-u zYG;OvWR$};VK2&ob*x{L;xjEELLABafS5 zG4%BqTSjC?Ry26y^vLe+!p`Mn^H;<(Nt3=T6HK;_KKob4!k?Kb;2-w&%l;zff!QnA zoZEGJJvQ#nZceSdTYr24(^G#p7q5SNdvE8$-q%+iTsn1s`-!F1TOYq3yFGLE$%VPK zr_0lelZ}I)*LL4|bm+!B-tYf@_ThnR)8`)kzI^`n@tb>hoO$(g`SH=GpH}xQU4HXo L<>l3FvpDh}Kw5Uq literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-delete.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..565afdc523b9d3afb789d43afa8c647e614b9f84 GIT binary patch literal 100 zcmZ?wbhEHb6k-r!SjYeZ|A7EZD*j|)WME)s&;f~pt8#2}(dY`SWJwcVvvSkEwbJ?-Hg#%>JWO$Z*7MV@XEU-p2^d;t%Ly@9 F0{~hZC+PqH literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-insert-before.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-insert-before.gif new file mode 100644 index 0000000000000000000000000000000000000000..9be8a6e4e92682c94a05aefc4953688cc43657e7 GIT binary patch literal 110 zcmZ?wbhEHb6k-r!IK%(~4;vc(|Nqax(7*tsU_kLF3nK#qJA)2L1xPIevvI|)JO4g3 zIyCN3I9KJ`=AhAaPQcc=$|!U9ru^h%$A7G4P!#x{`O>zxPyBaf*I|WRNpA)QYXGI3 BEn@%x literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-split.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/col-split.gif new file mode 100644 index 0000000000000000000000000000000000000000..83f21d14b3bfffbb1f9ec1695cc7474a9f5b7bba GIT binary patch literal 908 zcmW+#J&cZF5S%*-DsqL0DE1nchyqa%g-Im1T5~YOLC{SLZ;mBv7+vLsjef#e2?94px>G@Mfk6oI<41QpQHXm&s>VHype9jkZ z>omAQhA^a|3?Pgk;e?1Fk|+WWbI{=qIl_^Sa`ZeCD7bnsLP((+D_{WzJfJ`XGEe~| zEWv~)l!!zoDuIF(Snz@hQOH6S0NPlGK0p|wl?C>eW~9-LGKMjYW$fBccQ`3B$Rw)= zIL$}aopOdVo#kwjrcvsm#1K;~v6)+peh(@b!3J*i|QGg-;j$cl~RMHQo% z#VTT`+vDUz9>pN7f?74Rf$b)l!jz^mVXzqs`BHu{^)(+`x=XHbrK`M0c6S$c zZbV2amDEmHsQGxOLJ`VPh1woVHA(NfRHQOhsrJlD&D^`W6s0Ux3FBTgy>`2c+QYW1 zof$5g4K3Wp#IQ`uvNorE7y>y5ObmHiiQ%{TP|bZ{hi7`0w;0X4DK?w2P$*N4JZ^@? z(AQ&Z8Ic)T(cq2KBfGl`JC~D<^@t@&lfEnyOg4```&Y;8@2yk7KOE?n{YA_G+pb|_ z``$Av@#fC9jj0RoR-T^3^wi&txtrhK-rF_1|Mk^}mrp;~aq{r}TOYrkxV?4Z+4=2@ z&*!J-CU1^>T70(lXzu2pE$ + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-delete.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..e649d9f5c84ee70f5b24e7359b87c7c4d4f27da3 GIT binary patch literal 104 zcmZ?wbhEHb6k-r!SjYeZ|A7EZD*j|)WME)s&;f~p*pv#mSd y-ZH$X!ONt?@^V#DTY;4BZl(`^&sDL@Kl$NQ6En|0!_Y>n?o{Vz&RQ`B25SKFr6l_R literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-insert-above.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/row-insert-above.gif new file mode 100644 index 0000000000000000000000000000000000000000..e39c948b03c050f19b1165fae710d356ca093620 GIT binary patch literal 116 zcmZ?wbhEHb6k-r!IK;rf@c%ypL(9X4hW{W2kOu{dKUo+V7}yzffPz4kLJSPdmKD41 z{4-#4&6@gIz`%k>!J|aht#F=8-$->CMz|NopIqJG?&1io(5i?@5`Iya(B;rVe$O@nHw{h!4^hn@6q0&{wHO}X1@Be zO@kX`2tyjm0Ky0oPKXF1i6Y=I2OaK^BOK`{N6#~Xf~yB3gcPc=0v2Gv0}4bS0~J8R z5=?kPiAZFk5-3=K1uv)&g)CG7ppA9t1B5YJSzvEzMjG8HV;Iv|#;)yjhm#_MOtN}_ z(|lyzDQ7s-S5s8ur?*lv<3Olc|;2Ai>vk98WkL3*BAU-Pl0yW|R2y2^WGcXwgu zMue17N$rG%nvZuX6rl`NsO_;-lk~1jMJiL3YR|0H%)OgSQOZ)4Fz!XuYqz_oJ#4$$ znc-ZKb+{7{YA_GQ`fLF zefZ*fe7HZgGr794{$c_9CV!vJFCF=K@6hb=_sfrNep)`TFt_sa_w~=K$FAJnTz+%w v!pgzvjpvK2dFkQY(y60QPHugD%G*DF-FdtA?eXbz4=!)Kd;NWFGQrvZ{*!eQ literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/table-prop.gif b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/img/table-prop.gif new file mode 100644 index 0000000000000000000000000000000000000000..e15a4a4445482677100bdebe0c8b5d621c14f438 GIT binary patch literal 145 zcmZ?wbhEHb6k-r!Sj5J_z|e5uzySv1ng9R)KXc{`kPl=4NyVQmj0_BH3_3tIP^Az9 z19Mo$t~>8ky_gRetG4r`;<20bf&ea313?Kh<{UyJ%Ls@}L6JL%-jsWo{X3=Gx)=N>w3 literal 0 HcmV?d00001 diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/cz.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/cz.js new file mode 100644 index 0000000000..d407dae007 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/cz.js @@ -0,0 +1,90 @@ +// I18N constants + +// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2 +// Author: Jiri Löw, + +// 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.) + +TableOperations.I18N = { + "Align": "Zarovnání", + "All four sides": "VÅ¡echny čtyři strany", + "Background": "Pozadí", + "Baseline": "Základní linka", + "Border": "Obrys", + "Borders": "Obrysy", + "Bottom": "Dolů", + "CSS Style": "Kaskádové styly (CSS)", + "Caption": "Titulek", + "Cell Properties": "Vlastnosti buňky", + "Center": "Na střed", + "Char": "Znak", + "Collapsed borders": "Stlačené okraje", + "Color": "Barva", + "Description": "Popis", + "FG Color": "Barva popředí", + "Float": "Obtékání", + "Frames": "Rámečky", + "Height": "Výška", + "How many columns would you like to merge?": "Kolik sloupců si přejete spojit?", + "How many rows would you like to merge?": "Kolik řádků si přejete spojit?", + "Image URL": "Adresa obrázku", + "Justify": "Do stran", + "Layout": "Rozložení", + "Left": "Vlevo", + "Margin": "Okraj", + "Middle": "Na střed", + "No rules": "Žádné čáry", + "No sides": "Žádné strany", + "None": "Žádné", + "Padding": "Odsazování", + "Please click into some cell": "Prosím klikněte do některé buňky", + "Right": "Vpravo", + "Row Properties": "Vlastnosti řádku", + "Rules will appear between all rows and columns": "Čáry mezi vÅ¡emi řádky i sloupci", + "Rules will appear between columns only": "Čáry pouze mezi sloupci", + "Rules will appear between rows only": "Čáry pouze mezi řádky", + "Rules": "Čáry", + "Spacing and padding": "Mezery a odsazování", + "Spacing": "Mezery", + "Summary": "Shrnutí", + "TO-cell-delete": "Smazat buňku", + "TO-cell-insert-after": "Vložit buňku za", + "TO-cell-insert-before": "Vložit buňku před", + "TO-cell-merge": "Spojit buňky", + "TO-cell-prop": "Vlastnosti buňky", + "TO-cell-split": "Rozdělit buňku", + "TO-col-delete": "Smazat sloupec", + "TO-col-insert-after": "Vložit sloupec za", + "TO-col-insert-before": "Vložit sloupec před", + "TO-col-split": "Rozdělit sloupec", + "TO-row-delete": "Smazat řádek", + "TO-row-insert-above": "Smazat řádek nad", + "TO-row-insert-under": "Smazat řádek pod", + "TO-row-prop": "Vlastnosti řádku", + "TO-row-split": "Rozdělit řádek", + "TO-table-prop": "Vlastnosti tabulky", + "Table Properties": "Vlastnosti tabulky", + "Text align": "Zarovnání textu", + "The bottom side only": "Pouze spodní strana", + "The left-hand side only": "Pouze levá strana", + "The right and left sides only": "Pouze levá a pravá strana", + "The right-hand side only": "Pouze pravá strana", + "The top and bottom sides only": "Pouze horní a dolní strana", + "The top side only": "Pouze horní strana", + "Top": "Nahoru", + "Unset color": "ZruÅ¡it barvu", + "Vertical align": "Svislé zarovnání", + "Width": "Šířka", + "not-del-last-cell": "HTMLArea zbaběle odmítá smazat poslední buňku v řádku.", + "not-del-last-col": "HTMLArea zbaběle odmítá smazat poslední sloupec v tabulce.", + "not-del-last-row": "HTMLArea zbaběle odmítá smazat poslední řádek v tabulce.", + "percent": "procent", + "pixels": "pixelů" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/da.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/da.js new file mode 100644 index 0000000000..08a6f1b117 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/da.js @@ -0,0 +1,90 @@ +// I18N constants + +// LANG: "da", ENCODING: UTF-8 | ISO-8859-1 +// Author: Steen Sønderup, + +// 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.) + +TableOperations.I18N = { + "Align": "Placer", + "All four sides": "Alle fire sider", + "Background": "Baggrund", + "Baseline": "Bundlinie", + "Border": "Kant", + "Borders": "Kanter", + "Bottom": "Bund", + "CSS Style": "Stil [CSS]", + "Caption": "Titel", + "Cell Properties": "Celle egenskaber", + "Center": "Centrer", + "Char": "Plads", + "Collapsed borders": "Sammensmelt rammer", + "Color": "Farve", + "Description": "Beskrivelse", + "FG Color": "Font farve", + "Float": "Justering", + "Frames": "Udvendig", + "Height": "Højde", + "How many columns would you like to merge?": "Hvor mange kollonner vil du samle?", + "How many rows would you like to merge?": "Hvor mange rækker vil du samle?", + "Image URL": "Billede URL", + "Justify": "Lige margener", + "Layout": "Opsætning", + "Left": "Venstre", + "Margin": "Margen", + "Middle": "Centrer", + "No rules": "Ingen rammer", + "No sides": "Ingen sider", + "None": "Ingen", + "Padding": "Margen", + "Please click into some cell": "Klik pÃ¥ en celle", + "Right": "Højre", + "Row Properties": "Række egenskaber", + "Rules will appear between all rows and columns": "Rammer mellem rækker og kolonner", + "Rules will appear between columns only": "Kun rammer mellem kolonner", + "Rules will appear between rows only": "Kun rammer mellem rækker", + "Rules": "Invendig", + "Spacing and padding": "Afstand og margen", + "Spacing": "Afstand", + "Summary": "Beskrivelse", + "TO-cell-delete": "Slet celle", + "TO-cell-insert-after": "Indsæt celle efter", + "TO-cell-insert-before": "Indsæt celle før", + "TO-cell-merge": "Sammensæt celler", + "TO-cell-prop": "Celle egenskaber", + "TO-cell-split": "Opdel celle", + "TO-col-delete": "Slet kollonne", + "TO-col-insert-after": "Indsæt kolonne efter", + "TO-col-insert-before": "Indsæt kolonne før", + "TO-col-split": "Opdel kolonne", + "TO-row-delete": "Slet række", + "TO-row-insert-above": "Indsæt række før", + "TO-row-insert-under": "Indsæt række efter", + "TO-row-prop": "Række egenskaber", + "TO-row-split": "Opdel række", + "TO-table-prop": "Tabel egenskaber", + "Table Properties": "Tabel egenskaber", + "Text align": "Tekst", + "The bottom side only": "Kun i bunden", + "The left-hand side only": "Kun i højre side", + "The right and left sides only": "Kun i siderne", + "The right-hand side only": "Kun i venstre side", + "The top and bottom sides only": "Kun i top og bund", + "The top side only": "Kun i toppen", + "Top": "Top", + "Unset color": "Farve ikke valgt", + "Vertical align": "Vertikal placering", + "Width": "Bredde", + "not-del-last-cell": "Du kan ikke slette den sidste celle i en række.", + "not-del-last-col": "Du kan ikke slette den sidste kolonne i en tabel.", + "not-del-last-row": "Du kan ikke slette den sidste række i en tabel.", + "percent": "procent", + "pixels": "pixel" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/de.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/de.js new file mode 100644 index 0000000000..1128cff6fb --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/de.js @@ -0,0 +1,81 @@ +// I18N constants + +// LANG: "de", ENCODING: UTF-8 | ISO-8859-1 +// Author: broxx, + +TableOperations.I18N = { + "Align": "Ausrichten", + "All four sides": "Alle 4 Seiten", + "Background": "Hintergrund", + "Baseline": "Basislinie", + "Border": "Rand", + "Borders": "Raender", + "Bottom": "Unten", + "CSS Style": "Style [CSS]", + "Caption": "Ueberschrift", + "Cell Properties": "Zellen", + "Center": "Zentrieren", + "Char": "Zeichen", + "Collapsed borders": "Collapsed borders", + "Color": "Farbe", + "Description": "Beschreibung", + "FG Color": "FG Farbe", + "Float": "Ausrichtung", + "Frames": "Rahmen", + "Height": "Hoehe", + "How many columns would you like to merge?": "Wieviele Spalten willst du verbinden?", + "How many rows would you like to merge?": "Wieviele Zeilen willst du verbinden?", + "Image URL": "Bild URL", + "Justify": "Justieren", + "Layout": "Layout", + "Left": "Links", + "Margin": "Rand", + "Middle": "Mitte", + "No rules": "Keine Balken", + "No sides": "Keine Seiten", + "None": "Keine", + "Padding": "Auffuellung", + "Please click into some cell": "Waehle eine Zelle", + "Right": "Rechts", + "Row Properties": "Reihen", + "Rules will appear between all rows and columns": "Balken zwischen Reihen und Spalten", + "Rules will appear between columns only": "Balken zwischen Spalten", + "Rules will appear between rows only": "Balken zwischen Reihen", + "Rules": "Balken", + "Spacing and padding": "Abstaende", + "Spacing": "Abstand", + "Summary": "Zusammenfassung", + "TO-cell-delete": "Zelle loeschen", + "TO-cell-insert-after": "Zelle einfuegen nach", + "TO-cell-insert-before": "Zelle einfuegen bevor", + "TO-cell-merge": "Zellen zusammenfuegen", + "TO-cell-prop": "Zelleinstellungen", + "TO-cell-split": "Zellen aufteilen", + "TO-col-delete": "Spalte loeschen", + "TO-col-insert-after": "Spalte einfuegen nach", + "TO-col-insert-before": "Spalte einfuegen bevor", + "TO-col-split": "Spalte aufteilen", + "TO-row-delete": "Reihe loeschen", + "TO-row-insert-above": "Reihe einfuegen vor", + "TO-row-insert-under": "Reihe einfuegen nach", + "TO-row-prop": "Reiheneinstellungen", + "TO-row-split": "Reihen aufteilen", + "TO-table-prop": "Tabelle", + "Table Properties": "Tabelle", + "Text align": "Ausrichtung", + "The bottom side only": "Nur untere Seite", + "The left-hand side only": "Nur linke Seite", + "The right and left sides only": "Nur linke und rechte Seite", + "The right-hand side only": "Nur rechte Seite", + "The top and bottom sides only": "Nur obere und untere Seite", + "The top side only": "Nur obere Seite", + "Top": "Oben", + "Unset color": "Farbe", + "Vertical align": "Ausrichtung", + "Width": "Breite", + "not-del-last-cell": "Letzte Zelle in dieser Reihe!", + "not-del-last-col": "Letzte Spalte in dieser Tabelle!", + "not-del-last-row": "Letzte Reihe in dieser Tabelle", + "percent": "%", + "pixels": "pixels" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/el.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/el.js new file mode 100644 index 0000000000..06bae5cf7d --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/el.js @@ -0,0 +1,81 @@ +// I18N constants + +// LANG: "el", ENCODING: UTF-8 | ISO-8859-7 +// Author: Dimitris Glezos, dimitris@glezos.com + +TableOperations.I18N = { + "Align": "Στοίχηση", + "All four sides": "Και οι 4 πλευρές", + "Background": "Φόντο", + "Baseline": "Baseline", + "Border": "Περίγραμμα", + "Borders": "Περιγράμματα", + "Bottom": "Κάτω μέρος", + "CSS Style": "Στυλ [CSS]", + "Caption": "Λεζάντα", + "Cell Properties": "Ιδιότητες Κελιού", + "Center": "Κέντρο", + "Char": "Χαρακτήρας", + "Collapsed borders": "Συμπτυγμένα περιγράμματα", + "Color": "Χρώμα", + "Description": "Περιγραφή", + "FG Color": "Χρώμα αντικειμένων", + "Float": "Float", + "Frames": "Frames", + "Height": "Ύψος", + "How many columns would you like to merge?": "Πόσες στήλες θέλετε να ενώσετε;", + "How many rows would you like to merge?": "Πόσες γραμμές θέλετε να ενώσετε;", + "Image URL": "URL εικόνας", + "Justify": "Πλήρης στοίχηση", + "Layout": "Διάταξη", + "Left": "Αριστερά", + "Margin": "Περιθώριο", + "Middle": "Κέντρο", + "No rules": "Χωρίς Γραμμές", + "No sides": "No sides", + "None": "Τίποτα", + "Padding": "Εσοχή", + "Please click into some cell": "Κάντε κλικ μέσα σε κάποιο κελί", + "Right": "Δεξιά", + "Row Properties": "Ιδιότητες Γραμμής", + "Rules will appear between all rows and columns": "Γραμμές θα εμφανίζονται μεταξύ όλων των γραμμών και στηλών", + "Rules will appear between columns only": "Γραμμές θα εμφανίζονται μόνο μεταξύ στηλών", + "Rules will appear between rows only": "Γραμμές θα εμφανίζονται μόνο μεταξύ γραμμών", + "Rules": "Γραμμές", + "Spacing and padding": "Αποστάσεις και εσοχές", + "Spacing": "Αποστάσεις", + "Summary": "Σύνοψη", + "TO-cell-delete": "Διαγραφή κελιού", + "TO-cell-insert-after": "Εισαγωγή κελιού μετά", + "TO-cell-insert-before": "Εισαγωγή κελιού πριν", + "TO-cell-merge": "Συγχώνευση κελιών", + "TO-cell-prop": "Ιδιότητες κελιού", + "TO-cell-split": "Διαίρεση κελιού", + "TO-col-delete": "Διαγραφή στήλης", + "TO-col-insert-after": "Εισαγωγή στήλης μετά", + "TO-col-insert-before": "Εισαγωγή στήλης πριν", + "TO-col-split": "Διαίρεση στήλης", + "TO-row-delete": "Διαγραφή γραμμής", + "TO-row-insert-above": "Εισαγωγή γραμμής μετά", + "TO-row-insert-under": "Εισαγωγή γραμμής πριν", + "TO-row-prop": "Ιδιότητες γραμμής", + "TO-row-split": "Διαίρεση γραμμής", + "TO-table-prop": "Ιδιότητες πίνακα", + "Table Properties": "Ιδιότητες πίνακα", + "Text align": "Στοίχηση κειμένου", + "The bottom side only": "Η κάτω πλευρά μόνο", + "The left-hand side only": "Η αριστερή πλευρά μόνο", + "The right and left sides only": "Οι δεξιές και αριστερές πλευρές μόνο", + "The right-hand side only": "Η δεξιά πλευρά μόνο", + "The top and bottom sides only": "Οι πάνω και κάτω πλευρές μόνο", + "The top side only": "Η πάνω πλευρά μόνο", + "Top": "Πάνω", + "Unset color": "Αναίρεση χρώματος", + "Vertical align": "Κατακόρυφη στοίχηση", + "Width": "Πλάτος", + "not-del-last-cell": "Δεν μπορεί να διαγραφεί το τελευταίο κελί σε μια γραμμή.", + "not-del-last-col": "Δεν μπορεί να διαγραφεί η τελευταία στήλη σε ένα πίνακα.", + "not-del-last-row": "Δεν μπορεί να διαγραφεί η τελευταία γραμμή σε ένα πίνακα.", + "percent": "τοις εκατόν", + "pixels": "pixels" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/en.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/en.js new file mode 100644 index 0000000000..7168e09783 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/en.js @@ -0,0 +1,90 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 | ISO-8859-1 +// Author: Mihai Bazon, http://dynarch.com/mishoo + +// 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.) + +TableOperations.I18N = { + "Align": "Align", + "All four sides": "All four sides", + "Background": "Background", + "Baseline": "Baseline", + "Border": "Border", + "Borders": "Borders", + "Bottom": "Bottom", + "CSS Style": "Style [CSS]", + "Caption": "Caption", + "Cell Properties": "Cell Properties", + "Center": "Center", + "Char": "Char", + "Collapsed borders": "Collapsed borders", + "Color": "Color", + "Description": "Description", + "FG Color": "FG Color", + "Float": "Float", + "Frames": "Frames", + "Height": "Height", + "How many columns would you like to merge?": "How many columns would you like to merge?", + "How many rows would you like to merge?": "How many rows would you like to merge?", + "Image URL": "Image URL", + "Justify": "Justify", + "Layout": "Layout", + "Left": "Left", + "Margin": "Margin", + "Middle": "Middle", + "No rules": "No rules", + "No sides": "No sides", + "None": "None", + "Padding": "Padding", + "Please click into some cell": "Please click into some cell", + "Right": "Right", + "Row Properties": "Row Properties", + "Rules will appear between all rows and columns": "Rules will appear between all rows and columns", + "Rules will appear between columns only": "Rules will appear between columns only", + "Rules will appear between rows only": "Rules will appear between rows only", + "Rules": "Rules", + "Spacing and padding": "Spacing and padding", + "Spacing": "Spacing", + "Summary": "Summary", + "TO-cell-delete": "Delete cell", + "TO-cell-insert-after": "Insert cell after", + "TO-cell-insert-before": "Insert cell before", + "TO-cell-merge": "Merge cells", + "TO-cell-prop": "Cell properties", + "TO-cell-split": "Split cell", + "TO-col-delete": "Delete column", + "TO-col-insert-after": "Insert column after", + "TO-col-insert-before": "Insert column before", + "TO-col-split": "Split column", + "TO-row-delete": "Delete row", + "TO-row-insert-above": "Insert row before", + "TO-row-insert-under": "Insert row after", + "TO-row-prop": "Row properties", + "TO-row-split": "Split row", + "TO-table-prop": "Table properties", + "Table Properties": "Table Properties", + "Text align": "Text align", + "The bottom side only": "The bottom side only", + "The left-hand side only": "The left-hand side only", + "The right and left sides only": "The right and left sides only", + "The right-hand side only": "The right-hand side only", + "The top and bottom sides only": "The top and bottom sides only", + "The top side only": "The top side only", + "Top": "Top", + "Unset color": "Unset color", + "Vertical align": "Vertical align", + "Width": "Width", + "not-del-last-cell": "HTMLArea cowardly refuses to delete the last cell in row.", + "not-del-last-col": "HTMLArea cowardly refuses to delete the last column in table.", + "not-del-last-row": "HTMLArea cowardly refuses to delete the last row in table.", + "percent": "percent", + "pixels": "pixels" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/fi.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/fi.js new file mode 100644 index 0000000000..891f16885d --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/fi.js @@ -0,0 +1,66 @@ +TableOperations.I18N = { + "Align": "Kohdistus", + "All four sides": "Kaikki neljä sivua", + "Background": "Tausta", + "Baseline": "Takaraja", + "Border": "Reuna", + "Borders": "Reunat", + "Bottom": "Alle", + "CSS Style": "Tyyli [CSS]", + "Caption": "Otsikko", + "Cell Properties": "Solun asetukset", + "Center": "Keskelle", + "Char": "Merkki", + "Collapsed borders": "Luhistetut reunat", + "Color": "Väri", + "Description": "Kuvaus", + "FG Color": "FG Väri", + "Frames": "Kehykset", + "Image URL": "Kuvan osoite", + "Layout": "Sommittelu", + "Left": "Vasen", + "Margin": "Marginaali", + "Middle": "Keskelle", + "No rules": "Ei viivoja", + "No sides": "Ei sivuja", + "Padding": "Palstantäyte", + "Right": "Oikea", + "Row Properties": "Rivin asetukset", + "Rules will appear between all rows and columns": "Viivat jokaisen rivin ja sarakkeen välillä", + "Rules will appear between columns only": "Viivat ainoastaan sarakkeiden välillä", + "Rules will appear between rows only": "Viivat ainoastaan rivien välillä", + "Rules": "Viivat", + "Spacing": "Palstatila", + "Summary": "Yhteenveto", + "TO-cell-delete": "Poista solu", + "TO-cell-insert-after": "Lisää solu perään", + "TO-cell-insert-before": "Lisää solu ennen", + "TO-cell-merge": "Yhdistä solut", + "TO-cell-prop": "Solun asetukset", + "TO-cell-split": "Jaa solu", + "TO-col-delete": "Poista sarake", + "TO-col-insert-after": "Lisää sarake perään", + "TO-col-insert-before": "Lisää sarake ennen", + "TO-col-split": "Jaa sarake", + "TO-row-delete": "Poista rivi", + "TO-row-insert-above": "Lisää rivi yläpuolelle", + "TO-row-insert-under": "Lisää rivi alapuolelle", + "TO-row-prop": "Rivin asetukset", + "TO-row-split": "Jaa rivi", + "TO-table-prop": "Taulukon asetukset", + "Top": "Ylös", + "Table Properties": "Taulukon asetukset", + "The bottom side only": "Ainoastaan alapuolelle", + "The left-hand side only": "Ainoastaan vasenreuna", + "The right and left sides only": "Oikea- ja vasenreuna", + "The right-hand side only": "Ainoastaan oikeareuna", + "The top and bottom sides only": "Ylä- ja alapuoli.", + "The top side only": "Ainoastaan yläpuoli", + "Vertical align": "Vertikaali kohdistus", + "Width": "Leveys", + "not-del-last-cell": "Ei voida poistaa viimeistä solua rivistä.", + "not-del-last-col": "Ei voida poistaa viimeistä saraketta taulusta.", + "not-del-last-row": "Ei voida poistaa viimeistä riviä taulusta.", + "percent": "prosenttia", + "pixels": "pikseliä" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/hu.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/hu.js new file mode 100644 index 0000000000..828aec1523 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/hu.js @@ -0,0 +1,63 @@ +// I18N constants + +// LANG: "hu", ENCODING: UTF-8 +// Author: Miklós Somogyi, + +// 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.) + +HTMLArea.I18N = { + + // the following should be the filename without .js extension + // it will be used for automatically load plugin language. + lang: "hu", + + tooltips: { + bold: "Félkövér", + italic: "Dőlt", + underline: "Aláhúzott", + strikethrough: "Áthúzott", + subscript: "Alsó index", + superscript: "Felső index", + justifyleft: "Balra zárt", + justifycenter: "Középre zárt", + justifyright: "Jobbra zárt", + justifyfull: "Sorkizárt", + orderedlist: "Számozott lista", + unorderedlist: "Számozatlan lista", + outdent: "Behúzás csökkentése", + indent: "Behúzás növelése", + forecolor: "Karakterszín", + hilitecolor: "Háttérszín", + horizontalrule: "Elválasztó vonal", + createlink: "Hiperhivatkozás beszúrása", + insertimage: "Kép beszúrása", + inserttable: "Táblázat beszúrása", + htmlmode: "HTML forrás be/ki", + popupeditor: "Szerkesztő külön ablakban", + about: "Névjegy", + showhelp: "Súgó", + textindicator: "Aktuális stílus", + undo: "Visszavonás", + redo: "Újra végrehajtás", + cut: "Kivágás", + copy: "Másolás", + paste: "Beillesztés" + }, + + buttons: { + "ok": "Rendben", + "cancel": "Mégsem" + }, + + msg: { + "Path": "Hierarchia", + "TEXT_MODE": "Forrás mód. Visszaváltás [<>] gomb" + } +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/it.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/it.js new file mode 100644 index 0000000000..ccbdc94dbf --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/it.js @@ -0,0 +1,81 @@ +// I18N constants + +// LANG: "it", ENCODING: UTF-8 | ISO-8859-1 +// Author: Fabio Rotondo + +TableOperations.I18N = { + "Align": "Allinea", + "All four sides": "Tutti e quattro i lati", + "Background": "Sfondo", + "Baseline": "Allineamento", + "Border": "Bordo", + "Borders": "Bordi", + "Bottom": "Basso", + "CSS Style": "Stile [CSS]", + "Caption": "Titolo", + "Cell Properties": "Proprietà della Cella", + "Center": "Centra", + "Char": "Carattere", + "Collapsed borders": "Bordi chiusi", + "Color": "Colore", + "Description": "Descrizione", + "FG Color": "Colore Principale", + "Float": "Fluttuante", + "Frames": "Frames", + "Height": "Altezza", + "How many columns would you like to merge?": "Quante colonne vuoi unire?", + "How many rows would you like to merge?": "Quante righe vuoi unire?", + "Image URL": "URL dell'Immagine", + "Justify": "Justifica", + "Layout": "Layout", + "Left": "Sinistra", + "Margin": "Margine", + "Middle": "Centrale", + "No rules": "Nessun righello", + "No sides": "Nessun lato", + "None": "Nulla", + "Padding": "Padding", + "Please click into some cell": "Per favore, clicca in una cella", + "Right": "Destra", + "Row Properties": "Proprietà della Riga", + "Rules will appear between all rows and columns": "Le linee appariranno tra tutte le righe e colonne", + "Rules will appear between columns only": "Le linee appariranno solo tra le colonne", + "Rules will appear between rows only": "Le linee appariranno solo tra le righe", + "Rules": "Linee", + "Spacing and padding": "Spaziatura e Padding", + "Spacing": "Spaziatura", + "Summary": "Sommario", + "TO-cell-delete": "Cancella cella", + "TO-cell-insert-after": "Inserisci cella dopo", + "TO-cell-insert-before": "Inserisci cella prima", + "TO-cell-merge": "Unisci celle", + "TO-cell-prop": "Proprietà della cella", + "TO-cell-split": "Dividi cella", + "TO-col-delete": "Cancella colonna", + "TO-col-insert-after": "Inserisci colonna dopo", + "TO-col-insert-before": "Inserisci colonna prima", + "TO-col-split": "Dividi colonna", + "TO-row-delete": "Cancella riga", + "TO-row-insert-above": "Inserisci riga prima", + "TO-row-insert-under": "Inserisci riga dopo", + "TO-row-prop": "Proprietà della riga", + "TO-row-split": "Dividi riga", + "TO-table-prop": "Proprietà della Tabella", + "Table Properties": "Proprietà della Tabella", + "Text align": "Allineamento del Testo", + "The bottom side only": "Solo la parte inferiore", + "The left-hand side only": "Solo la parte sinistra", + "The right and left sides only": "Solo destra e sinistra", + "The right-hand side only": "Solo la parte destra", + "The top and bottom sides only": "Solo sopra e sotto", + "The top side only": "Solo la parte sopra", + "Top": "Alto", + "Unset color": "Rimuovi colore", + "Vertical align": "Allineamento verticale", + "Width": "Larghezza", + "not-del-last-cell": "HTMLArea si rifiuta codardamente di cancellare l'ultima cella nella riga.", + "not-del-last-col": "HTMLArea si rifiuta codardamente di cancellare l'ultima colonna nella tabella.", + "not-del-last-row": "HTMLArea si rifiuta codardamente di cancellare l'ultima riga nella tabella.", + "percent": "percento", + "pixels": "pixels" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/makefile.xml b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/makefile.xml new file mode 100644 index 0000000000..0d645c96b3 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/makefile.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/nl.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/nl.js new file mode 100644 index 0000000000..ce9eb305c7 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/nl.js @@ -0,0 +1,90 @@ +// I18N constants + +// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1 +// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.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.) + +TableOperations.I18N = { + "Align": "Uitlijning", + "All four sides": "Alle 4 zijden", + "Background": "Achtergrond", + "Baseline": "Basis", + "Border": "Rand", + "Borders": "Randen", + "Bottom": "Onder", + "CSS Style": "CSS Style", + "Caption": "Opmerking", + "Cell Properties": "Celeigenschappen", + "Center": "Centreren", + "Char": "Karakter", + "Collapsed borders": "Geen randen", + "Color": "Kleur", + "Description": "Omschrijving", + "FG Color": "Voorgrond", + "Float": "Zwevend", + "Frames": "Frames", + "Height": "Hoogte", + "How many columns would you like to merge?": "Hoeveel kolommen wilt u samenvoegen?", + "How many rows would you like to merge?": "Hoeveel rijen wilt u samenvoegen?", + "Image URL": "Afbeelding URL", + "Justify": "Uitvullen", + "Layout": "Opmaak", + "Left": "Links", + "Margin": "Marge", + "Middle": "Midden", + "No rules": "Geen regels", + "No sides": "Geen zijlijnen", + "None": "Geen", + "Padding": "Celmarge", + "Please click into some cell": "Klik in een cel a.u.b.", + "Right": "Rechts", + "Row Properties": "Rijeigenschappen", + "Rules will appear between all rows and columns": "Regels verschijnen tussen alle rijen en kolommen", + "Rules will appear between columns only": "Regels verschijnen enkel tussen de kolommen", + "Rules will appear between rows only": "Regels verschijnen enkel tussen de rijen", + "Rules": "Regels", + "Spacing and padding": "Celmarge en afstand tussen cellen", + "Spacing": "marge", + "Summary": "Overzicht", + "TO-cell-delete": "Cel verwijderen", + "TO-cell-insert-after": "Voeg cel toe achter", + "TO-cell-insert-before": "Voeg cel toe voor", + "TO-cell-merge": "Cellen samenvoegen", + "TO-cell-prop": "Celeigenschappen", + "TO-cell-split": "Cel splitsen", + "TO-col-delete": "Kolom verwijderen", + "TO-col-insert-after": "Kolom invoegen achter", + "TO-col-insert-before": "Kolom invoegen voor", + "TO-col-split": "Kolom splitsen", + "TO-row-delete": "Rij verwijderen", + "TO-row-insert-above": "Rij invoegen boven", + "TO-row-insert-under": "Rij invoegen onder", + "TO-row-prop": "Rij eigenschappen", + "TO-row-split": "Rij splitsen", + "TO-table-prop": "Tabel eigenschappen", + "Table Properties": "Tabel eigenschappen", + "Text align": "Text uitlijning", + "The bottom side only": "Enkel aan de onderkant", + "The left-hand side only": "Enkel aan de linkerkant", + "The right and left sides only": "Enkel aan de linker en rechterkant", + "The right-hand side only": "Enkel aan de rechterkant", + "The top and bottom sides only": "Enkel aan de bovenen onderkant", + "The top side only": "Enkel aan de bovenkant", + "Top": "Boven", + "Unset color": "Wis kleur", + "Vertical align": "Vertikale uitlijning", + "Width": "Breedte", + "not-del-last-cell": "HTMLArea kan de laatste cel in deze tabel niet verwijderen.", + "not-del-last-col": "HTMLArea kan de laatste kolom in deze tabel niet verwijderen.", + "not-del-last-row": "HTMLArea kan de laatste rij in deze tabel niet verwijderen.", + "percent": "procent", + "pixels": "pixels" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/no.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/no.js new file mode 100644 index 0000000000..a29e9034eb --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/no.js @@ -0,0 +1,91 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 | ISO-8859-1 +// Author: Mihai Bazon, +// translated into Norwegia: ses@online.no 11.11.03 + +// 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.) + +TableOperations.I18N = { + "Align": "Juster", + "All four sides": "Alle fire sider", + "Background": "Bakgrund", + "Baseline": "Grunnlinje", + "Border": "Kantlinje", + "Borders": "Kantlinjer", + "Bottom": "Bunn", + "CSS Style": "Stil [CSS]", + "Caption": "Overskrift", + "Cell Properties": "Celleegenskaper", + "Center": "Sentrer", + "Char": "Tegn", + "Collapsed borders": "Fjern kantlinjer", + "Color": "Farge", + "Description": "Beskrivelse", + "FG Color": "FG farge", + "Float": "Flytende", + "Frames": "rammer", + "Height": "Høyde", + "How many columns would you like to merge?": "Hvor mange kolonner vil du slå sammen?", + "How many rows would you like to merge?": "Hvor mange rader vil du slå sammen?", + "Image URL": "Bildets URL", + "Justify": "Juster", + "Layout": "Layout", + "Left": "Venstre", + "Margin": "Marg", + "Middle": "Midten", + "No rules": "Ingen linjal", + "No sides": "Ingen sider", + "None": "Ingen", + "Padding": "Luft", + "Please click into some cell": "Klikk i en eller annen celle", + "Right": "Høyre", + "Row Properties": "Egenskaper for rad", + "Rules will appear between all rows and columns": "Linjer vil synes mellom alle rader og kolonner", + "Rules will appear between columns only": "Linjer vil synes kun mellom kolonner", + "Rules will appear between rows only": "Linjer vil synes kun mellom rader", + "Rules": "Linjer", + "Spacing and padding": "Luft", + "Spacing": "Luft", + "Summary": "Sammendrag", + "TO-cell-delete": "Slett celle", + "TO-cell-insert-after": "Sett inn celle etter", + "TO-cell-insert-before": "Sett inn celle foran", + "TO-cell-merge": "Slå sammen celler", + "TO-cell-prop": "Egenskaper for celle", + "TO-cell-split": "Del celle", + "TO-col-delete": "Slett kolonne", + "TO-col-insert-after": "Skyt inn kolonne etter", + "TO-col-insert-before": "Skyt inn kolonne før", + "TO-col-split": "Del kolonne", + "TO-row-delete": "Slett rad", + "TO-row-insert-above": "Skyt inn rad foran", + "TO-row-insert-under": "Skyt inn rad etter", + "TO-row-prop": "Egenskaper for rad", + "TO-row-split": "Del rad", + "TO-table-prop": "Tabellegenskaper", + "Table Properties": "Tabellegenskaper", + "Text align": "Juster tekst", + "The bottom side only": "Bunnen kun", + "The left-hand side only": "Venstresiden kun", + "The right and left sides only": "Høyre- og venstresiden kun", + "The right-hand side only": "Høyresiden kun", + "The top and bottom sides only": "The top and bottom sides only", + "The top side only": "Overkanten kun", + "Top": "Overkant", + "Unset color": "Ikke-bestemt farge", + "Vertical align": "Vertikal justering", + "Width": "Bredde", + "not-del-last-cell": "HTMLArea nekter å slette siste cellen i tabellen.", + "not-del-last-col": "HTMLArea nekter å slette siste kolonnen i tabellen.", + "not-del-last-row": "HTMLArea nekter å slette siste raden i tabellen.", + "percent": "prosent", + "pixels": "billedpunkter" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/ro.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/ro.js new file mode 100644 index 0000000000..a008f21a23 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/lang/ro.js @@ -0,0 +1,90 @@ +// I18N constants + +// LANG: "ro", ENCODING: UTF-8 +// Author: Mihai Bazon, http://dynarch.com/mishoo + +// 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.) + +TableOperations.I18N = { + "Align": "Aliniere", + "All four sides": "Toate părÅ£ile", + "Background": "Fundal", + "Baseline": "Baseline", + "Border": "Chenar", + "Borders": "Chenare", + "Bottom": "Jos", + "CSS Style": "Stil [CSS]", + "Caption": "Titlu de tabel", + "Cell Properties": "Proprietăţile celulei", + "Center": "Centru", + "Char": "Caracter", + "Collapsed borders": "Chenare asimilate", + "Color": "Culoare", + "Description": "Descriere", + "FG Color": "Culoare text", + "Float": "PoziÅ£ie", + "Frames": "Chenare", + "Height": "ÎnălÅ£imea", + "How many columns would you like to merge?": "Câte coloane vrei să uneşti?", + "How many rows would you like to merge?": "Câte linii vrei să uneşti?", + "Image URL": "URL-ul imaginii", + "Justify": "Justify", + "Layout": "Aranjament", + "Left": "Stânga", + "Margin": "Margine", + "Middle": "Mijloc", + "No rules": "Fără linii", + "No sides": "Fără părÅ£i", + "None": "Nimic", + "Padding": "SpaÅ£iere", + "Please click into some cell": "Vă rog să daÅ£i click într-o celulă", + "Right": "Dreapta", + "Row Properties": "Proprietăţile liniei", + "Rules will appear between all rows and columns": "Vor apărea linii între toate rândurile şi coloanele", + "Rules will appear between columns only": "Vor apărea doar linii verticale", + "Rules will appear between rows only": "Vor apărea doar linii orizontale", + "Rules": "Linii", + "Spacing and padding": "SpaÅ£ierea", + "Spacing": "Între celule", + "Summary": "Sumar", + "TO-cell-delete": "Şterge celula", + "TO-cell-insert-after": "Inserează o celulă la dreapta", + "TO-cell-insert-before": "Inserează o celulă la stânga", + "TO-cell-merge": "Uneşte celulele", + "TO-cell-prop": "Proprietăţile celulei", + "TO-cell-split": "Împarte celula", + "TO-col-delete": "Şterge coloana", + "TO-col-insert-after": "Inserează o coloană la dreapta", + "TO-col-insert-before": "Inserează o coloană la stânga", + "TO-col-split": "Împarte coloana", + "TO-row-delete": "Şterge rândul", + "TO-row-insert-above": "Inserează un rând înainte", + "TO-row-insert-under": "Inserează un rând după", + "TO-row-prop": "Proprietăţile rândului", + "TO-row-split": "Împarte rândul", + "TO-table-prop": "Proprietăţile tabelei", + "Table Properties": "Proprietăţile tabelei", + "Text align": "Aliniere", + "The bottom side only": "Doar partea de jos", + "The left-hand side only": "Doar partea din stânga", + "The right and left sides only": "Partea din stânga şi cea din dreapta", + "The right-hand side only": "Doar partea din dreapta", + "The top and bottom sides only": "Partea de sus si cea de jos", + "The top side only": "Doar partea de sus", + "Top": "Sus", + "Unset color": "Dezactivează culoarea", + "Vertical align": "Aliniere pe verticală", + "Width": "Lăţime", + "not-del-last-cell": "HTMLArea refuză cu laşitate să şteargă ultima celulă din rând.", + "not-del-last-col": "HTMLArea refuză cu laşitate să şteargă ultima coloamă din tabela.", + "not-del-last-row": "HTMLArea refuză cu laşitate să şteargă ultimul rând din tabela.", + "percent": "procente", + "pixels": "pixeli" +}; diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/makefile.xml b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/makefile.xml new file mode 100644 index 0000000000..cf040f5d78 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/makefile.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/table-operations.js b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/table-operations.js new file mode 100644 index 0000000000..05908d6944 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/plugins/TableOperations/table-operations.js @@ -0,0 +1,1160 @@ +// Table Operations Plugin for HTMLArea-3.0 +// Implementation by Mihai Bazon. Sponsored by http://www.bloki.com +// +// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc. +// This notice MUST stay intact for use (see license.txt). +// +// A free WYSIWYG editor replacement for + + + diff --git a/tools/authcon/auth/resources/htmlarea/popups/insert_image.html b/tools/authcon/auth/resources/htmlarea/popups/insert_image.html new file mode 100644 index 0000000000..1a0e9604a0 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/insert_image.html @@ -0,0 +1,191 @@ + + + + Insert Image + + + + + + + + + + + +
Insert Image
+ +
+ + + + + + + + + + + + + +
Image URL: + +
Alternate text:
+ +

+ +

+Layout + +
+ +
Alignment:
+ + +

+ +

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

+ +

Vertical:
+ + +
+ +
+
+ + + + + +
+ Image Preview:
+ +
+
+ +
+
+ + diff --git a/tools/authcon/auth/resources/htmlarea/popups/insert_table.html b/tools/authcon/auth/resources/htmlarea/popups/insert_table.html new file mode 100644 index 0000000000..508dbf8e15 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/insert_table.html @@ -0,0 +1,174 @@ + + + + Insert Table + + + + + + + + + + + +
Insert Table
+ +
+ + + + + + + + + + + + + + + + + + + +
Rows:
Cols:Width:
+ +

+ +

+Layout + +
+ +
Alignment:
+ + +

+ +

Border thickness:
+ + +
+ +
+ +
+Spacing + +
+ +
Cell spacing:
+ + +

+ +

Cell padding:
+ + +
+ +
+ +
+ + +
+ +
+ + + diff --git a/tools/authcon/auth/resources/htmlarea/popups/link.html b/tools/authcon/auth/resources/htmlarea/popups/link.html new file mode 100644 index 0000000000..41780e4c56 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/link.html @@ -0,0 +1,142 @@ + + + + Insert/Modify Link + + + + + + + + +
Insert/Modify Link
+ + + + + + + + + + + + + + +
URL:
Title (tooltip):
Target: + +
+ +
+ + +
+ + + diff --git a/tools/authcon/auth/resources/htmlarea/popups/makefile.xml b/tools/authcon/auth/resources/htmlarea/popups/makefile.xml new file mode 100644 index 0000000000..83bc7fbee3 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/makefile.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tools/authcon/auth/resources/htmlarea/popups/old-fullscreen.html b/tools/authcon/auth/resources/htmlarea/popups/old-fullscreen.html new file mode 100644 index 0000000000..7c00d916cb --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/old-fullscreen.html @@ -0,0 +1,131 @@ + +Fullscreen Editor + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/tools/authcon/auth/resources/htmlarea/popups/old_insert_image.html b/tools/authcon/auth/resources/htmlarea/popups/old_insert_image.html new file mode 100644 index 0000000000..613f460131 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/old_insert_image.html @@ -0,0 +1,206 @@ + + + + + + + +Insert Image + + + + + +
Image URL:
+ + +
Alternate Text:
+ + +
+Layout +
+ +
+Spacing +
+ +
Alignment:
+ + +
Horizontal:
+ + +
Border Thickness:
+ + +
Vertical:
+ + + + + + + \ No newline at end of file diff --git a/tools/authcon/auth/resources/htmlarea/popups/popup.js b/tools/authcon/auth/resources/htmlarea/popups/popup.js new file mode 100644 index 0000000000..ce4517b594 --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/popups/popup.js @@ -0,0 +1,109 @@ +// 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 + + +

Where can I find out more info, download the latest version and talk to +other HTMLArea users?

+ +

You can find out more about HTMLArea and download the latest version on +the HTMLArea +homepage and you can talk to other HTMLArea users and post any comments +or suggestions you have in the HTMLArea forum.

+ +

Keyboard shortcuts

+ +

The editor provides the following key combinations:

+ +
    +
  • CTRL-A -- select all
  • +
  • CTRL-B -- bold
  • +
  • CTRL-I -- italic
  • +
  • CTRL-U -- underline
  • +
  • CTRL-S -- strikethrough
  • +
  • CTRL-L -- justify left
  • +
  • CTRL-E -- justify center
  • +
  • CTRL-R -- justify right
  • +
  • CTRL-J -- justify full
  • +
  • CTRL-1 .. CTRL-6 -- headings (<h1> .. <h6>)
  • +
  • CTRL-0 (zero) -- clean content pasted from Word
  • +
+ +

Installation

+ +

How do I add HTMLArea to my web page?

+ +

It's easy. First you need to upload HTMLArea files to your website. +Just follow these steps.

+ +
    +
  1. Download the latest version from the htmlArea + homepage.
  2. +
  3. Unzip the files onto your local computer (making sure to maintain the + directory structure contained in the zip).
  4. +
  5. Create a new folder on your website called /htmlarea/ (make sure it's + NOT inside the cgi-bin).
  6. +
  7. Transfer all the HTMLArea files from your local computer into the + /htmlarea/ folder on your website.
  8. +
  9. Open the example page /htmlarea/examples/core.html with your browser to make + sure everything works.
  10. +
+ +

Once htmlArea is on your website all you need to do is add some +JavaScript to any pages that you want to add WYSIWYG editors to. Here's how +to do that.

+ +
    + +
  1. Define some global variables. "_editor_url" has to be the absolute + URL where HTMLArea resides within your + website; as we discussed, this would be “/htmlarea/”. "_editor_lang" must + be the language code in which you want HTMLArea to appear. This defaults + to "en" (English); for a list of supported languages, please look into + the "lang" subdirectory in the distribution. +
    <script type="text/javascript">
    +   _editor_url = "/htmlarea/";
    +   _editor_lang = "en";
    +</script>
    + +
  2. Include the "htmlarea.js" script: +
    <script type="text/javascript" src="/htmlarea/htmlarea.js"></script>
    +
  3. + +
  4. If you want to change all your <textarea>-s into + HTMLArea-s then you can use the simplest way to create HTMLArea:

    +
    <script type="text/javascript" defer="1">
    +    HTMLArea.replaceAll();
    +</script>
    +

    Note: you can also add the + HTMLArea.replaceAll() code to the onload + event handler for the body element, if you find it more appropriate.

    + +

    A different approach, if you have more than one textarea and only want + to change one of them, is to use HTMLArea.replace("id") -- + pass the id of your textarea. Do not use the + name attribute anymore, it's not a standard solution!

    + +
+ +

This section applies to HTMLArea-3.0 release candidate 1 or later; prior +to this version, one needed to include more files; however, now HTMLArea is +able to include other files too (such as stylesheet, language definition +file, etc.) so you only need to define the editor path and load +"htmlarea.js". Nice, eh? ;-)

+ +

I want to change the editor settings, how do I do that?

+ +

While it's true that all you need is one line of JavaScript to create an +htmlArea WYSIWYG editor, you can also specify more config settings in the +code to control how the editor works and looks. Here's an example of some of +the available settings:

+ +
var config = new HTMLArea.Config(); // create a new configuration object
+                                    // having all the default values
+config.width = '90%';
+config.height = '200px';
+
+// the following sets a style for the page body (black text on yellow page)
+// and makes all paragraphs be bold by default
+config.pageStyle =
+  'body { background-color: yellow; color: black; font-family: verdana,sans-serif } ' +
+  'p { font-width: bold; } ';
+
+// the following replaces the textarea with the given id with a new
+// HTMLArea object having the specified configuration
+HTMLArea.replace('id', config);
+ +

Important: It's recommended that you add +custom features and configuration to a separate file. This will ensure you +that when we release a new official version of HTMLArea you'll have less +trouble upgrading it.

+ +

How do I customize the toolbar?

+ +

Using the configuration object introduced above allows you to completely +control what the toolbar contains. Following is an example of a one-line, +customized toolbar, much simpler than the default one:

+ +
var config = new HTMLArea.Config();
+config.toolbar = [
+  ['fontname', 'space',
+   'fontsize', 'space',
+   'formatblock', 'space',
+   'bold', 'italic', 'underline']
+];
+HTMLArea.replace('id', config);
+ +

The toolbar is an Array of Array objects. Each array in the toolbar +defines a new line. The default toolbar looks like this:

+ +
config.toolbar = [
+[ "fontname", "space",
+  "fontsize", "space",
+  "formatblock", "space",
+  "bold", "italic", "underline", "separator",
+  "strikethrough", "subscript", "superscript", "separator",
+  "copy", "cut", "paste", "space", "undo", "redo" ],
+		
+[ "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator",
+  "insertorderedlist", "insertunorderedlist", "outdent", "indent", "separator",
+  "forecolor", "hilitecolor", "textindicator", "separator",
+  "inserthorizontalrule", "createlink", "insertimage", "inserttable", "htmlmode", "separator",
+  "popupeditor", "separator", "showhelp", "about" ]
+];
+ +

Except three strings, all others in the examples above need to be defined +in the config.btnList object (detailed a bit later in this +document). The three exceptions are: 'space', 'separator' and 'linebreak'. +These three have the following meaning, and need not be present in +btnList:

+ +
    +
  • 'space' -- Inserts a space of 5 pixels (the width is configurable by external + CSS) at the current + position in the toolbar.
  • +
  • 'separator' -- Inserts a small vertical separator, for visually grouping related + buttons.
  • +
  • 'linebreak' -- Starts a new line in the toolbar. Subsequent controls will be + inserted on the new line.
  • +
+ +

Important: It's recommended that you add +custom features and configuration to a separate file. This will ensure you +that when we release a new official version of HTMLArea you'll have less +trouble upgrading it.

+ +

How do I create custom buttons?

+ +

By design, the toolbar is easily extensible. For adding a custom button +one needs to follow two steps.

+ +

1. Register the button in config.btnList.

+ +

For each button in the toolbar, HTMLArea needs to know the following +information:

+
    +
  • a name for it (we call it the ID of the button);
  • +
  • the path to an image to be displayed in the toolbar;
  • +
  • a tooltip for it;
  • +
  • whether the button is enabled or not in text mode;
  • +
  • what to do when the button is clicked;
  • +
+

You need to provide all this information for registering a new button +too. The button ID can be any string identifier and it's used when +defining the toolbar, as you saw above. We recommend starting +it with "my-" so that it won't clash with the standard ID-s (those from +the default toolbar).

+ +

Register button example #1

+ +
// get a default configuration
+var config = new HTMLArea.Config();
+// register the new button using Config.registerButton.
+// parameters:        button ID,   tooltip,          image,           textMode,
+config.registerButton("my-hilite", "Highlight text", "my-hilite.gif", false,
+// function that gets called when the button is clicked
+  function(editor, id) {
+    editor.surroundHTML('<span class="hilite">', '</span>');
+  }
+);
+ +

An alternate way of calling registerButton is exemplified above. Though +the code might be a little bit larger, using this form makes your code more +maintainable. It doesn't even needs comments as it's pretty clear.

+ +

Register button example #2

+ +
var config = new HTMLArea.Config();
+config.registerButton({
+  id        : "my-hilite",
+  tooltip   : "Highlight text",
+  image     : "my-hilite.gif",
+  textMode  : false,
+  action    : function(editor, id) {
+                editor.surroundHTML('<span class="hilite">', '</span>');
+              }
+});
+ +

You might notice that the "action" function receives two parameters: +editor and id. In the examples above we only used the +editor parameter. But it could be helpful for you to understand +both:

+ +
    +
  • editor is a reference to the HTMLArea object. Since our entire + code now has an OOP-like + design, you need to have a reference to + the editor object in order to do things with it. In previous versions of + HTMLArea, in order to identify the object an ID was used -- the ID of the + HTML element. In this version ID-s are no longer necessary.
  • + +
  • id is the button ID. Wondering why is this useful? Well, you + could use the same handler function (presuming that it's not an anonymous + function like in the examples above) for more buttons. You can see an example a bit later in this document.
  • +
+ +

2. Inserting it into the toolbar

+ +

At this step you need to specify where in the toolbar to insert the +button, or just create the whole toolbar again as you saw in the previous +section. You use the button ID, as shown in the examples of customizing the +toolbar in the previous section.

+ +

For the sake of completion, following there are another examples.

+ +

Append your button to the default toolbar

+ +
config.toolbar.push([ "my-hilite" ]);
+ +

Customized toolbar

+ +
config.toolbar = [
+  ['fontname', 'space',
+   'fontsize', 'space',
+   'formatblock', 'space',
+   'separator', 'my-hilite', 'separator', 'space', // here's your button
+   'bold', 'italic', 'underline', 'space']
+];
+ +

Note: in the example above our new button is +between two vertical separators. But this is by no means required. You can +put it wherever you like. Once registered in the btnList (step 1) your custom button behaves just like a default +button.

+ +

Important: It's recommended that you add +custom features and configuration to a separate file. This will ensure you +that when we release a new official version of HTMLArea you'll have less +trouble upgrading it.

+ +

A complete example

+ +

Please note that it is by no means necessary to include the following +code into the htmlarea.js file. On the contrary, it might not work there. +The configuration system is designed such that you can always customize the +editor from outside files, thus keeping the htmlarea.js file +intact. This will make it easy for you to upgrade your HTMLArea when we +release a new official version. OK, I promise it's the last time I said +this. ;)

+ +
// All our custom buttons will call this function when clicked.
+// We use the buttonId parameter to determine what button
+// triggered the call.
+function clickHandler(editor, buttonId) {
+  switch (buttonId) {
+    case "my-toc":
+      editor.insertHTML("<h1>Table Of Contents</h1>");
+      break;
+    case "my-date":
+      editor.insertHTML((new Date()).toString());
+      break;
+    case "my-bold":
+      editor.execCommand("bold");
+      editor.execCommand("italic");
+      break;
+    case "my-hilite":
+      editor.surroundHTML("<span class=\"hilite\">", "</span>");
+      break;
+  }
+};
+
+// Create a new configuration object
+var config = new HTMLArea.Config();
+
+// Register our custom buttons
+config.registerButton("my-toc",  "Insert TOC", "my-toc.gif", false, clickHandler);
+config.registerButton("my-date", "Insert date/time", "my-date.gif", false, clickHandler);
+config.registerButton("my-bold", "Toggle bold/italic", "my-bold.gif", false, clickHandler);
+config.registerButton("my-hilite", "Hilite selection", "my-hilite.gif", false, clickHandler);
+
+// Append the buttons to the default toolbar
+config.toolbar.push(["linebreak", "my-toc", "my-date", "my-bold", "my-hilite"]);
+
+// Replace an existing textarea with an HTMLArea object having the above config.
+HTMLArea.replace("textAreaID", config);
+ + +
+
© InteractiveTools.com 2002-2004. +
+© dynarch.com 2003-2004
+HTMLArea v3.0 developed by Mihai Bazon. +
+Documentation written by Mihai Bazon. +
+ Last modified: Wed Jan 28 12:18:23 EET 2004 + + diff --git a/tools/authcon/auth/resources/htmlarea/release-notes.html b/tools/authcon/auth/resources/htmlarea/release-notes.html new file mode 100644 index 0000000000..f2200d50ed --- /dev/null +++ b/tools/authcon/auth/resources/htmlarea/release-notes.html @@ -0,0 +1,165 @@ + + + + HTMLArea-3.0-rc1 release notes + + + + + +

HTMLArea-3.0-rc1 release notes

+ +

This release was compiled on Mar 1, 2004 [19:37] GMT.

+ +

3.0-rc1

+ +

Changes since 3.0-Beta:

+ +
    +
  • + New plugins +
      +
    • + ContextMenu plugin (provides a nice context menu with common + operations, including table ops, link ops, etc.) +
    • +
    • + CSS plugin (provides an easy way to insert/change CSS classes) +
    • +
    • + FullPage plugin (allows HTMLArea to edit a whole HTML file, + not only the content within <body>.) +
    • +
    +
  • +
  • + Changes in the SpellChecker plugin +
      +
    • + Many bugfixes: now it works ;-) Fully Unicode-safe. +
    • +
    • + Speed and bandwidth optimization: reports the list of + suggestions only once for each mispelled word; this helps + in cases where you have, for instance, the word “HTMLArea” + in 10 places all over the document; the list of + suggestions for it--which is kind of huge--will only be + included once. +
    • +
    • + User interface improvements: the highlighted word will + remain in view; in cases where it's normally outside, the + window will be scrolled to it. +
    • +
    • + Added a "Revert" button for those that change their minds ;-) +
    • +
    • + Added a "Info" button which reports information about the + document, retrieved by the server-side spell checker: + total number of words, total number of mispelled words, + number of suggestions made, spell check time, etc. More + can be easily added. FIXME: this part + is not yet internationalized. +
    • +
    • + The server-side spell checker now uses XML::DOM instead of + HTML::Parser, which means that it will be unable to parse + “tag-soup” HTML. It needs valid code. Usually HTMLArea + generates valid code, but on rare occasions it might fail + and the spell checker will report a gross error message. + This gonna have to be fixed, but instead of making the + spell checker accept invalid HTML I prefer to make + HTMLArea generate valid code, so changes are to be done in + other places ;-) +
    • +
    +
  • +
  • + Changes in the core editor +
      +
    • + Easier to setup: you only need to load + htmlarea.js; other scripts will be loaded + automatically. Documentation + and examples updated. +
    • +
    • + Better plugin support (they register information about + themselves with the editor; can register event handlers for + the editor, etc.) +
    • +
    • + New about box; check it out, it's cool ;-) +
    • +
    • + Word cleaner (can be enabled to automatically kill Word crap + on paste (see Config.killWordOnPaste); otherwise accessible by + pressing CTRL-0 in the editor; a toolbar button will come up + soon) +
    • +
    • + Image preview in "insert image" dialog. Also allows + modification of current image, if selected. +
    • +
    • + New "insert link" dialog, allows target and title + specification, allows editing links. +
    • +
    • + Implemented support for text direction (left-to-right or + right-to-left). +
    • +
    • + Lots of bug fixes! ... and more, I guess ;-) an + automatically generated change log + is now available. +
    • +
    +
  • +
+ +

I don't have the power to go through the bug +system at SourceForge + now. Some of the bugs reported there may be fixed; I'll update + their status, some other time. If you reported bugs there and now + find them to be fixed, please let me know.

+ +

3.0-Beta

+ +

Changes since 3.0-Alpha:

+ +
    + +
  • Performance improvements.
  • + +
  • Many bugs fixed.
  • + +
  • Plugin infrastructure.
  • + +
  • TableOperations plugin.
  • + +
  • SpellChecker plugin.
  • + +
  • Status bar.
  • + +
  • API for registering custom buttons and drop-down boxes in the + toolbar.
  • + +
  • Toolbar can contain text labels.
  • + +
  • Cut, copy, paste, undo, redo buttons.
  • + +
+
+
Mihai Bazon
+ + Last modified: Sun Feb 1 13:16:10 EET 2004 + + + + + diff --git a/tools/authcon/auth/resources/mattkruse-lib.js b/tools/authcon/auth/resources/mattkruse-lib.js new file mode 100644 index 0000000000..c7230c1c38 --- /dev/null +++ b/tools/authcon/auth/resources/mattkruse-lib.js @@ -0,0 +1,124 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* SOURCE FILE: selectbox.js */ +function selectUnselectMatchingOptions(obj,regex,which,only){if(window.RegExp){if(which == "select"){var selected1=true;var selected2=false;}else if(which == "unselect"){var selected1=false;var selected2=true;}else{return;}var re = new RegExp(regex);for(var i=0;i(b.text+"")){return 1;}return 0;});for(var i=0;i3){var regex = arguments[3];if(regex != ""){unSelectMatchingOptions(from,regex);}}for(var i=0;i=0;i--){var o = from.options[i];if(o.selected){from.options[i] = null;}}if((arguments.length<3) ||(arguments[2]==true)){sortSelect(from);sortSelect(to);}from.selectedIndex = -1;to.selectedIndex = -1;} +function copySelectedOptions(from,to){var options = new Object();for(var i=0;i=0;i--){var o=from.options[i];if(o.selected){from.options[i] = null;}}from.selectedIndex = -1;} + + +/* SOURCE FILE: OptionTransfer.js */ + +function OT_transferLeft(){moveSelectedOptions(this.right,this.left,this.autoSort);this.update();} +function OT_transferRight(){moveSelectedOptions(this.left,this.right,this.autoSort);this.update();} +function OT_transferAllLeft(){moveAllOptions(this.right,this.left,this.autoSort);this.update();} +function OT_transferAllRight(){moveAllOptions(this.left,this.right,this.autoSort);this.update();} +function OT_saveRemovedLeftOptions(f){this.removedLeftField = f;} +function OT_saveRemovedRightOptions(f){this.removedRightField = f;} +function OT_saveAddedLeftOptions(f){this.addedLeftField = f;} +function OT_saveAddedRightOptions(f){this.addedRightField = f;} +function OT_saveNewLeftOptions(f){this.newLeftField = f;} +function OT_saveNewRightOptions(f){this.newRightField = f;} +function OT_update(){var removedLeft = new Object();var removedRight = new Object();var addedLeft = new Object();var addedRight = new Object();var newLeft = new Object();var newRight = new Object();for(var i=0;i0){str=str+delimiter;}str=str+val;}return str;} +function OT_setDelimiter(val){this.delimiter=val;} +function OT_setAutoSort(val){this.autoSort=val;} +function OT_init(theform){this.form = theform;if(!theform[this.left]){alert("OptionTransfer init(): Left select list does not exist in form!");return false;}if(!theform[this.right]){alert("OptionTransfer init(): Right select list does not exist in form!");return false;}this.left=theform[this.left];this.right=theform[this.right];for(var i=0;i9?"":"0")+x} +function isDate(val,format){var date=getDateFromFormat(val,format);if(date==0){return false;}return true;} +function compareDates(date1,dateformat1,date2,dateformat2){var d1=getDateFromFormat(date1,dateformat1);var d2=getDateFromFormat(date2,dateformat2);if(d1==0 || d2==0){return -1;}else if(d1 > d2){return 1;}return 0;} +function formatDate(date,format){format=format+"";var result="";var i_format=0;var c="";var token="";var y=date.getYear()+"";var M=date.getMonth()+1;var d=date.getDate();var E=date.getDay();var H=date.getHours();var m=date.getMinutes();var s=date.getSeconds();var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;var value=new Object();if(y.length < 4){y=""+(y-0+1900);}value["y"]=""+y;value["yyyy"]=y;value["yy"]=y.substring(2,4);value["M"]=M;value["MM"]=LZ(M);value["MMM"]=MONTH_NAMES[M-1];value["NNN"]=MONTH_NAMES[M+11];value["d"]=d;value["dd"]=LZ(d);value["E"]=DAY_NAMES[E+7];value["EE"]=DAY_NAMES[E];value["H"]=H;value["HH"]=LZ(H);if(H==0){value["h"]=12;}else if(H>12){value["h"]=H-12;}else{value["h"]=H;}value["hh"]=LZ(value["h"]);if(H>11){value["K"]=H-12;}else{value["K"]=H;}value["k"]=H+1;value["KK"]=LZ(value["K"]);value["kk"]=LZ(value["k"]);if(H > 11){value["a"]="PM";}else{value["a"]="AM";}value["m"]=m;value["mm"]=LZ(m);value["s"]=s;value["ss"]=LZ(s);while(i_format < format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c) &&(i_format < format.length)){token += format.charAt(i_format++);}if(value[token] != null){result=result + value[token];}else{result=result + token;}}return result;} +function _isInteger(val){var digits="1234567890";for(var i=0;i < val.length;i++){if(digits.indexOf(val.charAt(i))==-1){return false;}}return true;} +function _getInt(str,i,minlength,maxlength){for(var x=maxlength;x>=minlength;x--){var token=str.substring(i,i+x);if(token.length < minlength){return null;}if(_isInteger(token)){return token;}}return null;} +function getDateFromFormat(val,format){val=val+"";format=format+"";var i_val=0;var i_format=0;var c="";var token="";var token2="";var x,y;var now=new Date();var year=now.getYear();var month=now.getMonth()+1;var date=1;var hh=now.getHours();var mm=now.getMinutes();var ss=now.getSeconds();var ampm="";while(i_format < format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c) &&(i_format < format.length)){token += format.charAt(i_format++);}if(token=="yyyy" || token=="yy" || token=="y"){if(token=="yyyy"){x=4;y=4;}if(token=="yy"){x=2;y=2;}if(token=="y"){x=2;y=4;}year=_getInt(val,i_val,x,y);if(year==null){return 0;}i_val += year.length;if(year.length==2){if(year > 70){year=1900+(year-0);}else{year=2000+(year-0);}}}else if(token=="MMM"||token=="NNN"){month=0;for(var i=0;i11)){month=i+1;if(month>12){month -= 12;}i_val += month_name.length;break;}}}if((month < 1)||(month>12)){return 0;}}else if(token=="EE"||token=="E"){for(var i=0;i12)){return 0;}i_val+=month.length;}else if(token=="dd"||token=="d"){date=_getInt(val,i_val,token.length,2);if(date==null||(date<1)||(date>31)){return 0;}i_val+=date.length;}else if(token=="hh"||token=="h"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>12)){return 0;}i_val+=hh.length;}else if(token=="HH"||token=="H"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>23)){return 0;}i_val+=hh.length;}else if(token=="KK"||token=="K"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>11)){return 0;}i_val+=hh.length;}else if(token=="kk"||token=="k"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>24)){return 0;}i_val+=hh.length;hh--;}else if(token=="mm"||token=="m"){mm=_getInt(val,i_val,token.length,2);if(mm==null||(mm<0)||(mm>59)){return 0;}i_val+=mm.length;}else if(token=="ss"||token=="s"){ss=_getInt(val,i_val,token.length,2);if(ss==null||(ss<0)||(ss>59)){return 0;}i_val+=ss.length;}else if(token=="a"){if(val.substring(i_val,i_val+2).toLowerCase()=="am"){ampm="AM";}else if(val.substring(i_val,i_val+2).toLowerCase()=="pm"){ampm="PM";}else{return 0;}i_val+=2;}else{if(val.substring(i_val,i_val+token.length)!=token){return 0;}else{i_val+=token.length;}}}if(i_val != val.length){return 0;}if(month==2){if( ((year%4==0)&&(year%100 != 0) ) ||(year%400==0) ){if(date > 29){return 0;}}else{if(date > 28){return 0;}}}if((month==4)||(month==6)||(month==9)||(month==11)){if(date > 30){return 0;}}if(hh<12 && ampm=="PM"){hh=hh-0+12;}else if(hh>11 && ampm=="AM"){hh-=12;}var newdate=new Date(year,month-1,date,hh,mm,ss);return newdate.getTime();} +function parseDate(val){var preferEuro=(arguments.length==2)?arguments[1]:false;generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');var d=null;for(var i=0;i screen.availHeight){this.y = screen.availHeight - this.height;}}if(screen && screen.availWidth){if((this.x + this.width) > screen.availWidth){this.x = screen.availWidth - this.width;}}var avoidAboutBlank = window.opera ||( document.layers && !navigator.mimeTypes['*']) || navigator.vendor == 'KDE' ||( document.childNodes && !document.all && !navigator.taintEnabled);this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");}this.refresh();}} +function PopupWindow_hidePopup(){if(this.divName != null){if(this.use_gebi){document.getElementById(this.divName).style.visibility = "hidden";}else if(this.use_css){document.all[this.divName].style.visibility = "hidden";}else if(this.use_layers){document.layers[this.divName].visibility = "hidden";}}else{if(this.popupWindow && !this.popupWindow.closed){this.popupWindow.close();this.popupWindow = null;}}} +function PopupWindow_isClicked(e){if(this.divName != null){if(this.use_layers){var clickX = e.pageX;var clickY = e.pageY;var t = document.layers[this.divName];if((clickX > t.left) &&(clickX < t.left+t.clip.width) &&(clickY > t.top) &&(clickY < t.top+t.clip.height)){return true;}else{return false;}}else if(document.all){var t = window.event.srcElement;while(t.parentElement != null){if(t.id==this.divName){return true;}t = t.parentElement;}return false;}else if(this.use_gebi){var t = e.originalTarget;while(t.parentNode != null){if(t.id==this.divName){return true;}t = t.parentNode;}return false;}return false;}return false;} +function PopupWindow_hideIfNotClicked(e){if(this.autoHideEnabled && !this.isClicked(e)){this.hidePopup();}} +function PopupWindow_autoHide(){this.autoHideEnabled = true;} +function PopupWindow_hidePopupWindows(e){for(var i=0;i0){this.type="DIV";this.divName = arguments[0];}else{this.type="WINDOW";}this.use_gebi = false;this.use_css = false;this.use_layers = false;if(document.getElementById){this.use_gebi = true;}else if(document.all){this.use_css = true;}else if(document.layers){this.use_layers = true;}else{this.type = "WINDOW";}this.offsetX = 0;this.offsetY = 0;this.getXYPosition = PopupWindow_getXYPosition;this.populate = PopupWindow_populate;this.setUrl = PopupWindow_setUrl;this.setWindowProperties = PopupWindow_setWindowProperties;this.refresh = PopupWindow_refresh;this.showPopup = PopupWindow_showPopup;this.hidePopup = PopupWindow_hidePopup;this.setSize = PopupWindow_setSize;this.isClicked = PopupWindow_isClicked;this.autoHide = PopupWindow_autoHide;this.hideIfNotClicked = PopupWindow_hideIfNotClicked;} + + +/* SOURCE FILE: CalendarPopup.js */ + +function CalendarPopup(){var c;if(arguments.length>0){c = new PopupWindow(arguments[0]);}else{c = new PopupWindow();c.setSize(150,175);}c.offsetX = -152;c.offsetY = 25;c.autoHide();c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");c.dayHeaders = new Array("S","M","T","W","T","F","S");c.returnFunction = "CP_tmpReturnFunction";c.returnMonthFunction = "CP_tmpReturnMonthFunction";c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";c.returnYearFunction = "CP_tmpReturnYearFunction";c.weekStartDay = 0;c.isShowYearNavigation = false;c.displayType = "date";c.disabledWeekDays = new Object();c.disabledDatesExpression = "";c.yearSelectStartOffset = 2;c.currentDate = null;c.todayText="Today";c.cssPrefix="";c.isShowYearNavigationInput=false;window.CP_targetInput = null;window.CP_dateFormat = "MM/dd/yyyy";c.setReturnFunction = CP_setReturnFunction;c.setReturnMonthFunction = CP_setReturnMonthFunction;c.setReturnQuarterFunction = CP_setReturnQuarterFunction;c.setReturnYearFunction = CP_setReturnYearFunction;c.setMonthNames = CP_setMonthNames;c.setMonthAbbreviations = CP_setMonthAbbreviations;c.setDayHeaders = CP_setDayHeaders;c.setWeekStartDay = CP_setWeekStartDay;c.setDisplayType = CP_setDisplayType;c.setDisabledWeekDays = CP_setDisabledWeekDays;c.addDisabledDates = CP_addDisabledDates;c.setYearSelectStartOffset = CP_setYearSelectStartOffset;c.setTodayText = CP_setTodayText;c.showYearNavigation = CP_showYearNavigation;c.showCalendar = CP_showCalendar;c.hideCalendar = CP_hideCalendar;c.getStyles = getCalendarStyles;c.refreshCalendar = CP_refreshCalendar;c.getCalendar = CP_getCalendar;c.select = CP_select;c.setCssPrefix = CP_setCssPrefix;c.showYearNavigationInput = CP_showYearNavigationInput +return c;} +function CP_tmpReturnFunction(y,m,d){if(window.CP_targetInput!=null){var dt = new Date(y,m-1,d,0,0,0);window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);}else{alert('Use setReturnFunction() to define which function will get the clicked results!');}} +function CP_tmpReturnMonthFunction(y,m){alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m);} +function CP_tmpReturnQuarterFunction(y,q){alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q);} +function CP_tmpReturnYearFunction(y){alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y);} +function CP_setReturnFunction(name){this.returnFunction = name;} +function CP_setReturnMonthFunction(name){this.returnMonthFunction = name;} +function CP_setReturnQuarterFunction(name){this.returnQuarterFunction = name;} +function CP_setReturnYearFunction(name){this.returnYearFunction = name;} +function CP_setMonthNames(){for(var i=0;i0)?arguments[0]:true;} +function CP_setDisplayType(type){if(type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year"){alert("Invalid display type! Must be one of: date,week-end,month,quarter,year");return false;}this.displayType=type;} +function CP_setYearSelectStartOffset(num){this.yearSelectStartOffset=num;} +function CP_setDisabledWeekDays(){this.disabledWeekDays = new Object();for(var i=0;i="+start+")";}else{this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")";}} +function CP_setTodayText(text){this.todayText = text;} +function CP_setCssPrefix(val){this.cssPrefix = val;} +function CP_showYearNavigationInput(){this.isShowYearNavigationInput =(arguments.length>0)?arguments[0]:true;} +function CP_hideCalendar(){if(arguments.length > 0){window.popupWindowObjects[arguments[0]].hidePopup();}else{this.hidePopup();}} +function CP_refreshCalendar(index){var calObject = window.popupWindowObjects[index];if(arguments.length>1){calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));}else{calObject.populate(calObject.getCalendar());}calObject.refresh();} +function CP_showCalendar(anchorname){if(arguments.length>1){if(arguments[1]==null||arguments[1]==""){this.currentDate=new Date();}else{this.currentDate=new Date(parseDate(arguments[1]));}}this.populate(this.getCalendar());this.showPopup(anchorname);} +function CP_select(inputobj, linkname, format){var selectedDate=(arguments.length>3)?arguments[3]:null;if(!window.getDateFromFormat){alert("calendar.select: To use this method you must also include 'date.js' for date formatting");return;}if(this.displayType!="date"&&this.displayType!="week-end"){alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");return;}if(inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea"){alert("calendar.select: Input object passed is not a valid form input object");window.CP_targetInput=null;return;}window.CP_targetInput = inputobj;this.currentDate=null;var time=0;if(selectedDate!=null){time = getDateFromFormat(selectedDate,format)}else if(inputobj.value!=""){time = getDateFromFormat(inputobj.value,format);}if(selectedDate!=null || inputobj.value!=""){if(time==0){this.currentDate=null;}else{this.currentDate=new Date(time);}}window.CP_dateFormat = format;this.showCalendar(linkname);} +function getCalendarStyles(){var result = "";var p = "";if(this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!=""){p=this.cssPrefix;}result += "\n";return result;} +function CP_getCalendar(){var now = new Date();if(this.type == "WINDOW"){var windowref = "window.opener.";}else{var windowref = "";}var result = "";if(this.type == "WINDOW"){result += "Calendar"+this.getStyles()+"\n";result += '
\n';}else{result += '
\n';result += '
\n';result += '
\n';}if(this.displayType=="date" || this.displayType=="week-end"){if(this.currentDate==null){this.currentDate = now;}if(arguments.length > 0){var month = arguments[0];}else{var month = this.currentDate.getMonth()+1;}if(arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]){var year = arguments[1];}else{var year = this.currentDate.getFullYear();}var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);if( ((year%4 == 0)&&(year%100 != 0) ) ||(year%400 == 0) ){daysinmonth[2] = 29;}var current_month = new Date(year,month-1,1);var display_year = year;var display_month = month;var display_date = 1;var weekday= current_month.getDay();var offset = 0;offset =(weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;if(offset > 0){display_month--;if(display_month < 1){display_month = 12;display_year--;}display_date = daysinmonth[display_month]-offset+1;}var next_month = month+1;var next_month_year = year;if(next_month > 12){next_month=1;next_month_year++;}var last_month = month-1;var last_month_year = year;if(last_month < 1){last_month=12;last_month_year--;}var date_class;if(this.type!="WINDOW"){result += "";}result += '\n';var refresh = 'javascript:'+windowref+'CP_refreshCalendar';if(this.isShowYearNavigation){result += '';result += '';result += '';result += '';result += '';if(this.isShowYearNavigationInput){result += '';}else{result += '';}result += '';}else{result += '\n';result += '\n';result += '\n';}result += '
<'+this.monthNames[month-1]+'> <'+year+'><<'+this.monthNames[month-1]+' '+year+'>>
\n';result += '\n';result += '\n';for(var j=0;j<7;j++){result += '\n';}result += '\n';for(var row=1;row<=6;row++){result += '\n';for(var col=1;col<=7;col++){var disabled=false;if(this.disabledDatesExpression!=""){var ds=""+display_year+LZ(display_month)+LZ(display_date);eval("disabled=("+this.disabledDatesExpression+")");}var dateClass = "";if((display_month == this.currentDate.getMonth()+1) &&(display_date==this.currentDate.getDate()) &&(display_year==this.currentDate.getFullYear())){dateClass = "cpCurrentDate";}else if(display_month == month){dateClass = "cpCurrentMonthDate";}else{dateClass = "cpOtherMonthDate";}if(disabled || this.disabledWeekDays[col-1]){result += ' \n';}else{var selected_date = display_date;var selected_month = display_month;var selected_year = display_year;if(this.displayType=="week-end"){var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);d.setDate(d.getDate() +(7-col));selected_year = d.getYear();if(selected_year < 1000){selected_year += 1900;}selected_month = d.getMonth()+1;selected_date = d.getDate();}result += ' \n';}display_date++;if(display_date > daysinmonth[display_month]){display_date=1;display_month++;}if(display_month > 12){display_month=1;display_year++;}}result += '';}var current_weekday = now.getDay() - this.weekStartDay;if(current_weekday < 0){current_weekday += 7;}result += '\n';result += '
'+this.dayHeaders[(this.weekStartDay+j)%7]+'
'+display_date+''+display_date+'
\n';if(this.disabledDatesExpression!=""){var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());eval("disabled=("+this.disabledDatesExpression+")");}if(disabled || this.disabledWeekDays[current_weekday+1]){result += ' '+this.todayText+'\n';}else{result += ' '+this.todayText+'\n';}result += '
\n';result += '
\n';}if(this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year"){if(arguments.length > 0){var year = arguments[0];}else{if(this.displayType=="year"){var year = now.getFullYear()-this.yearSelectStartOffset;}else{var year = now.getFullYear();}}if(this.displayType!="year" && this.isShowYearNavigation){result += "";result += '\n';result += ' \n';result += ' \n';result += ' \n';result += '
<<'+year+'>>
\n';}}if(this.displayType=="month"){result += '\n';for(var i=0;i<4;i++){result += '';for(var j=0;j<3;j++){var monthindex =((i*3)+j);result += '';}result += '';}result += '
'+this.monthAbbreviations[monthindex]+'
\n';}if(this.displayType=="quarter"){result += '
\n';for(var i=0;i<2;i++){result += '';for(var j=0;j<2;j++){var quarter =((i*2)+j+1);result += '';}result += '';}result += '

Q'+quarter+'

\n';}if(this.displayType=="year"){var yearColumnSize = 4;result += "";result += '\n';result += ' \n';result += ' \n';result += '
<<>>
\n';result += '\n';for(var i=0;i'+currentyear+'';}result += '';}result += '
\n';}if(this.type == "WINDOW"){result += "\n";}return result;} + diff --git a/tools/authcon/auth/resources/mattkruse-lib/AnchorPosition.js b/tools/authcon/auth/resources/mattkruse-lib/AnchorPosition.js new file mode 100644 index 0000000000..deb7922afe --- /dev/null +++ b/tools/authcon/auth/resources/mattkruse-lib/AnchorPosition.js @@ -0,0 +1,147 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* +AnchorPosition.js +Author: Matt Kruse +Last modified: 10/11/02 + +DESCRIPTION: These functions find the position of an tag in a document, +so other elements can be positioned relative to it. + +COMPATIBILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. + +FUNCTIONS: +getAnchorPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor. Position is relative to the PAGE. + +getAnchorWindowPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor, relative to the WHOLE SCREEN. + +NOTES: + +1) For popping up separate browser windows, use getAnchorWindowPosition. + Otherwise, use getAnchorPosition + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. +*/ + +// getAnchorPosition(anchorname) +// This function returns an object having .x and .y properties which are the coordinates +// of the named anchor, relative to the page. +function getAnchorPosition(anchorname) { + // This function will return an Object with x and y properties + var useWindow=false; + var coordinates=new Object(); + var x=0,y=0; + // Browser capability sniffing + var use_gebi=false, use_css=false, use_layers=false; + if (document.getElementById) { use_gebi=true; } + else if (document.all) { use_css=true; } + else if (document.layers) { use_layers=true; } + // Logic to find position + if (use_gebi && document.all) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_gebi) { + var o=document.getElementById(anchorname); + x=AnchorPosition_getPageOffsetLeft(o); + y=AnchorPosition_getPageOffsetTop(o); + } + else if (use_css) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_layers) { + var found=0; + for (var i=0; i +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +// HISTORY +// ------------------------------------------------------------------ +// March 24, 2004: Fixed bug - when month name and abbreviations were +// changed, date format still used original values. +// January 26, 2004: Added support for drop-down month and year +// navigation (Thanks to Chris Reid for the idea) +// September 22, 2003: Fixed a minor problem in YEAR calendar with +// CSS prefix. +// August 19, 2003: Renamed the function to get styles, and made it +// work correctly without an object reference +// August 18, 2003: Changed showYearNavigation and +// showYearNavigationInput to optionally take an argument of +// true or false +// July 31, 2003: Added text input option for year navigation. +// Added a per-calendar CSS prefix option to optionally use +// different styles for different calendars. +// July 29, 2003: Fixed bug causing the Today link to be clickable +// even though today falls in a disabled date range. +// Changed formatting to use pure CSS, allowing greater control +// over look-and-feel options. +// June 11, 2003: Fixed bug causing the Today link to be unselectable +// under certain cases when some days of week are disabled +// March 14, 2003: Added ability to disable individual dates or date +// ranges, display as light gray and strike-through +// March 14, 2003: Removed dependency on graypixel.gif and instead +/// use table border coloring +// March 12, 2003: Modified showCalendar() function to allow optional +// start-date parameter +// March 11, 2003: Modified select() function to allow optional +// start-date parameter +/* +DESCRIPTION: This object implements a popup calendar to allow the user to +select a date, month, quarter, or year. + +COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. +The calendar can be modified to work for any location in the world by +changing which weekday is displayed as the first column, changing the month +names, and changing the column headers for each day. + +USAGE: +// Create a new CalendarPopup object of type WINDOW +var cal = new CalendarPopup(); + +// Create a new CalendarPopup object of type DIV using the DIV named 'mydiv' +var cal = new CalendarPopup('mydiv'); + +// Easy method to link the popup calendar with an input box. +cal.select(inputObject, anchorname, dateFormat); +// Same method, but passing a default date other than the field's current value +cal.select(inputObject, anchorname, dateFormat, '01/02/2000'); +// This is an example call to the popup calendar from a link to populate an +// input box. Note that to use this, date.js must also be included!! +Select + +// Set the type of date select to be used. By default it is 'date'. +cal.setDisplayType(type); + +// When a date, month, quarter, or year is clicked, a function is called and +// passed the details. You must write this function, and tell the calendar +// popup what the function name is. +// Function to be called for 'date' select receives y, m, d +cal.setReturnFunction(functionname); +// Function to be called for 'month' select receives y, m +cal.setReturnMonthFunction(functionname); +// Function to be called for 'quarter' select receives y, q +cal.setReturnQuarterFunction(functionname); +// Function to be called for 'year' select receives y +cal.setReturnYearFunction(functionname); + +// Show the calendar relative to a given anchor +cal.showCalendar(anchorname); + +// Hide the calendar. The calendar is set to autoHide automatically +cal.hideCalendar(); + +// Set the month names to be used. Default are English month names +cal.setMonthNames("January","February","March",...); + +// Set the month abbreviations to be used. Default are English month abbreviations +cal.setMonthAbbreviations("Jan","Feb","Mar",...); + +// Show navigation for changing by the year, not just one month at a time +cal.showYearNavigation(); + +// Show month and year dropdowns, for quicker selection of month of dates +cal.showNavigationDropdowns(); + +// Set the text to be used above each day column. The days start with +// sunday regardless of the value of WeekStartDay +cal.setDayHeaders("S","M","T",...); + +// Set the day for the first column in the calendar grid. By default this +// is Sunday (0) but it may be changed to fit the conventions of other +// countries. +cal.setWeekStartDay(1); // week is Monday - Saturday + +// Set the weekdays which should be disabled in the 'date' select popup. You can +// then allow someone to only select week end dates, or Tuedays, for example +cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week + +// Selectively disable individual days or date ranges. Disabled days will not +// be clickable, and show as strike-through text on current browsers. +// Date format is any format recognized by parseDate() in date.js +// Pass a single date to disable: +cal.addDisabledDates("2003-01-01"); +// Pass null as the first parameter to mean "anything up to and including" the +// passed date: +cal.addDisabledDates(null, "01/02/03"); +// Pass null as the second parameter to mean "including the passed date and +// anything after it: +cal.addDisabledDates("Jan 01, 2003", null); +// Pass two dates to disable all dates inbetween and including the two +cal.addDisabledDates("January 01, 2003", "Dec 31, 2003"); + +// When the 'year' select is displayed, set the number of years back from the +// current year to start listing years. Default is 2. +// This is also used for year drop-down, to decide how many years +/- to display +cal.setYearSelectStartOffset(2); + +// Text for the word "Today" appearing on the calendar +cal.setTodayText("Today"); + +// The calendar uses CSS classes for formatting. If you want your calendar to +// have unique styles, you can set the prefix that will be added to all the +// classes in the output. +// For example, normal output may have this: +// Today +// But if you set the prefix like this: +cal.setCssPrefix("Test"); +// The output will then look like: +// Today +// And you can define that style somewhere in your page. + +// When using Year navigation, you can make the year be an input box, so +// the user can manually change it and jump to any year +cal.showYearNavigationInput(); + +// Set the calendar offset to be different than the default. By default it +// will appear just below and to the right of the anchorname. So if you have +// a text box where the date will go and and anchor immediately after the +// text box, the calendar will display immediately under the text box. +cal.offsetX = 20; +cal.offsetY = 20; + +NOTES: +1) Requires the functions in AnchorPosition.js and PopupWindow.js + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. + +4) When a CalendarPopup object is created, a handler for 'onmouseup' is + attached to any event handler you may have already defined. Do NOT define + an event handler for 'onmouseup' after you define a CalendarPopup object + or the autoHide() will not work correctly. + +5) The calendar popup display uses style sheets to make it look nice. + +*/ + +// CONSTRUCTOR for the CalendarPopup Object +function CalendarPopup() { + var c; + if (arguments.length>0) { + c = new PopupWindow(arguments[0]); + } + else { + c = new PopupWindow(); + c.setSize(150,175); + } + c.offsetX = -152; + c.offsetY = 25; + c.autoHide(); + // Calendar-specific properties + c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December"); + c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); + c.dayHeaders = new Array("S","M","T","W","T","F","S"); + c.returnFunction = "CP_tmpReturnFunction"; + c.returnMonthFunction = "CP_tmpReturnMonthFunction"; + c.returnQuarterFunction = "CP_tmpReturnQuarterFunction"; + c.returnYearFunction = "CP_tmpReturnYearFunction"; + c.weekStartDay = 0; + c.isShowYearNavigation = false; + c.displayType = "date"; + c.disabledWeekDays = new Object(); + c.disabledDatesExpression = ""; + c.yearSelectStartOffset = 2; + c.currentDate = null; + c.todayText="Today"; + c.cssPrefix=""; + c.isShowNavigationDropdowns=false; + c.isShowYearNavigationInput=false; + window.CP_calendarObject = null; + window.CP_targetInput = null; + window.CP_dateFormat = "MM/dd/yyyy"; + // Method mappings + c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow; + c.setReturnFunction = CP_setReturnFunction; + c.setReturnMonthFunction = CP_setReturnMonthFunction; + c.setReturnQuarterFunction = CP_setReturnQuarterFunction; + c.setReturnYearFunction = CP_setReturnYearFunction; + c.setMonthNames = CP_setMonthNames; + c.setMonthAbbreviations = CP_setMonthAbbreviations; + c.setDayHeaders = CP_setDayHeaders; + c.setWeekStartDay = CP_setWeekStartDay; + c.setDisplayType = CP_setDisplayType; + c.setDisabledWeekDays = CP_setDisabledWeekDays; + c.addDisabledDates = CP_addDisabledDates; + c.setYearSelectStartOffset = CP_setYearSelectStartOffset; + c.setTodayText = CP_setTodayText; + c.showYearNavigation = CP_showYearNavigation; + c.showCalendar = CP_showCalendar; + c.hideCalendar = CP_hideCalendar; + c.getStyles = getCalendarStyles; + c.refreshCalendar = CP_refreshCalendar; + c.getCalendar = CP_getCalendar; + c.select = CP_select; + c.setCssPrefix = CP_setCssPrefix; + c.showNavigationDropdowns = CP_showNavigationDropdowns; + c.showYearNavigationInput = CP_showYearNavigationInput; + c.copyMonthNamesToWindow(); + // Return the object + return c; + } +function CP_copyMonthNamesToWindow() { + // Copy these values over to the date.js + if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) { + window.MONTH_NAMES = new Array(); + for (var i=0; i\n"; + result += '
\n'; + } + else { + result += '
\n'; + result += '
\n'; + result += '
\n'; + } + // Code for DATE display (default) + // ------------------------------- + if (this.displayType=="date" || this.displayType=="week-end") { + if (this.currentDate==null) { this.currentDate = now; } + if (arguments.length > 0) { var month = arguments[0]; } + else { var month = this.currentDate.getMonth()+1; } + if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; } + else { var year = this.currentDate.getFullYear(); } + var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31); + if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) { + daysinmonth[2] = 29; + } + var current_month = new Date(year,month-1,1); + var display_year = year; + var display_month = month; + var display_date = 1; + var weekday= current_month.getDay(); + var offset = 0; + + offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ; + if (offset > 0) { + display_month--; + if (display_month < 1) { display_month = 12; display_year--; } + display_date = daysinmonth[display_month]-offset+1; + } + var next_month = month+1; + var next_month_year = year; + if (next_month > 12) { next_month=1; next_month_year++; } + var last_month = month-1; + var last_month_year = year; + if (last_month < 1) { last_month=12; last_month_year--; } + var date_class; + if (this.type!="WINDOW") { + result += ""; + } + result += '\n'; + var refresh = windowref+'CP_refreshCalendar'; + var refreshLink = 'javascript:' + refresh; + if (this.isShowNavigationDropdowns) { + result += ''; + result += ''; + + result += ''; + } + else { + if (this.isShowYearNavigation) { + result += ''; + result += ''; + result += ''; + result += ''; + + result += ''; + if (this.isShowYearNavigationInput) { + result += ''; + } + else { + result += ''; + } + result += ''; + } + else { + result += '\n'; + result += '\n'; + result += '\n'; + } + } + result += '
 <'+this.monthNames[month-1]+'> <'+year+'><<'+this.monthNames[month-1]+' '+year+'>>
\n'; + result += '\n'; + result += '\n'; + for (var j=0; j<7; j++) { + + result += '\n'; + } + result += '\n'; + for (var row=1; row<=6; row++) { + result += '\n'; + for (var col=1; col<=7; col++) { + var disabled=false; + if (this.disabledDatesExpression!="") { + var ds=""+display_year+LZ(display_month)+LZ(display_date); + eval("disabled=("+this.disabledDatesExpression+")"); + } + var dateClass = ""; + if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) { + dateClass = "cpCurrentDate"; + } + else if (display_month == month) { + dateClass = "cpCurrentMonthDate"; + } + else { + dateClass = "cpOtherMonthDate"; + } + if (disabled || this.disabledWeekDays[col-1]) { + result += ' \n'; + } + else { + var selected_date = display_date; + var selected_month = display_month; + var selected_year = display_year; + if (this.displayType=="week-end") { + var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0); + d.setDate(d.getDate() + (7-col)); + selected_year = d.getYear(); + if (selected_year < 1000) { selected_year += 1900; } + selected_month = d.getMonth()+1; + selected_date = d.getDate(); + } + result += ' \n'; + } + display_date++; + if (display_date > daysinmonth[display_month]) { + display_date=1; + display_month++; + } + if (display_month > 12) { + display_month=1; + display_year++; + } + } + result += ''; + } + var current_weekday = now.getDay() - this.weekStartDay; + if (current_weekday < 0) { + current_weekday += 7; + } + result += '\n'; + result += '
'+this.dayHeaders[(this.weekStartDay+j)%7]+'
'+display_date+''+display_date+'
\n'; + if (this.disabledDatesExpression!="") { + var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate()); + eval("disabled=("+this.disabledDatesExpression+")"); + } + if (disabled || this.disabledWeekDays[current_weekday+1]) { + result += ' '+this.todayText+'\n'; + } + else { + result += ' '+this.todayText+'\n'; + } + result += '
\n'; + result += '
\n'; + } + + // Code common for MONTH, QUARTER, YEAR + // ------------------------------------ + if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") { + if (arguments.length > 0) { var year = arguments[0]; } + else { + if (this.displayType=="year") { var year = now.getFullYear()-this.yearSelectStartOffset; } + else { var year = now.getFullYear(); } + } + if (this.displayType!="year" && this.isShowYearNavigation) { + result += ""; + result += '\n'; + result += ' \n'; + result += ' \n'; + result += ' \n'; + result += '
<<'+year+'>>
\n'; + } + } + + // Code for MONTH display + // ---------------------- + if (this.displayType=="month") { + // If POPUP, write entire HTML document + result += '\n'; + for (var i=0; i<4; i++) { + result += ''; + for (var j=0; j<3; j++) { + var monthindex = ((i*3)+j); + result += ''; + } + result += ''; + } + result += '
'+this.monthAbbreviations[monthindex]+'
\n'; + } + + // Code for QUARTER display + // ------------------------ + if (this.displayType=="quarter") { + result += '
\n'; + for (var i=0; i<2; i++) { + result += ''; + for (var j=0; j<2; j++) { + var quarter = ((i*2)+j+1); + result += ''; + } + result += ''; + } + result += '

Q'+quarter+'

\n'; + } + + // Code for YEAR display + // --------------------- + if (this.displayType=="year") { + var yearColumnSize = 4; + result += ""; + result += '\n'; + result += ' \n'; + result += ' \n'; + result += '
<<>>
\n'; + result += '\n'; + for (var i=0; i'+currentyear+''; + } + result += ''; + } + result += '
\n'; + } + // Common + if (this.type == "WINDOW") { + result += "\n"; + } + return result; + } diff --git a/tools/authcon/auth/resources/mattkruse-lib/OptionTransfer.js b/tools/authcon/auth/resources/mattkruse-lib/OptionTransfer.js new file mode 100644 index 0000000000..4e19afa86d --- /dev/null +++ b/tools/authcon/auth/resources/mattkruse-lib/OptionTransfer.js @@ -0,0 +1,187 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* +OptionTransfer.js +Last Modified: 11/18/2002 + +DESCRIPTION: This widget is used to easily and quickly create an interface +where the user can transfer choices from one select box to another. For +example, when selecting which columns to show or hide in search results. +This object adds value by automatically storing the values that were added +or removed from each list, as well as the state of the final list. + +COMPATIBILITY: Should work on all Javascript-compliant browsers. + +USAGE: +// Create a new OptionTransfer object. Pass it the field names of the left +// select box and the right select box. +var ot = new OptionTransfer("from","to"); + +// Optionally tell the lists whether or not to auto-sort when options are +// moved. By default, the lists will be sorted. +ot.setAutoSort(true); + +// Optionally set the delimiter to be used to separate values that are +// stored in hidden fields for the added and removed options, as well as +// final state of the lists. Defaults to a comma. +ot.setDelimiter("|"); + +// These functions assign the form fields which will store the state of +// the lists. Each one is optional, so you can pick to only store the +// new options which were transferred to the right list, for example. +// Each function takes the name of a HIDDEN or TEXT input field. + +// Store list of options removed from left list into an input field +ot.saveRemovedLeftOptions("removedLeft"); +// Store list of options removed from right list into an input field +ot.saveRemovedRightOptions("removedRight"); +// Store list of options added to left list into an input field +ot.saveAddedLeftOptions("addedLeft"); +// Store list of options radded to right list into an input field +ot.saveAddedRightOptions("addedRight"); +// Store all options existing in the left list into an input field +ot.saveNewLeftOptions("newLeft"); +// Store all options existing in the right list into an input field +ot.saveNewRightOptions("newRight"); + +// IMPORTANT: This step is required for the OptionTransfer object to work +// correctly. +// Add a call to the BODY onLoad="" tag of the page, and pass a reference to +// the form which contains the select boxes and input fields. +BODY onLoad="ot.init(document.forms[0])" + +// ADDING ACTIONS INTO YOUR PAGE +// Finally, add calls to the object to move options back and forth, either +// from links in your page or from double-clicking the options themselves. +// See example page, and use the following methods: +ot.transferRight(); +ot.transferAllRight(); +ot.transferLeft(); +ot.transferAllLeft(); + + +NOTES: +1) Requires the functions in selectbox.js + +*/ +function OT_transferLeft() { moveSelectedOptions(this.right,this.left,this.autoSort); this.update(); } +function OT_transferRight() { moveSelectedOptions(this.left,this.right,this.autoSort); this.update(); } +function OT_transferAllLeft() { moveAllOptions(this.right,this.left,this.autoSort); this.update(); } +function OT_transferAllRight() { moveAllOptions(this.left,this.right,this.autoSort); this.update(); } +function OT_saveRemovedLeftOptions(f) { this.removedLeftField = f; } +function OT_saveRemovedRightOptions(f) { this.removedRightField = f; } +function OT_saveAddedLeftOptions(f) { this.addedLeftField = f; } +function OT_saveAddedRightOptions(f) { this.addedRightField = f; } +function OT_saveNewLeftOptions(f) { this.newLeftField = f; } +function OT_saveNewRightOptions(f) { this.newRightField = f; } +function OT_update() { + var removedLeft = new Object(); + var removedRight = new Object(); + var addedLeft = new Object(); + var addedRight = new Object(); + var newLeft = new Object(); + var newRight = new Object(); + for (var i=0;i0) { str=str+delimiter; } + str=str+val; + } + return str; + } +function OT_setDelimiter(val) { this.delimiter=val; } +function OT_setAutoSort(val) { this.autoSort=val; } +function OT_init(theform) { + this.form = theform; + if(!theform[this.left]){alert("OptionTransfer init(): Left select list does not exist in form!");return false;} + if(!theform[this.right]){alert("OptionTransfer init(): Right select list does not exist in form!");return false;} + this.left=theform[this.left]; + this.right=theform[this.right]; + for(var i=0;i +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* +PopupWindow.js +Author: Matt Kruse +Last modified: 02/16/04 + +DESCRIPTION: This object allows you to easily and quickly popup a window +in a certain place. The window can either be a DIV or a separate browser +window. + +COMPATIBILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. Due to bugs in Netscape 4.x, populating the popup +window with + + + + + + +
+ <? + + + + + + ?> +
+
+ + + +
+ + + +
+
+ + + +
+ - + <!-- + +
+               
+            
+
+ --> +
+
+ + + + + + + =" + + + + " + + + + + + + +
+ < + + + + + + + + + /> +
+
+ + + +
+ < + + + + + + + + + + > + + + + + </ + + + + + > + +
+
+ + +
+
+ - + < + + + + + + + + + + > + +
+
+ +
+ </ + + + + + > + +
+
+
+
+ + + + + + + + + + + + + + + + + xmlns + + : + + + + =" + + + + " + + + + + + diff --git a/tools/authcon/seth/build.xml b/tools/authcon/seth/build.xml new file mode 100644 index 0000000000..bf921c4f2d --- /dev/null +++ b/tools/authcon/seth/build.xml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/authcon/seth/src/EasySSLProtocolSocketFactory.java b/tools/authcon/seth/src/EasySSLProtocolSocketFactory.java new file mode 100644 index 0000000000..cd332abd01 --- /dev/null +++ b/tools/authcon/seth/src/EasySSLProtocolSocketFactory.java @@ -0,0 +1,238 @@ +package org.apache.cocoon.transformation; + +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; + +import javax.net.SocketFactory; +//import javax.net.ssl.SSLContext; +//import javax.net.ssl.TrustManager; +import com.sun.net.ssl.SSLContext; +import com.sun.net.ssl.TrustManagerFactory; +import com.sun.net.ssl.TrustManager; +import com.sun.net.ssl.X509TrustManager; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.HttpClientError; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +//import org.apache.commons.httpclient.contrib.ssl.EasyX509TrustManager; + +/** + *

+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s + * that accept self-signed certificates. + *

+ *

+ * This socket factory SHOULD NOT be used for productive systems + * due to security reasons, unless it is a concious decision and + * you are perfectly aware of security implications of accepting + * self-signed certificates + *

+ * + *

+ * Example of using custom protocol socket factory for a specific host: + *

+ *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
+ *
+ *     URI uri = new URI("https://localhost/", true);
+ *     // use relative url only
+ *     GetMethod httpget = new GetMethod(uri.getPathQuery());
+ *     HostConfiguration hc = new HostConfiguration();
+ *     hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
+ *     HttpClient client = new HttpClient();
+ *     client.executeMethod(hc, httpget);
+ *     
+ *

+ *

+ * Example of using custom protocol socket factory per default instead of the standard one: + *

+ *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
+ *     Protocol.registerProtocol("https", easyhttps);
+ *
+ *     HttpClient client = new HttpClient();
+ *     GetMethod httpget = new GetMethod("https://localhost/");
+ *     client.executeMethod(httpget);
+ *     
+ *

+ * + * @author Oleg Kalnichevski + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. + * The component is provided as a reference material, which may be inappropriate + * for use without additional customization. + *

+ */ + +public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory { + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class); + + private SSLContext sslcontext = null; + + /** + * Constructor for EasySSLProtocolSocketFactory. + */ + public EasySSLProtocolSocketFactory() { + super(); + } + + private static SSLContext createEasySSLContext() { + try { + SSLContext context = SSLContext.getInstance("SSL"); + context.init( + null, + new TrustManager[] {new EasyX509TrustManager(null)}, + null); + return context; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new HttpClientError(e.toString()); + } + } + + private SSLContext getSSLContext() { + if (this.sslcontext == null) { + this.sslcontext = createEasySSLContext(); + } + return this.sslcontext; + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) + */ + public Socket createSocket( + String host, + int port, + InetAddress clientHost, + int clientPort) + throws IOException, UnknownHostException { + + return getSSLContext().getSocketFactory().createSocket( + host, + port, + clientHost, + clientPort + ); + } + + /** + * Attempts to get a new socket connection to the given host within the given time limit. + *

+ * To circumvent the limitations of older JREs that do not support connect timeout a + * controller thread is executed. The controller thread attempts to create a new socket + * within the given limit of time. If socket constructor does not return until the + * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException} + *

+ * + * @param host the host name/IP + * @param port the port on the host + * @param clientHost the local host name/IP to bind the socket to + * @param clientPort the port on the local machine + * @param params {@link HttpConnectionParams Http connection parameters} + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + public Socket createSocket( + final String host, + final int port, + final InetAddress localAddress, + final int localPort, + final HttpConnectionParams params + ) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = getSSLContext().getSocketFactory(); + if (timeout == 0) { + return socketfactory.createSocket(host, port, localAddress, localPort); + } else { + Socket socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + return socket; + } + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) + */ + public Socket createSocket(String host, int port) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + host, + port + ); + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) + */ + public Socket createSocket( + Socket socket, + String host, + int port, + boolean autoClose) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + socket, + host, + port, + autoClose + ); + } + + public boolean equals(Object obj) { + return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class)); + } + + public int hashCode() { + return EasySSLProtocolSocketFactory.class.hashCode(); + } + +} diff --git a/tools/authcon/seth/src/EasyX509TrustManager.java b/tools/authcon/seth/src/EasyX509TrustManager.java new file mode 100644 index 0000000000..0090dd0f14 --- /dev/null +++ b/tools/authcon/seth/src/EasyX509TrustManager.java @@ -0,0 +1,121 @@ +package org.apache.cocoon.transformation; +/* + * ==================================================================== + * + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + + +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import com.sun.net.ssl.TrustManagerFactory; +import com.sun.net.ssl.TrustManager; +import com.sun.net.ssl.X509TrustManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + *

+ * EasyX509TrustManager unlike default {@link X509TrustManager} accepts + * self-signed certificates. + *

+ *

+ * This trust manager SHOULD NOT be used for productive systems + * due to security reasons, unless it is a concious decision and + * you are perfectly aware of security implications of accepting + * self-signed certificates + *

+ * + * @author Adrian Sutton + * @author Oleg Kalnichevski + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. + * The component is provided as a reference material, which may be inappropriate + * for use without additional customization. + *

+ */ + +public class EasyX509TrustManager implements X509TrustManager +{ + private X509TrustManager standardTrustManager = null; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(EasyX509TrustManager.class); + + /** + * Constructor for EasyX509TrustManager. + */ + public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException { + super(); + TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509"); + factory.init(keystore); + TrustManager[] trustmanagers = factory.getTrustManagers(); + if (trustmanagers.length == 0) { + throw new NoSuchAlgorithmException("SunX509 trust manager not supported"); + } + this.standardTrustManager = (X509TrustManager)trustmanagers[0]; + } + + /** + * @see com.sun.net.ssl.X509TrustManager#isClientTrusted(X509Certificate[]) + */ + public boolean isClientTrusted(X509Certificate[] certificates) { + return this.standardTrustManager.isClientTrusted(certificates); + } + + /** + * @see com.sun.net.ssl.X509TrustManager#isServerTrusted(X509Certificate[]) + */ + public boolean isServerTrusted(X509Certificate[] certificates) { + if ((certificates != null) && LOG.isDebugEnabled()) { + LOG.debug("Server certificate chain:"); + for (int i = 0; i < certificates.length; i++) { + LOG.debug("X509Certificate[" + i + "]=" + certificates[i]); + } + } + if ((certificates != null) && (certificates.length == 1)) { + X509Certificate certificate = certificates[0]; + try { + certificate.checkValidity(); + } + catch (CertificateException e) { + LOG.error(e.toString()); + return false; + } + return true; + } else { + return this.standardTrustManager.isServerTrusted(certificates); + } + } + + /** + * @see com.sun.net.ssl.X509TrustManager#getAcceptedIssuers() + */ + public X509Certificate[] getAcceptedIssuers() { + return this.standardTrustManager.getAcceptedIssuers(); + } +} diff --git a/tools/authcon/seth/src/sethTransformer.java b/tools/authcon/seth/src/sethTransformer.java new file mode 100644 index 0000000000..99caf63500 --- /dev/null +++ b/tools/authcon/seth/src/sethTransformer.java @@ -0,0 +1,1517 @@ +/* + sethTransformer - written in May 2004 + * updated 2005 for hackfest + * updated 2009 for ssl sockets/certificate handling + + (c) Copyright GNU General Public License (GPL) + @author art rhyno +*/ +package org.apache.cocoon.transformation; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +import java.net.*; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.SourceResolver; + +import org.apache.cocoon.xml.dom.DOMStreamer; +import org.apache.cocoon.xml.XMLConsumer; +import org.apache.cocoon.xml.XMLUtils; + +import org.apache.commons.httpclient.*; +import org.apache.commons.httpclient.auth.AuthPolicy; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.httpclient.util.HttpURLConnection; +import org.apache.commons.httpclient.cookie.CookiePolicy; +import org.apache.commons.httpclient.methods.*; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.util.URIUtil; + +//import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory; + +import org.apache.regexp.RE; +import org.apache.regexp.RESyntaxException; + +import org.xml.sax.Attributes; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.tidy.Tidy; + +/** + * SETH Transformer - May, 2004 + * + * @author art rhyno + */ +public class sethTransformer extends AbstractTransformer { + + public static final String my_uri = "http://seth.sourceforge.net"; + public static final String my_name = "sethTransformer"; + + /** Outgoing tags */ + public static final String RESULTS_ELEMENT = "retrieval-results"; + public static final String URL_ELEMENT = "url"; + public static final String RESPONSE_ELEMENT = "responses"; + public static final String REQUEST_ELEMENT = "requests"; + public static final String COOKIES_ELEMENT = "cookies"; + public static final String CONTENTS_ELEMENT = "contents"; + public static final String REGEXP_ELEMENT = "regexpval"; + + /** Our allowed tags */ + public static final String MAGIC_EXECUTE_RETRIEVAL = "execute-retrieval"; + public static final String MAGIC_URL_ELEMENT = "url"; + public static final String MAGIC_USERNAME_ELEMENT = "username"; + public static final String MAGIC_PASSWORD_ELEMENT = "password"; + public static final String MAGIC_LIMIT_ELEMENT = "limit"; + public static final String MAGIC_USERAGENT_ELEMENT = "useragent"; + public static final String MAGIC_TIMEOUT_ELEMENT = "timeout"; + public static final String MAGIC_REDIRECT_LIMIT_ELEMENT = "redirect_limit"; + public static final String MAGIC_REGEXP_ELEMENT = "regexp"; + public static final String MAGIC_NVP_ELEMENT = "nvp"; + public static final String MAGIC_COOKIE_ELEMENT = "cookie"; + public static final String MAGIC_METHOD_ELEMENT = "method"; + public static final String MAGIC_REDIRECT_ELEMENT = "redirect"; + public static final String MAGIC_DEBUG_ELEMENT = "debug"; + + /** The states we are allowed to be in */ + public static final int STATE_OUTSIDE = 0; + public static final int STATE_INSIDE_EXECUTE_RETRIEVAL = 1; + public static final int STATE_INSIDE_URL_ELEMENT = 2; + public static final int STATE_INSIDE_USERNAME_ELEMENT = 3; + public static final int STATE_INSIDE_PASSWORD_ELEMENT = 4; + public static final int STATE_INSIDE_LIMIT_ELEMENT = 5; + public static final int STATE_INSIDE_USERAGENT_ELEMENT = 6; + public static final int STATE_INSIDE_TIMEOUT_ELEMENT = 7; + public static final int STATE_INSIDE_REDIRECT_LIMIT_ELEMENT = 8; + public static final int STATE_INSIDE_REGEXP_ELEMENT = 9; + public static final int STATE_INSIDE_NVP_ELEMENT = 10; + public static final int STATE_INSIDE_COOKIE_ELEMENT = 11; + public static final int STATE_INSIDE_METHOD_ELEMENT = 12; + public static final int STATE_INSIDE_REDIRECT_ELEMENT = 13; + public static final int STATE_INSIDE_DEBUG_ELEMENT = 14; + + /** Default parameters that might apply to all retrievals */ + protected Properties default_properties = new Properties(); + + /** The name of the value element we're currently receiving */ + protected String current_name; + + /** The current state of the event receiving FSM */ + protected int current_state = STATE_OUTSIDE; + + /** The value of the value element we're currently receiving */ + protected StringBuffer current_value = new StringBuffer(); + + /** The list of retrievals that we're currently working on */ + protected Vector retrievals = new Vector(); + + /** The offset of the current retrieval in the retrievals list */ + protected int current_retrieval_index = -1; + + /** SAX producing state information */ + protected XMLConsumer xml_consumer; + protected LexicalHandler lexical_handler; + + /** BEGIN SitemapComponent methods */ + + public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters) + throws ProcessingException, SAXException, IOException { + current_state = STATE_OUTSIDE; + + String parameter; + + // Check the url + parameter = parameters.getParameter(MAGIC_URL_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_URL_ELEMENT, parameter); + } + + // Check the username + parameter = parameters.getParameter(MAGIC_USERNAME_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_USERNAME_ELEMENT, parameter); + } + + // Check the password + parameter = parameters.getParameter(MAGIC_PASSWORD_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_PASSWORD_ELEMENT, parameter); + } + + // Check the limit + parameter = parameters.getParameter(MAGIC_LIMIT_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_LIMIT_ELEMENT, parameter); + } + + // Check the useragent + parameter = parameters.getParameter(MAGIC_USERAGENT_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_USERAGENT_ELEMENT, parameter); + } + + // Check the timeout + parameter = parameters.getParameter(MAGIC_TIMEOUT_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_TIMEOUT_ELEMENT, parameter); + } + + // Check the redirect_limit + parameter = parameters.getParameter(MAGIC_REDIRECT_LIMIT_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_REDIRECT_LIMIT_ELEMENT, parameter); + } + + // Check the regexp + parameter = parameters.getParameter(MAGIC_REGEXP_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_REGEXP_ELEMENT, parameter); + } + + // Check the method + parameter = parameters.getParameter(MAGIC_METHOD_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_METHOD_ELEMENT, parameter); + } + + // Check the nvp + parameter = parameters.getParameter(MAGIC_NVP_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_NVP_ELEMENT, parameter); + } + + // Check the cookie + parameter = parameters.getParameter(MAGIC_COOKIE_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_COOKIE_ELEMENT, parameter); + } + + // Check the redirect element + parameter = parameters.getParameter(MAGIC_REDIRECT_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_REDIRECT_ELEMENT, parameter); + } + + // Check the debug element + parameter = parameters.getParameter(MAGIC_DEBUG_ELEMENT, null); + if (parameter != null) { + default_properties.setProperty(MAGIC_DEBUG_ELEMENT, parameter); + } + + } + + /** END SitemapComponent methods */ + + /** + * This will be the meat of sethTransformer, where the retrieval is run. + */ + protected void executeRetrieval(int index) throws SAXException { + // this.contentHandler.startPrefixMapping("", sethTransformer.my_uri); + HTMLRetrieval retrieval = (HTMLRetrieval) retrievals.elementAt(index); + try { + retrieval.execute(); + } catch (Exception e) { + System.out.println("error " + e.toString()); + getLogger().error(e.toString()); + throw new SAXException(e); + } + + this.contentHandler.endPrefixMapping(""); + } + + protected static void throwIllegalStateException(String message) { + throw new IllegalStateException(my_name + ": " + message); + } + + /** Move into elements */ + protected void startExecuteRetrieval(Attributes attributes) { + HTMLRetrieval retrieval; + switch (current_state) { + case sethTransformer.STATE_OUTSIDE : + current_state = sethTransformer.STATE_INSIDE_EXECUTE_RETRIEVAL; + current_retrieval_index = retrievals.size(); + retrieval = new HTMLRetrieval(this); + retrievals.addElement(retrieval); + getCurrentRetrieval().toDo = sethTransformer.STATE_INSIDE_EXECUTE_RETRIEVAL; + getCurrentRetrieval().retrieval_index = current_retrieval_index; + break; + default : + throwIllegalStateException("Not expecting a start execute-retrieval element"); + } + } + + protected void endExecuteRetrieval() throws SAXException { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + executeRetrieval(current_retrieval_index); + retrievals.remove(current_retrieval_index); + --current_retrieval_index; + if (current_retrieval_index > -1) { + current_state = getCurrentRetrieval().toDo; + } else { + retrievals.removeAllElements(); + current_state = sethTransformer.STATE_OUTSIDE; + } + break; + default : + throwIllegalStateException("Not expecting a end execute-retrieval element"); + } + } + + protected void startNvpElement(Attributes attributes) { + String thisName = attributes.getValue("name"); + + if (thisName != null) + getCurrentRetrieval().nvpName = thisName; + else + throwIllegalStateException("value without name"); + + String checkJsonSpace = attributes.getValue("jsspace"); + if (checkJsonSpace != null) + getCurrentRetrieval().jsspace = checkJsonSpace; + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_NVP_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start nvp element"); + } + } + + protected void endNvpElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_NVP_ELEMENT : + String parmVal = current_value.toString().trim(); + //examples of extra encoding options + /* + try { + parmVal = URIUtil.encodeQuery(parmVal); + } catch (URIException uriEx) { + System.out.println("prob: " + uriEx.toString()); + parmVal = current_value.toString().trim(); + } */ + /* + try { + parmVal = URLEncoder.encode(parmVal,"UTF-8"); + } catch (UnsupportedEncodingException uriEx) { + System.out.println("prob: " + uriEx.toString()); + parmVal = current_value.toString().trim(); + } + */ + + //we can't always rely on uri encodings for whitespaces + if (getCurrentRetrieval().jsspace != null) + parmVal = parmVal.replaceAll(" ","\\\\u0020"); + + NameValuePair thisNVP = new NameValuePair( + getCurrentRetrieval().nvpName, + parmVal); + getCurrentRetrieval().nvps.addElement(thisNVP); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end nvp element"); + } + } + + protected void startCookieElement(Attributes attributes) { + String checkDomain = attributes.getValue("domain"); + if (checkDomain != null) + getCurrentRetrieval().thisDomain = checkDomain; + + if (checkDomain == null) { + try { + InetAddress localaddr = InetAddress.getLocalHost(); + String thisHost = localaddr.getHostAddress().toString(); + int firstPart = thisHost.indexOf("."); + if (firstPart != -1) + getCurrentRetrieval().thisDomain = + thisHost.substring(firstPart); + } catch (UnknownHostException uhe) { + getCurrentRetrieval().thisDomain = "*"; + + } + } + getCurrentRetrieval().thisName = attributes.getValue("name"); + getCurrentRetrieval().thisPath = attributes.getValue("path"); + String checkDate = attributes.getValue("date"); + if (checkDate != null) { + DateFormat theFormat = new + SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy"); + try { + getCurrentRetrieval().thisDate = + theFormat.parse(checkDate); + } catch (Exception e) { + throwIllegalStateException("Problem with cookie date"); + } + } + String checkAge = attributes.getValue("age"); + if (checkAge != null) + getCurrentRetrieval().thisAge = Integer.parseInt(checkAge); + String checkSecure = attributes.getValue("secure"); + if (checkSecure != null) { + if (checkSecure.trim().toUpperCase().equals("TRUE")) + getCurrentRetrieval().isSecure = true; + } + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_COOKIE_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start cookie element"); + } + } + + protected void endCookieElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_COOKIE_ELEMENT : + String thisValue = current_value.toString().trim(); + Cookie thisCookie; + System.out.println("-> domain: " + + getCurrentRetrieval().thisDomain + "\n name: " + + getCurrentRetrieval().thisName + "\n value: " + + thisValue + "\n path: " + + getCurrentRetrieval().thisPath + "\n date: " + + getCurrentRetrieval().thisDate +"\n secure: " + + getCurrentRetrieval().isSecure); + + if (getCurrentRetrieval().thisPath != null && + getCurrentRetrieval().thisDate != null) + { + System.out.println("1"); + thisCookie = new Cookie(getCurrentRetrieval().thisDomain, + getCurrentRetrieval().thisName, + thisValue, + getCurrentRetrieval().thisPath, + getCurrentRetrieval().thisDate, + getCurrentRetrieval().isSecure); + } else if (getCurrentRetrieval().thisPath != null && + getCurrentRetrieval().thisAge >= 0) + { + System.out.println("2"); + thisCookie = new Cookie(getCurrentRetrieval().thisDomain, + getCurrentRetrieval().thisName, + thisValue, + getCurrentRetrieval().thisPath, + getCurrentRetrieval().thisAge, + getCurrentRetrieval().isSecure); + } else { + System.out.println("3"); + thisCookie = new Cookie(getCurrentRetrieval().thisDomain, + getCurrentRetrieval().thisName, + thisValue); + } + getCurrentRetrieval().sethcookies.addElement(thisCookie); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end cookie element"); + } + } + + protected void startMethodElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_METHOD_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start method element"); + } + } + + protected void endMethodElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_METHOD_ELEMENT : + getCurrentRetrieval().method = current_value.toString().trim().toUpperCase(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end method element"); + } + } + + protected void startUrlElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_URL_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start url element"); + } + } + + protected void endUrlElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_URL_ELEMENT : + getCurrentRetrieval().url = current_value.toString(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end url element"); + } + } + + protected void startUsernameElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_USERNAME_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start username element"); + } + } + + protected void endUsernameElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_USERNAME_ELEMENT : + getCurrentRetrieval().username = current_value.toString(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end username element"); + } + } + + protected void startPasswordElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_PASSWORD_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start password element"); + } + } + + protected void endPasswordElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_PASSWORD_ELEMENT : + getCurrentRetrieval().password = current_value.toString(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end password element"); + } + } + + protected void startLimitElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_LIMIT_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start limit element"); + } + } + + protected void endLimitElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_LIMIT_ELEMENT : + getCurrentRetrieval().limit = current_value.toString().trim().toUpperCase(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end limit element"); + } + } + protected void startUserAgentElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_USERAGENT_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start useragent element"); + } + } + + protected void endUserAgentElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_USERAGENT_ELEMENT : + getCurrentRetrieval().useragent = current_value.toString().trim(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end useragent element"); + } + } + + protected void startTimeoutElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_TIMEOUT_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start timeout element"); + } + } + + protected void endTimeoutElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_TIMEOUT_ELEMENT : + getCurrentRetrieval().timeout = Integer.parseInt(current_value.toString()); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end timeout element"); + } + } + + protected void startRedirectLimitElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_REDIRECT_LIMIT_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start redirect_limit element"); + } + } + + protected void endRedirectLimitElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_REDIRECT_LIMIT_ELEMENT : + getCurrentRetrieval().redirect_limit = Integer.parseInt(current_value.toString()); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end redirect_limit element"); + } + } + + protected void startRegExpElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_REGEXP_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start regexp element"); + } + } + + protected void endRegExpElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_REGEXP_ELEMENT : + getCurrentRetrieval().regexp = current_value.toString(); + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end regexp element"); + } + } + + protected void startRedirectElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_REDIRECT_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start redirect element"); + } + } + + protected void endRedirectElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_REDIRECT_ELEMENT : + if (current_value.toString().toUpperCase().equals("FALSE")) { + getCurrentRetrieval().redirect = false; + } + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end redirect element"); + } + } + + protected void startDebugElement(Attributes attributes) { + switch (current_state) { + case STATE_INSIDE_EXECUTE_RETRIEVAL : + current_value.setLength(0); + current_state = sethTransformer.STATE_INSIDE_DEBUG_ELEMENT; + break; + default : + throwIllegalStateException("Not expecting a start debug element"); + } + } + + protected void endDebugElement() { + switch (current_state) { + case sethTransformer.STATE_INSIDE_DEBUG_ELEMENT : + if (current_value.toString().toUpperCase().equals("TRUE")) { + getCurrentRetrieval().debug = true; + } + current_state = getCurrentRetrieval().toDo; + break; + default : + throwIllegalStateException("Not expecting a end debug element"); + } + } + + protected HTMLRetrieval getCurrentRetrieval() { + return (HTMLRetrieval) retrievals.elementAt(current_retrieval_index); + } + + protected HTMLRetrieval getRetrieval(int i) { + return (HTMLRetrieval) retrievals.elementAt(i); + } + + /** END my very own methods */ + + /** BEGIN SAX ContentHandler handlers */ + + public void setDocumentLocator(Locator locator) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("PUBLIC ID: " + locator.getPublicId()); + getLogger().debug("SYSTEM ID: " + locator.getSystemId()); + } + if (super.contentHandler != null) + super.contentHandler.setDocumentLocator(locator); + } + + public void startElement(String uri, String name, String raw, Attributes attributes) throws SAXException { + if (!uri.equals(my_uri)) { + super.startElement(uri, name, raw, attributes); + return; + } + getLogger().debug("RECEIVED START ELEMENT " + name + "(" + uri + ")"); + + if (name.equals(sethTransformer.MAGIC_EXECUTE_RETRIEVAL)) { + startExecuteRetrieval(attributes); + } else if (name.equals(sethTransformer.MAGIC_NVP_ELEMENT)) { + startNvpElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_COOKIE_ELEMENT)) { + startCookieElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_METHOD_ELEMENT)) { + startMethodElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_URL_ELEMENT)) { + startUrlElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_USERNAME_ELEMENT)) { + startUsernameElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_PASSWORD_ELEMENT)) { + startPasswordElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_LIMIT_ELEMENT)) { + startLimitElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_USERAGENT_ELEMENT)) { + startUserAgentElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_TIMEOUT_ELEMENT)) { + startTimeoutElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_REDIRECT_LIMIT_ELEMENT)) { + startRedirectLimitElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_REGEXP_ELEMENT)) { + startRegExpElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_REDIRECT_ELEMENT)) { + startRedirectElement(attributes); + } else if (name.equals(sethTransformer.MAGIC_DEBUG_ELEMENT)) { + startDebugElement(attributes); + } + } + + public void endElement(String uri, String name, String raw) throws SAXException { + if (!uri.equals(my_uri)) { + super.endElement(uri, name, raw); + return; + } + getLogger().debug("RECEIVED END ELEMENT " + name + "(" + uri + ")"); + + if (name.equals(sethTransformer.MAGIC_EXECUTE_RETRIEVAL)) { + endExecuteRetrieval(); + } else if (name.equals(sethTransformer.MAGIC_NVP_ELEMENT)) { + endNvpElement(); + } else if (name.equals(sethTransformer.MAGIC_COOKIE_ELEMENT)) { + endCookieElement(); + } else if (name.equals(sethTransformer.MAGIC_METHOD_ELEMENT)) { + endMethodElement(); + } else if (name.equals(sethTransformer.MAGIC_URL_ELEMENT)) { + endUrlElement(); + } else if (name.equals(sethTransformer.MAGIC_USERNAME_ELEMENT)) { + endUsernameElement(); + } else if (name.equals(sethTransformer.MAGIC_PASSWORD_ELEMENT)) { + endPasswordElement(); + } else if (name.equals(sethTransformer.MAGIC_LIMIT_ELEMENT)) { + endLimitElement(); + } else if (name.equals(sethTransformer.MAGIC_USERAGENT_ELEMENT)) { + endUserAgentElement(); + } else if (name.equals(sethTransformer.MAGIC_TIMEOUT_ELEMENT)) { + endTimeoutElement(); + } else if (name.equals(sethTransformer.MAGIC_REDIRECT_LIMIT_ELEMENT)) { + endRedirectLimitElement(); + } else if (name.equals(sethTransformer.MAGIC_REGEXP_ELEMENT)) { + endRegExpElement(); + } else if (name.equals(sethTransformer.MAGIC_REDIRECT_ELEMENT)) { + endRedirectElement(); + } else if (name.equals(sethTransformer.MAGIC_DEBUG_ELEMENT)) { + endDebugElement(); + } + } + + public void characters(char ary[], int start, int length) throws SAXException { + if (current_state != sethTransformer.STATE_INSIDE_NVP_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_COOKIE_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_METHOD_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_URL_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_USERNAME_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_PASSWORD_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_LIMIT_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_USERAGENT_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_TIMEOUT_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_REDIRECT_LIMIT_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_REGEXP_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_REDIRECT_ELEMENT + && current_state != sethTransformer.STATE_INSIDE_DEBUG_ELEMENT) + { + super.characters(ary, start, length); + } + getLogger().debug("RECEIVED CHARACTERS: " + new String(ary, start, length)); + current_value.append(ary, start, length); + } + + private void attribute(AttributesImpl attr, String name, String value) { + attr.addAttribute("", name, name, "CDATA", value); + } + + private void start(String name, AttributesImpl attr) throws SAXException { + super.contentHandler.startElement("", name, name, attr); + attr.clear(); + } + + private void end(String name) throws SAXException { + super.contentHandler.endElement("", name, name); + } + + private void data(String data) throws SAXException { + if (data != null) + super.contentHandler.characters(data.toCharArray(), 0, data.length()); + } + + protected static String getStringValue(Object object) { + if (object instanceof byte[]) { + return new String((byte[]) object); + } else if (object instanceof char[]) { + return new String((char[]) object); + } else if (object != null) { + return object.toString(); + } else { + return ""; + } + } + + public final Logger getTheLogger() { + return getLogger(); + } + + class HTMLRetrieval { + + /** Index for retrievals list */ + protected int retrieval_index; + + /** The current state of the event */ + protected int current_state; + + protected sethTransformer transformer; + + protected String url = "http://127.0.0.1"; + + protected String username = null; + + protected String password = null; + + protected String limit = null; + + protected String useragent = null; + + protected int timeout = 0; + + protected int redirect_limit = 5; + + protected String regexp = null; + + protected RE sethRE; + + protected String method = "GET"; + + protected String cookieType = "NAME"; + + protected Vector nvps = new Vector(); + + protected Vector sethcookies = new Vector(); + + protected int toDo; + + //NVP values + protected String nvpName = null; + protected String jsspace = null; + + //Cookie values + protected String thisDomain = null; + protected String thisName = null; + protected String thisPath = null; + protected Date thisDate = null; + protected int thisAge = -1; + protected boolean isSecure = false; + + protected int sequence = 1; + + protected StringBuffer textBucket = new StringBuffer(); + + protected AttributesImpl attr = new AttributesImpl(); + + protected HttpClient _httpClient; + + protected HttpMethod _httpMethod; + + protected boolean redirect = true; + + protected int limitTagBlock = 0; + + protected boolean debug = false; + + //work through elements + protected HTMLRetrieval(sethTransformer transformer) { + this.transformer = transformer; + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_NVP_ELEMENT)) + { + nvps.addElement(transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_NVP_ELEMENT)); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_COOKIE_ELEMENT)) + { + sethcookies.addElement(transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_COOKIE_ELEMENT)); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_METHOD_ELEMENT)) + { + method = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_METHOD_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_URL_ELEMENT)) + { + url = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_URL_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_USERNAME_ELEMENT)) + { + username = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_USERNAME_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_PASSWORD_ELEMENT)) + { + password = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_PASSWORD_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_LIMIT_ELEMENT)) + { + limit = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_LIMIT_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_USERAGENT_ELEMENT)) + { + useragent = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_USERAGENT_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_TIMEOUT_ELEMENT)) + { + timeout = Integer.parseInt(transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_TIMEOUT_ELEMENT)); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_REDIRECT_LIMIT_ELEMENT)) + { + redirect_limit = Integer.parseInt(transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_REDIRECT_LIMIT_ELEMENT)); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_REGEXP_ELEMENT)) + { + regexp = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_REGEXP_ELEMENT); + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_REDIRECT_ELEMENT)) + { + redirect = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_REDIRECT_ELEMENT).equals("TRUE") ? true : false; + } + + if (null != transformer. + default_properties. + getProperty(sethTransformer.MAGIC_DEBUG_ELEMENT)) + { + debug = transformer. + default_properties. + getProperty(sethTransformer. + MAGIC_DEBUG_ELEMENT).equals("TRUE") ? true : false; + } + + + } //HTMLRetrieval + + // set up DOM and execute http request + protected void execute() throws Exception { + int ret; + + //start with regexp + if (regexp != null) { + try { + sethRE = new RE(regexp); + } catch (RESyntaxException reex) { + transformer.getTheLogger().debug("[sethTransformer] " + + "compiling regular expression problem " + + reex.toString()); + regexp = null; + } + } + + if (debug) + debugPrint(); + try { + // Setup an instance of Tidy. + Tidy tidy = new Tidy(); + tidy.setXmlOut(true); + tidy.setXHTML(true); + tidy.setIndentAttributes(true); + + tidy.setShowWarnings(getLogger().isWarnEnabled()); + + tidy.setQuiet(!getLogger().isInfoEnabled()); + StringWriter stringWriter = new StringWriter(); + PrintWriter errorWriter = new PrintWriter(stringWriter); + + tidy.setErrout(errorWriter); + + + HttpMethod _httpMethod = workOutHttpMethod(url, username, password); + URL thisUrl = new URL(url); + HttpURLConnection _httpURLConnection = new HttpURLConnection(_httpMethod, thisUrl); + System.out.println("lm: " + _httpURLConnection.getLastModified()); + Date last_modified = new Date(_httpURLConnection.getLastModified()); + + org.w3c.dom.Document doc = tidy.parseDOM(new + BufferedInputStream(_httpMethod.getResponseBodyAsStream()), null); + + XMLUtils.stripDuplicateAttributes(doc, null); + + Element docRoot = doc.getDocumentElement(); + + Cookie[] cookies = _httpClient.getState().getCookies(); + + Header[] responseHeaders = _httpMethod.getResponseHeaders(); + + Header[] requestHeaders = _httpMethod.getRequestHeaders(); + + //_httpClient.endSession(); + transformer.start(RESULTS_ELEMENT, attr); + + transformer.start(URL_ELEMENT, attr); + transformer.data(url); + transformer.end(URL_ELEMENT); + + transformer.start(RESPONSE_ELEMENT, attr); + for (int i=0; i 0) { + String qs = ((HttpMethod) _httpMethod).getQueryString(); + NameValuePair nvpa[] = new NameValuePair[nvps.size()]; + ((HttpMethod) _httpMethod).setQueryString((NameValuePair []) + nvps.toArray(nvpa)); + if (qs != null) { + ((HttpMethod) _httpMethod). + setQueryString(qs + "&" + + ((HttpMethod) _httpMethod). + getQueryString()); + } + } + } + System.out.println("0"); + + if (timeout > 0) + _httpClient.setTimeout(timeout * 1000); + + + if (method.equals("GET")) + ((HttpMethod) _httpMethod).setFollowRedirects(redirect); + /* setFollowRedirects won't work for a post, need somethng like this + if (method.equals("POST")) { + URI redirectLocation = new URI( + ((HttpMethod) _httpMethod).getURI(), + ((HttpMethod) _httpMethod).getResponseHeader("location"). + getValue() + ); + */ + + System.out.println("1"); + + // HTTPSession + //_httpClient.startSession(u); + HostConfiguration hostConfig = _httpClient.getHostConfiguration(); + System.out.println("3"); + hostConfig.setHost(u.getHost(),u.getPort(),u.getProtocol()); + + /* - would we ever set these? + for(int i = 0; i < this.header.size(); i++) { + ((HttpMethod) _httpMethod).setRequestHeader( + (Header) this.header.elementAt(i)); + } + */ + + System.out.println("4"); + // value for "accept-encoding" must be empty + ((HttpMethod) _httpMethod). + setRequestHeader("accept-encoding", ""); + + /* + ((HttpMethod) _httpMethod). + setRequestHeader( + "Content-Type", + "text/plain; charset=utf-8"); + */ + + + System.out.println("username is " + + username + " and " + password); + if (username != null && password != null) { + System.out.println("host is " + u.getHost()); + /* + Credentials defaultcreds = new UsernamePasswordCredentials(username, password); + _httpClient.getState().setCredentials(null, u.getHost(), defaultcreds); + _httpClient.getState().setAuthenticationPreemptive(true); + */ + + List authPrefs = new ArrayList(2); + authPrefs.add(AuthPolicy.DIGEST ); + authPrefs.add(AuthPolicy.BASIC); + _httpClient.getParams().setParameter (AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs); + _httpClient.getParams().setAuthenticationPreemptive(true); + Credentials defaultcreds = new UsernamePasswordCredentials(username, password); + //_httpClient.getState().setCredentials(new AuthScope( u.getHost(), 443, AuthScope.ANY_REALM), defaultcreds); + _httpClient.getState().setCredentials(null, u.getHost(), defaultcreds); + } + + try { + System.out.println("here goes"); + result = _httpClient.executeMethod(_httpMethod); + System.out.println("the result - " + result); + } catch (Exception ex) { + System.out.println("oh oh"); + System.out.println(ex.toString()); + } + int num_redirects = 0; + + while (result == HttpStatus.SC_MOVED_TEMPORARILY && + num_redirects++ < redirect_limit) { + //will need to make this a parameter at some point + locationHeader = + ((HttpMethod) _httpMethod). + getResponseHeader("location"); + if (locationHeader != null) { + redirectLocation = + locationHeader.getValue(); + System.out.println("suggesting " + + redirectLocation); + //I am assuming a redirect is always a GET + //If not, we would need something like this +/* + if (method.equals("GET")) { + _httpMethod = new GetMethod(redirectLocation); + } else { + _httpMethod = new PostMethod( + redirectLocation); + } +*/ + _httpMethod = new GetMethod(redirectLocation); + System.out.println("result is now - " + result); + result = _httpClient.executeMethod(_httpMethod); + } + } + + Cookie[] cookies = _httpClient.getState().getCookies(); + if (username != null && password != null) + _httpMethod.setDoAuthentication( true ); + + return _httpMethod; + } catch (Exception e){ + getLogger().error("problem: ", e); + } + + return null; + } + + // Traverse DOM Tree. Print out Element Names + protected void traverse (Node node) + throws IOException, SAXException { + String name = ""; + String value = ""; + int numChildren = 0; + + int type = node.getNodeType(); + NodeList children = node.getChildNodes(); + if (children != null) + numChildren = children.getLength(); + + transformer.getTheLogger().debug("[sethTransformer] node type: " + type); + if (type == Node.ELEMENT_NODE) { + name = + node.getNodeName().trim(); + if (!checkLimitTags(name)) + transformer.start(name, copyAttributes(node)); + } + if (type == Node.TEXT_NODE) { + value = + node.getNodeValue().trim(); + if (textBucket.length() > 0) + textBucket.append(" "); + textBucket.append(value); + } + if (children != null) { + for (int i=0; i< numChildren; i++) + traverse (children.item(i)); + } + if (type == Node.ELEMENT_NODE) { + if (regexp != null && textBucket.length() > 0) { + try { + String newText = + textBucket.toString(); + + if (sethRE.match(newText)) { + transformer.getTheLogger().debug("[sethTransformer] regexp: " + regexp + + " matches on " + newText); + /* RE matches ok, but doesn't extract properly, may not need */ + /* + System.out.println("1> " + sethRE.getParenStart(0)); + System.out.println("2> " + sethRE.getParenStart(1)); + System.out.println("3> " + sethRE.getParenEnd(0)); + System.out.println("4> " + sethRE.getParenEnd(1)); + System.out.println("5> " + sethRE.getParen(0)); + System.out.println("6> " + sethRE.getParen(1)); + */ + + transformer.start(REGEXP_ELEMENT,attr); + transformer.data(newText); + transformer.end(REGEXP_ELEMENT); + textBucket.setLength(0); + } + } catch (Exception reex) { + System.out.println("matching regular expression problem " + reex.toString()); + regexp = null; + } + } + if (textBucket.length() > 0) { + if (!checkLimitTags(name)) + transformer.data(textBucket.toString()); + textBucket.setLength(0); + } + if (!checkLimitTags(name)) + transformer.end(name); + } + } + + protected boolean checkLimitTags(String currentTag) { + if (limit != null) { + String thisLimit = "," + limit + ","; + int limitNum = thisLimit.indexOf("," + currentTag.trim().toUpperCase() + ","); + if (limitNum == -1 ) + return true; + } + + return false; + } +/* + protected boolean checkLimitTags(String currentTag,boolean atEnd,int numKids) { + if (limit != null) { + String thisLimit = "," + limit + ","; + int limitNum = thisLimit.indexOf("," + currentTag.trim().toUpperCase() + ","); + System.out.println("working with " + currentTag); + if (limitTagBlock > 0 && limitNum != -1 && atEnd) { + System.out.println("stopping block for " + currentTag); + limitTagBlock--; + System.out.println("value is now " + limitTagBlock); + } else { + if (limitNum == -1 && limitTagBlock <= 0) { + System.out.println("stop printing for " + currentTag); + return true; + } else { + if (limitNum != -1 && numKids > 0) { + System.out.println("set block to true for " + currentTag); + limitTagBlock++; + System.out.println("value is now " + limitTagBlock); + } + } + } + } + + return false; + } +*/ + + + protected AttributesImpl copyAttributes(Node currentNode) + throws IOException, SAXException + { + AttributesImpl currentAtts = new AttributesImpl(); + NamedNodeMap map = currentNode.getAttributes(); + currentAtts.clear(); + + for (int i = map.getLength() - 1; i >= 0; i--) { + Attr att = (Attr) map.item(i); + /* + currentAtts.addAttribute( att.getNamespaceURI(), + att.getLocalName(), att.getName(), + "CDATA", att.getValue()); + */ + currentAtts.addAttribute(null,att.getName(), att.getName(), + "CDATA", att.getValue()); + } + + return currentAtts; + } + + //show every element if working in DEBUG mode + protected void debugPrint() { + transformer.getTheLogger().debug("[sethTransformer] retrieval_index: " + retrieval_index); + transformer.getTheLogger().debug("[sethTransformer] # of nvps: " + nvps.size()); + transformer.getTheLogger().debug("[sethTransformer] # of cookies: " + sethcookies.size()); + transformer.getTheLogger().debug("[sethTransformer] url: " + url); + transformer.getTheLogger().debug("[sethTransformer] limit: " + limit); + transformer.getTheLogger().debug("[sethTransformer] redirect_limit: " + redirect_limit); + transformer.getTheLogger().debug("[sethTransformer] useragent: " + useragent); + transformer.getTheLogger().debug("[sethTransformer] timeout: " + timeout); + transformer.getTheLogger().debug("[sethTransformer] redirect: " + redirect); + transformer.getTheLogger().debug("[sethTransformer] regexp: " + regexp); + } + + } +} -- 2.11.0