From d9404210e4b835ded65db509126f306e8e6c3c84 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 8 Jun 2011 14:24:18 +0530 Subject: [PATCH] Sourced WebNotes Framework from Google Code. --- INSTALL.txt | 81 + blank.html | 39 + blank1.html | 0 cgi-bin/backupall.py | 24 + cgi-bin/core/Module Def/Core/Core.txt | 84 + .../core/Role/Administrator/Administrator.txt | 17 + cgi-bin/core/Role/All/All.txt | 17 + cgi-bin/core/Role/Guest/Guest.txt | 47 + cgi-bin/core/__init__.py | 0 cgi-bin/core/doctype/__init__.py | 0 .../doctype/comment_widget_record/__init__.py | 0 .../comment_widget_record.txt | 358 + .../core/doctype/control_panel/__init__.py | 0 .../doctype/control_panel/control_panel.py | 36 + .../doctype/control_panel/control_panel.txt | 1933 +++ cgi-bin/core/doctype/custom_field/__init__.py | 0 .../core/doctype/custom_field/custom_field.js | 54 + .../core/doctype/custom_field/custom_field.py | 100 + .../doctype/custom_field/custom_field.txt | 929 ++ .../core/doctype/custom_script/__init__.py | 0 .../doctype/custom_script/custom_script.txt | 189 + .../doctype/default_home_page/__init__.py | 0 .../default_home_page/default_home_page.txt | 125 + cgi-bin/core/doctype/defaultvalue/__init__.py | 0 .../doctype/defaultvalue/defaultvalue.txt | 125 + cgi-bin/core/doctype/docfield/__init__.py | 0 cgi-bin/core/doctype/docfield/docfield.txt | 907 ++ cgi-bin/core/doctype/docformat/__init__.py | 0 cgi-bin/core/doctype/docformat/docformat.txt | 90 + cgi-bin/core/doctype/docperm/__init__.py | 0 cgi-bin/core/doctype/docperm/docperm.txt | 405 + cgi-bin/core/doctype/doctrigger/__init__.py | 0 .../core/doctype/doctrigger/doctrigger.txt | 196 + cgi-bin/core/doctype/doctype/__init__.py | 0 cgi-bin/core/doctype/doctype/doctype.js | 75 + cgi-bin/core/doctype/doctype/doctype.py | 94 + cgi-bin/core/doctype/doctype/doctype.txt | 1796 +++ .../core/doctype/doctype_label/__init__.py | 0 .../doctype/doctype_label/doctype_label.txt | 148 + .../core/doctype/doctype_mapper/__init__.py | 0 .../doctype/doctype_mapper/doctype_mapper.js | 9 + .../doctype/doctype_mapper/doctype_mapper.py | 247 + .../doctype/doctype_mapper/doctype_mapper.txt | 311 + cgi-bin/core/doctype/event/__init__.py | 0 cgi-bin/core/doctype/event/event.txt | 603 + cgi-bin/core/doctype/event_role/__init__.py | 0 .../core/doctype/event_role/event_role.txt | 90 + cgi-bin/core/doctype/event_user/__init__.py | 0 .../core/doctype/event_user/event_user.txt | 90 + .../doctype/field_mapper_detail/__init__.py | 0 .../field_mapper_detail.txt | 230 + cgi-bin/core/doctype/file_data/__init__.py | 0 cgi-bin/core/doctype/file_data/file_data.txt | 125 + cgi-bin/core/doctype/letter_head/__init__.py | 0 .../core/doctype/letter_head/letter_head.js | 26 + .../core/doctype/letter_head/letter_head.py | 31 + .../core/doctype/letter_head/letter_head.txt | 324 + cgi-bin/core/doctype/module_def/__init__.py | 0 cgi-bin/core/doctype/module_def/module_def.py | 50 + .../core/doctype/module_def/module_def.txt | 708 + .../core/doctype/module_def_item/__init__.py | 0 .../module_def_item/module_def_item.txt | 335 + .../core/doctype/module_def_role/__init__.py | 0 .../module_def_role/module_def_role.txt | 90 + cgi-bin/core/doctype/page/__init__.py | 0 cgi-bin/core/doctype/page/page.py | 49 + cgi-bin/core/doctype/page/page.txt | 1023 ++ cgi-bin/core/doctype/page_role/__init__.py | 0 cgi-bin/core/doctype/page_role/page_role.txt | 90 + .../core/doctype/page_template/__init__.py | 0 .../doctype/page_template/page_template.py | 20 + .../doctype/page_template/page_template.txt | 160 + cgi-bin/core/doctype/print_format/__init__.py | 0 .../doctype/print_format/print_format.txt | 183 + cgi-bin/core/doctype/profile/__init__.py | 0 cgi-bin/core/doctype/profile/profile.js | 26 + cgi-bin/core/doctype/profile/profile.py | 48 + cgi-bin/core/doctype/profile/profile.txt | 2003 +++ .../core/doctype/property_setter/__init__.py | 0 .../property_setter/property_setter.comp.js | 8 + .../property_setter/property_setter.js | 109 + .../property_setter/property_setter.py | 29 + .../property_setter/property_setter.txt | 500 + cgi-bin/core/doctype/role/__init__.py | 0 cgi-bin/core/doctype/role/role.txt | 183 + .../core/doctype/search_criteria/__init__.py | 0 .../search_criteria/search_criteria.py | 71 + .../search_criteria/search_criteria.txt | 1092 ++ cgi-bin/core/doctype/stylesheet/__init__.py | 0 cgi-bin/core/doctype/stylesheet/stylesheet.py | 18 + .../core/doctype/stylesheet/stylesheet.txt | 160 + .../core/doctype/system_console/__init__.py | 0 .../system_console/system_console.comp.js | 8 + .../doctype/system_console/system_console.js | 23 + .../doctype/system_console/system_console.py | 17 + .../doctype/system_console/system_console.txt | 242 + .../doctype/table_mapper_detail/__init__.py | 0 .../table_mapper_detail.txt | 335 + cgi-bin/core/doctype/tag/__init__.py | 0 cgi-bin/core/doctype/tag/tag.txt | 90 + cgi-bin/core/doctype/userrole/__init__.py | 0 cgi-bin/core/doctype/userrole/userrole.txt | 90 + cgi-bin/core/module.info | 1 + cgi-bin/core/page/__init__.py | 0 cgi-bin/core/page/login_page/__init__.py | 0 cgi-bin/core/page/login_page/login_page.html | 29 + cgi-bin/core/page/login_page/login_page.js | 56 + cgi-bin/core/page/login_page/login_page.txt | 33 + .../page/login_page/login_page_static.html | 3 + cgi-bin/getfile.cgi | 82 + cgi-bin/getjsfile.cgi | 73 + cgi-bin/pypi-setup.py | 35 + cgi-bin/webnotes/__init__.py | 228 + cgi-bin/webnotes/auth.py | 424 + cgi-bin/webnotes/db.py | 310 + cgi-bin/webnotes/defs_template.py | 86 + cgi-bin/webnotes/handler.py | 437 + cgi-bin/webnotes/install_lib/__init__.py | 0 cgi-bin/webnotes/install_lib/db_init.py | 284 + cgi-bin/webnotes/install_lib/install.py | 232 + cgi-bin/webnotes/model/__init__.py | 205 + cgi-bin/webnotes/model/code.py | 223 + cgi-bin/webnotes/model/db_schema.py | 430 + cgi-bin/webnotes/model/doc.py | 671 + cgi-bin/webnotes/model/doclist.py | 191 + cgi-bin/webnotes/model/doctype.py | 282 + cgi-bin/webnotes/model/import_docs.py | 415 + cgi-bin/webnotes/model/meta.py | 57 + cgi-bin/webnotes/model/modules.py | 26 + cgi-bin/webnotes/model/triggers.py | 68 + cgi-bin/webnotes/modules/__init__.py | 65 + cgi-bin/webnotes/modules/compress.py | 342 + cgi-bin/webnotes/modules/export_module.py | 237 + cgi-bin/webnotes/modules/import_module.py | 278 + cgi-bin/webnotes/modules/module_manager.py | 187 + cgi-bin/webnotes/modules/patch.py | 36 + cgi-bin/webnotes/multi_tenant/__init__.py | 1 + cgi-bin/webnotes/multi_tenant/query_parser.py | 38 + cgi-bin/webnotes/multi_tenant/setup.py | 19 + cgi-bin/webnotes/profile.py | 239 + cgi-bin/webnotes/session_cache.py | 183 + cgi-bin/webnotes/settings/__init__.py | 0 .../webnotes/settings/account_map_template.py | 10 + cgi-bin/webnotes/utils/__init__.py | 550 + cgi-bin/webnotes/utils/archive.py | 107 + cgi-bin/webnotes/utils/backups.py | 107 + cgi-bin/webnotes/utils/cache.py | 57 + cgi-bin/webnotes/utils/email_lib/__init__.py | 88 + .../webnotes/utils/email_lib/form_email.py | 160 + cgi-bin/webnotes/utils/email_lib/html2text.py | 491 + cgi-bin/webnotes/utils/email_lib/receive.py | 142 + cgi-bin/webnotes/utils/email_lib/send.py | 293 + cgi-bin/webnotes/utils/encrypt.py | 54 + cgi-bin/webnotes/utils/file_manager.py | 202 + cgi-bin/webnotes/utils/jsmin.py | 213 + cgi-bin/webnotes/utils/nestedset.py | 80 + cgi-bin/webnotes/utils/scheduler.py | 166 + cgi-bin/webnotes/utils/sitemap.py | 34 + cgi-bin/webnotes/utils/transfer.py | 300 + cgi-bin/webnotes/utils/webservice.py | 111 + cgi-bin/webnotes/widgets/__init__.py | 0 cgi-bin/webnotes/widgets/auto_master.py | 53 + cgi-bin/webnotes/widgets/event.py | 48 + cgi-bin/webnotes/widgets/follow.py | 134 + cgi-bin/webnotes/widgets/form.py | 490 + cgi-bin/webnotes/widgets/menus.py | 181 + cgi-bin/webnotes/widgets/page.py | 87 + cgi-bin/webnotes/widgets/page_body.py | 240 + cgi-bin/webnotes/widgets/query_builder.py | 333 + cgi-bin/webnotes/widgets/search.py | 101 + cgi-bin/webnotes/widgets/tags.py | 256 + cgi-bin/webnotes/widgets/todo.py | 49 + change_log.txt | 143 + compress.py | 424 + css/autosuggest.css | 91 + css/body.css | 108 + css/bw-icons.css | 250 + css/calendar.css | 171 + css/default.css | 1773 ++ css/dialog.css | 76 + css/doc_column_view.css | 62 + css/forms.css | 222 + css/grid.css | 122 + css/images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes css/images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes css/images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes css/images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-hard_65_ffffff_1x100.png | Bin 0 -> 93 bytes .../ui-bg_highlight-hard_75_dadada_1x100.png | Bin 0 -> 97 bytes .../ui-bg_highlight-hard_75_e6e6e6_1x100.png | Bin 0 -> 94 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes css/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes css/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes css/images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes css/images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes css/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes css/jqplot.css | 169 + css/jquery-ui.css | 383 + css/listing.css | 56 + css/menus.css | 51 + css/messages.css | 59 + css/report.css | 180 + css/sidebar.css | 44 + css/tabs.css | 58 + css/user.css | 1 + css/wntoolbar.css | 47 + data/Framework.sql | 245 + data/GeoIP.dat | Bin 0 -> 1133002 bytes docs/html/.buildinfo | 4 + docs/html/_sources/admin_login.txt | 10 + docs/html/_sources/apps_intro.txt | 98 + docs/html/_sources/auth.txt | 104 + docs/html/_sources/autosuggest.txt | 62 + docs/html/_sources/build_app.txt | 13 + docs/html/_sources/client_side_cookbook.txt | 242 + docs/html/_sources/client_side_script.txt | 85 + docs/html/_sources/client_side_widgets.txt | 17 + docs/html/_sources/code.txt | 68 + docs/html/_sources/concepts.txt | 30 + docs/html/_sources/creating_doctypes.txt | 270 + docs/html/_sources/creating_entities.txt | 15 + docs/html/_sources/creating_pages.txt | 31 + docs/html/_sources/creating_profiles.txt | 26 + docs/html/_sources/creating_reports.txt | 64 + docs/html/_sources/creating_roles.txt | 21 + docs/html/_sources/database_api.txt | 23 + docs/html/_sources/db.txt | 98 + docs/html/_sources/db_schema.txt | 61 + docs/html/_sources/dialog.txt | 86 + docs/html/_sources/doc.txt | 133 + docs/html/_sources/doclist.txt | 52 + docs/html/_sources/doctype.txt | 56 + docs/html/_sources/email_lib.txt | 90 + docs/html/_sources/form_server.txt | 35 + docs/html/_sources/form_widget.txt | 274 + docs/html/_sources/glossary.txt | 105 + docs/html/_sources/index.txt | 41 + docs/html/_sources/intro.txt | 7 + docs/html/_sources/javascript_utils.txt | 370 + docs/html/_sources/listing.txt | 195 + docs/html/_sources/local_data.txt | 45 + docs/html/_sources/menus_server.txt | 10 + docs/html/_sources/module.txt | 17 + docs/html/_sources/navigation.txt | 94 + docs/html/_sources/page_body.txt | 32 + docs/html/_sources/page_cookbook.txt | 4 + docs/html/_sources/page_server.txt | 27 + docs/html/_sources/profile.txt | 77 + docs/html/_sources/report_builder.txt | 248 + docs/html/_sources/report_cookbook.txt | 100 + docs/html/_sources/save_submit.txt | 18 + docs/html/_sources/server_side_api.txt | 15 + docs/html/_sources/server_side_cookbook.txt | 99 + docs/html/_sources/server_side_internals.txt | 17 + docs/html/_sources/server_side_script.txt | 86 + docs/html/_sources/sitemap.txt | 25 + docs/html/_sources/tabbed_page.txt | 48 + docs/html/_sources/tree.txt | 158 + docs/html/_sources/utils_server.txt | 142 + docs/html/_sources/webnotes.txt | 60 + docs/html/_sources/webnotes_intro.txt | 62 + docs/html/_sources/webservice.txt | 34 + docs/html/_sources/what_is_an_app.txt | 18 + docs/html/_sources/writing_scripts.txt | 17 + docs/html/_static/banner300910.gif | Bin 0 -> 8366 bytes docs/html/_static/basic.css | 405 + docs/html/_static/contents.png | Bin 0 -> 202 bytes docs/html/_static/default.css | 339 + docs/html/_static/doctools.js | 232 + docs/html/_static/file.png | Bin 0 -> 392 bytes docs/html/_static/jquery.js | 32 + docs/html/_static/minus.png | Bin 0 -> 199 bytes docs/html/_static/navigation.png | Bin 0 -> 218 bytes docs/html/_static/plus.png | Bin 0 -> 199 bytes docs/html/_static/pygments.css | 61 + docs/html/_static/searchtools.js | 467 + docs/html/_static/sphinxdoc.css | 323 + docs/html/admin_login.html | 120 + docs/html/apps_intro.html | 228 + docs/html/auth.html | 246 + docs/html/autosuggest.html | 187 + docs/html/build_app.html | 201 + docs/html/client_side_cookbook.html | 378 + docs/html/client_side_script.html | 204 + docs/html/client_side_widgets.html | 189 + docs/html/code.html | 198 + docs/html/concepts.html | 152 + docs/html/creating_doctypes.html | 473 + docs/html/creating_entities.html | 128 + docs/html/creating_pages.html | 146 + docs/html/creating_profiles.html | 143 + docs/html/creating_reports.html | 185 + docs/html/creating_roles.html | 139 + docs/html/database_api.html | 143 + docs/html/db.html | 244 + docs/html/db_schema.html | 192 + docs/html/dialog.html | 217 + docs/html/doc.html | 284 + docs/html/doclist.html | 181 + docs/html/doctype.html | 191 + docs/html/email_lib.html | 223 + docs/html/form_server.html | 153 + docs/html/form_widget.html | 459 + docs/html/genindex.html | 704 + docs/html/glossary.html | 200 + docs/html/index.html | 394 + docs/html/intro.html | 126 + docs/html/javascript_utils.html | 571 + docs/html/listing.html | 336 + docs/html/local_data.html | 146 + docs/html/menus_server.html | 124 + docs/html/modindex.html | 186 + docs/html/module.html | 134 + docs/html/navigation.html | 235 + docs/html/objects.inv | 381 + docs/html/page_body.html | 144 + docs/html/page_cookbook.html | 119 + docs/html/page_server.html | 154 + docs/html/profile.html | 214 + docs/html/report_builder.html | 410 + docs/html/report_cookbook.html | 236 + docs/html/save_submit.html | 128 + docs/html/search.html | 98 + docs/html/searchindex.js | 1 + docs/html/server_side_api.html | 189 + docs/html/server_side_cookbook.html | 217 + docs/html/server_side_internals.html | 156 + docs/html/server_side_script.html | 205 + docs/html/sitemap.html | 140 + docs/html/tabbed_page.html | 176 + docs/html/tree.html | 298 + docs/html/utils_server.html | 291 + docs/html/webnotes.html | 197 + docs/html/webnotes_intro.html | 196 + docs/html/webservice.html | 157 + docs/html/what_is_an_app.html | 133 + docs/html/writing_scripts.html | 170 + images/icons/Accounts.gif | Bin 0 -> 1042 bytes images/icons/Accounts.png | Bin 0 -> 3935 bytes images/icons/Analysis.gif | Bin 0 -> 1017 bytes images/icons/Analysis.png | Bin 0 -> 3772 bytes images/icons/Buying.gif | Bin 0 -> 1016 bytes images/icons/Buying.png | Bin 0 -> 3808 bytes images/icons/HR.gif | Bin 0 -> 1012 bytes images/icons/HR.png | Bin 0 -> 3751 bytes images/icons/Home.gif | Bin 0 -> 1046 bytes images/icons/Home.png | Bin 0 -> 3917 bytes images/icons/Maintenance.gif | Bin 0 -> 617 bytes images/icons/Maintenance.png | Bin 0 -> 4045 bytes images/icons/Production.gif | Bin 0 -> 1024 bytes images/icons/Production.png | Bin 0 -> 3698 bytes images/icons/Projects.gif | Bin 0 -> 1001 bytes images/icons/Projects.png | Bin 0 -> 3822 bytes images/icons/Selling.gif | Bin 0 -> 994 bytes images/icons/Selling.png | Bin 0 -> 3667 bytes images/icons/Setup.gif | Bin 0 -> 528 bytes images/icons/Setup.png | Bin 0 -> 3675 bytes images/icons/Stock.gif | Bin 0 -> 1030 bytes images/icons/Stock.png | Bin 0 -> 3635 bytes images/icons/accept.gif | Bin 0 -> 1024 bytes images/icons/accept.png | Bin 0 -> 781 bytes images/icons/add.gif | Bin 0 -> 1010 bytes images/icons/add.png | Bin 0 -> 733 bytes images/icons/anchor.png | Bin 0 -> 523 bytes images/icons/application.gif | Bin 0 -> 600 bytes images/icons/application.png | Bin 0 -> 464 bytes images/icons/application_add.png | Bin 0 -> 619 bytes images/icons/application_cascade.png | Bin 0 -> 524 bytes images/icons/application_delete.png | Bin 0 -> 610 bytes images/icons/application_double.png | Bin 0 -> 533 bytes images/icons/application_form.png | Bin 0 -> 467 bytes images/icons/application_go.png | Bin 0 -> 634 bytes images/icons/application_side_list.png | Bin 0 -> 510 bytes images/icons/application_side_tree.png | Bin 0 -> 483 bytes images/icons/application_split.png | Bin 0 -> 520 bytes images/icons/application_tile_horizontal.png | Bin 0 -> 432 bytes images/icons/application_tile_vertical.png | Bin 0 -> 492 bytes images/icons/application_view_columns.png | Bin 0 -> 493 bytes images/icons/application_view_detail.png | Bin 0 -> 576 bytes images/icons/application_view_tile.png | Bin 0 -> 465 bytes images/icons/application_xp.png | Bin 0 -> 426 bytes images/icons/application_xp_terminal.png | Bin 0 -> 507 bytes images/icons/arrow_branch.png | Bin 0 -> 582 bytes images/icons/arrow_divide.png | Bin 0 -> 677 bytes images/icons/arrow_down.gif | Bin 0 -> 312 bytes images/icons/arrow_down.png | Bin 0 -> 379 bytes images/icons/arrow_in.png | Bin 0 -> 600 bytes images/icons/arrow_inout.png | Bin 0 -> 551 bytes images/icons/arrow_join.png | Bin 0 -> 626 bytes images/icons/arrow_left.gif | Bin 0 -> 306 bytes images/icons/arrow_left.png | Bin 0 -> 345 bytes images/icons/arrow_merge.png | Bin 0 -> 484 bytes images/icons/arrow_out.png | Bin 0 -> 594 bytes images/icons/arrow_redo.png | Bin 0 -> 625 bytes images/icons/arrow_refresh.png | Bin 0 -> 685 bytes images/icons/arrow_refresh_small.png | Bin 0 -> 506 bytes images/icons/arrow_right.gif | Bin 0 -> 307 bytes images/icons/arrow_right.png | Bin 0 -> 349 bytes images/icons/arrow_rotate_anticlockwise.png | Bin 0 -> 608 bytes images/icons/arrow_rotate_clockwise.png | Bin 0 -> 602 bytes images/icons/arrow_switch.png | Bin 0 -> 683 bytes images/icons/arrow_turn_left.png | Bin 0 -> 516 bytes images/icons/arrow_turn_right.png | Bin 0 -> 489 bytes images/icons/arrow_undo.png | Bin 0 -> 631 bytes images/icons/arrow_up.gif | Bin 0 -> 311 bytes images/icons/arrow_up.png | Bin 0 -> 372 bytes images/icons/asterisk_orange.png | Bin 0 -> 760 bytes images/icons/asterisk_yellow.png | Bin 0 -> 743 bytes images/icons/attach.png | Bin 0 -> 391 bytes images/icons/award_star_add.png | Bin 0 -> 853 bytes images/icons/award_star_bronze_1.png | Bin 0 -> 733 bytes images/icons/award_star_bronze_2.png | Bin 0 -> 755 bytes images/icons/award_star_bronze_3.png | Bin 0 -> 754 bytes images/icons/award_star_delete.png | Bin 0 -> 849 bytes images/icons/award_star_gold_1.png | Bin 0 -> 753 bytes images/icons/award_star_gold_2.png | Bin 0 -> 770 bytes images/icons/award_star_gold_3.png | Bin 0 -> 781 bytes images/icons/award_star_silver_1.png | Bin 0 -> 714 bytes images/icons/award_star_silver_2.png | Bin 0 -> 734 bytes images/icons/award_star_silver_3.png | Bin 0 -> 738 bytes images/icons/basket.png | Bin 0 -> 669 bytes images/icons/bell.png | Bin 0 -> 789 bytes images/icons/bin.png | Bin 0 -> 476 bytes images/icons/bin_closed.png | Bin 0 -> 363 bytes images/icons/bin_empty.png | Bin 0 -> 475 bytes images/icons/bomb.png | Bin 0 -> 793 bytes images/icons/book.png | Bin 0 -> 593 bytes images/icons/book_add.png | Bin 0 -> 714 bytes images/icons/book_addresses.png | Bin 0 -> 770 bytes images/icons/box.png | Bin 0 -> 555 bytes images/icons/brick.png | Bin 0 -> 452 bytes images/icons/bricks.png | Bin 0 -> 825 bytes images/icons/briefcase.png | Bin 0 -> 793 bytes images/icons/bug.png | Bin 0 -> 774 bytes images/icons/building.png | Bin 0 -> 556 bytes images/icons/bullet_add.png | Bin 0 -> 286 bytes images/icons/bullet_arrow_bottom.png | Bin 0 -> 229 bytes images/icons/bullet_arrow_down.png | Bin 0 -> 201 bytes images/icons/bullet_arrow_top.png | Bin 0 -> 230 bytes images/icons/bullet_arrow_up.png | Bin 0 -> 201 bytes images/icons/bullet_black.png | Bin 0 -> 211 bytes images/icons/bullet_blue.png | Bin 0 -> 289 bytes images/icons/bullet_delete.png | Bin 0 -> 308 bytes images/icons/bullet_green.png | Bin 0 -> 295 bytes images/icons/bullet_key.png | Bin 0 -> 436 bytes images/icons/bullet_orange.png | Bin 0 -> 283 bytes images/icons/bullet_picture.png | Bin 0 -> 470 bytes images/icons/bullet_pink.png | Bin 0 -> 286 bytes images/icons/bullet_purple.png | Bin 0 -> 294 bytes images/icons/bullet_red.png | Bin 0 -> 287 bytes images/icons/bullet_star.png | Bin 0 -> 331 bytes images/icons/bullet_toggle_minus.png | Bin 0 -> 207 bytes images/icons/bullet_toggle_plus.png | Bin 0 -> 209 bytes images/icons/bullet_white.png | Bin 0 -> 201 bytes images/icons/bullet_wrench.png | Bin 0 -> 448 bytes images/icons/bullet_yellow.png | Bin 0 -> 287 bytes images/icons/cake.png | Bin 0 -> 676 bytes images/icons/calculator.gif | Bin 0 -> 597 bytes images/icons/calculator.png | Bin 0 -> 543 bytes images/icons/calendar.gif | Bin 0 -> 1037 bytes images/icons/calendar.png | Bin 0 -> 675 bytes images/icons/calendar_view_day.png | Bin 0 -> 572 bytes images/icons/calendar_view_month.png | Bin 0 -> 595 bytes images/icons/calendar_view_week.png | Bin 0 -> 480 bytes images/icons/camera.png | Bin 0 -> 665 bytes images/icons/cancel.gif | Bin 0 -> 607 bytes images/icons/cancel.png | Bin 0 -> 587 bytes images/icons/car.png | Bin 0 -> 610 bytes images/icons/car_add.png | Bin 0 -> 677 bytes images/icons/car_delete.png | Bin 0 -> 689 bytes images/icons/cart.png | Bin 0 -> 421 bytes images/icons/cart_add.png | Bin 0 -> 711 bytes images/icons/cart_delete.png | Bin 0 -> 742 bytes images/icons/cart_edit.png | Bin 0 -> 789 bytes images/icons/cart_error.png | Bin 0 -> 790 bytes images/icons/cart_go.png | Bin 0 -> 763 bytes images/icons/cart_put.png | Bin 0 -> 763 bytes images/icons/cart_remove.png | Bin 0 -> 769 bytes images/icons/cd.png | Bin 0 -> 673 bytes images/icons/chart_bar.gif | Bin 0 -> 1015 bytes images/icons/chart_bar.png | Bin 0 -> 541 bytes images/icons/chart_curve.png | Bin 0 -> 710 bytes images/icons/chart_line.png | Bin 0 -> 526 bytes images/icons/chart_organisation.png | Bin 0 -> 444 bytes images/icons/chart_pie.png | Bin 0 -> 918 bytes images/icons/clock.png | Bin 0 -> 882 bytes images/icons/clock_play.png | Bin 0 -> 943 bytes images/icons/clock_red.png | Bin 0 -> 889 bytes images/icons/clock_stop.png | Bin 0 -> 922 bytes images/icons/close.gif | Bin 0 -> 85 bytes images/icons/cog.png | Bin 0 -> 512 bytes images/icons/coins.png | Bin 0 -> 732 bytes images/icons/coins_add.png | Bin 0 -> 789 bytes images/icons/coins_delete.png | Bin 0 -> 775 bytes images/icons/color_swatch.png | Bin 0 -> 209 bytes images/icons/color_wheel.png | Bin 0 -> 892 bytes images/icons/comment.png | Bin 0 -> 413 bytes images/icons/comment_add.png | Bin 0 -> 530 bytes images/icons/comment_delete.png | Bin 0 -> 548 bytes images/icons/comment_edit.png | Bin 0 -> 644 bytes images/icons/comments.gif | Bin 0 -> 89 bytes images/icons/comments.png | Bin 0 -> 557 bytes images/icons/comments_add.png | Bin 0 -> 648 bytes images/icons/comments_delete.png | Bin 0 -> 670 bytes images/icons/compress.png | Bin 0 -> 766 bytes images/icons/computer.png | Bin 0 -> 667 bytes images/icons/connect.png | Bin 0 -> 748 bytes images/icons/contrast.png | Bin 0 -> 434 bytes images/icons/control_eject.png | Bin 0 -> 603 bytes images/icons/control_eject_blue.png | Bin 0 -> 727 bytes images/icons/control_end.png | Bin 0 -> 621 bytes images/icons/control_end_blue.png | Bin 0 -> 737 bytes images/icons/control_equalizer.png | Bin 0 -> 432 bytes images/icons/control_equalizer_blue.png | Bin 0 -> 764 bytes images/icons/control_fastforward.png | Bin 0 -> 607 bytes images/icons/control_fastforward_blue.png | Bin 0 -> 736 bytes images/icons/control_pause.png | Bin 0 -> 598 bytes images/icons/control_pause_blue.png | Bin 0 -> 721 bytes images/icons/control_play.png | Bin 0 -> 592 bytes images/icons/control_play_blue.png | Bin 0 -> 717 bytes images/icons/control_repeat.png | Bin 0 -> 422 bytes images/icons/control_repeat_blue.png | Bin 0 -> 750 bytes images/icons/control_rewind.png | Bin 0 -> 614 bytes images/icons/control_rewind_blue.png | Bin 0 -> 745 bytes images/icons/control_start.png | Bin 0 -> 604 bytes images/icons/control_start_blue.png | Bin 0 -> 720 bytes images/icons/controller.png | Bin 0 -> 666 bytes images/icons/creditcards.png | Bin 0 -> 693 bytes images/icons/cross.png | Bin 0 -> 655 bytes images/icons/css.png | Bin 0 -> 524 bytes images/icons/cup.png | Bin 0 -> 633 bytes images/icons/cursor.png | Bin 0 -> 354 bytes images/icons/cut.png | Bin 0 -> 648 bytes images/icons/cut_red.png | Bin 0 -> 650 bytes images/icons/database.png | Bin 0 -> 390 bytes images/icons/date.png | Bin 0 -> 626 bytes images/icons/date_magnify.png | Bin 0 -> 711 bytes images/icons/date_next.png | Bin 0 -> 688 bytes images/icons/date_previous.png | Bin 0 -> 720 bytes images/icons/delete.png | Bin 0 -> 715 bytes images/icons/disconnect.png | Bin 0 -> 796 bytes images/icons/disk.gif | Bin 0 -> 1061 bytes images/icons/disk.png | Bin 0 -> 620 bytes images/icons/disk_multiple.png | Bin 0 -> 691 bytes images/icons/door.png | Bin 0 -> 412 bytes images/icons/door_in.png | Bin 0 -> 693 bytes images/icons/door_open.png | Bin 0 -> 508 bytes images/icons/door_out.png | Bin 0 -> 688 bytes images/icons/down-arrow.gif | Bin 0 -> 189 bytes images/icons/drink.png | Bin 0 -> 692 bytes images/icons/drink_empty.png | Bin 0 -> 433 bytes images/icons/drive.png | Bin 0 -> 346 bytes images/icons/dvd.png | Bin 0 -> 764 bytes images/icons/email.gif | Bin 0 -> 1014 bytes images/icons/email.png | Bin 0 -> 641 bytes images/icons/email_add.png | Bin 0 -> 761 bytes images/icons/email_attach.png | Bin 0 -> 793 bytes images/icons/email_delete.png | Bin 0 -> 756 bytes images/icons/email_edit.png | Bin 0 -> 756 bytes images/icons/email_error.png | Bin 0 -> 792 bytes images/icons/email_go.png | Bin 0 -> 754 bytes images/icons/email_link.png | Bin 0 -> 821 bytes images/icons/email_open.png | Bin 0 -> 783 bytes images/icons/email_open_image.png | Bin 0 -> 811 bytes images/icons/emoticon_evilgrin.png | Bin 0 -> 727 bytes images/icons/emoticon_grin.png | Bin 0 -> 714 bytes images/icons/emoticon_happy.png | Bin 0 -> 731 bytes images/icons/emoticon_smile.gif | Bin 0 -> 1025 bytes images/icons/emoticon_smile.png | Bin 0 -> 725 bytes images/icons/emoticon_surprised.png | Bin 0 -> 741 bytes images/icons/emoticon_tongue.png | Bin 0 -> 727 bytes images/icons/emoticon_unhappy.png | Bin 0 -> 723 bytes images/icons/emoticon_waii.png | Bin 0 -> 737 bytes images/icons/emoticon_wink.png | Bin 0 -> 712 bytes images/icons/error.gif | Bin 0 -> 994 bytes images/icons/error.png | Bin 0 -> 666 bytes images/icons/error_add.png | Bin 0 -> 710 bytes images/icons/error_delete.png | Bin 0 -> 729 bytes images/icons/error_go.png | Bin 0 -> 734 bytes images/icons/exclamation.png | Bin 0 -> 701 bytes images/icons/eye.png | Bin 0 -> 750 bytes images/icons/feed.png | Bin 0 -> 691 bytes images/icons/female.png | Bin 0 -> 590 bytes images/icons/film.png | Bin 0 -> 653 bytes images/icons/find.png | Bin 0 -> 659 bytes images/icons/flag_blue.png | Bin 0 -> 671 bytes images/icons/flag_green.png | Bin 0 -> 672 bytes images/icons/flag_orange.png | Bin 0 -> 669 bytes images/icons/flag_pink.png | Bin 0 -> 651 bytes images/icons/flag_purple.png | Bin 0 -> 656 bytes images/icons/flag_red.png | Bin 0 -> 665 bytes images/icons/flag_yellow.png | Bin 0 -> 671 bytes images/icons/folder.gif | Bin 0 -> 996 bytes images/icons/folder.png | Bin 0 -> 537 bytes images/icons/folder_delete.png | Bin 0 -> 666 bytes images/icons/folder_error.png | Bin 0 -> 727 bytes images/icons/folder_link.png | Bin 0 -> 785 bytes images/icons/folder_page_white.png | Bin 0 -> 639 bytes images/icons/folder_star.png | Bin 0 -> 755 bytes images/icons/folder_user.png | Bin 0 -> 730 bytes images/icons/font.png | Bin 0 -> 567 bytes images/icons/font_add.png | Bin 0 -> 634 bytes images/icons/font_delete.png | Bin 0 -> 661 bytes images/icons/font_go.png | Bin 0 -> 700 bytes images/icons/group.gif | Bin 0 -> 1014 bytes images/icons/group.png | Bin 0 -> 753 bytes images/icons/heart.png | Bin 0 -> 749 bytes images/icons/heart_add.png | Bin 0 -> 820 bytes images/icons/heart_delete.png | Bin 0 -> 823 bytes images/icons/help.gif | Bin 0 -> 1024 bytes images/icons/help.png | Bin 0 -> 786 bytes images/icons/hourglass.png | Bin 0 -> 744 bytes images/icons/house.gif | Bin 0 -> 1027 bytes images/icons/house.png | Bin 0 -> 806 bytes images/icons/house_go.png | Bin 0 -> 861 bytes images/icons/house_link.png | Bin 0 -> 868 bytes images/icons/html.png | Bin 0 -> 578 bytes images/icons/icon-recommend.gif | Bin 0 -> 85 bytes images/icons/icons.png | Bin 0 -> 53108 bytes images/icons/image.png | Bin 0 -> 516 bytes images/icons/image_add.png | Bin 0 -> 653 bytes images/icons/image_delete.png | Bin 0 -> 653 bytes images/icons/image_edit.png | Bin 0 -> 783 bytes images/icons/image_link.png | Bin 0 -> 773 bytes images/icons/images.png | Bin 0 -> 661 bytes images/icons/information.png | Bin 0 -> 778 bytes images/icons/ipod.png | Bin 0 -> 463 bytes images/icons/joystick.png | Bin 0 -> 559 bytes images/icons/key.png | Bin 0 -> 612 bytes images/icons/key_add.png | Bin 0 -> 703 bytes images/icons/key_delete.png | Bin 0 -> 724 bytes images/icons/key_go.png | Bin 0 -> 744 bytes images/icons/keyboard.png | Bin 0 -> 570 bytes images/icons/layers.png | Bin 0 -> 597 bytes images/icons/layout.png | Bin 0 -> 480 bytes images/icons/layout_add.png | Bin 0 -> 577 bytes images/icons/layout_content.png | Bin 0 -> 519 bytes images/icons/lightbulb.gif | Bin 0 -> 1022 bytes images/icons/lightbulb.png | Bin 0 -> 782 bytes images/icons/lightbulb_off.png | Bin 0 -> 700 bytes images/icons/lightning.png | Bin 0 -> 634 bytes images/icons/link.png | Bin 0 -> 343 bytes images/icons/lock.png | Bin 0 -> 749 bytes images/icons/lock_open.png | Bin 0 -> 727 bytes images/icons/lorry.png | Bin 0 -> 582 bytes images/icons/magifier_zoom_out.png | Bin 0 -> 657 bytes images/icons/magnifier.gif | Bin 0 -> 568 bytes images/icons/magnifier.png | Bin 0 -> 615 bytes images/icons/magnifier_zoom_in.png | Bin 0 -> 680 bytes images/icons/male.png | Bin 0 -> 629 bytes images/icons/map.png | Bin 0 -> 804 bytes images/icons/medal_bronze_1.png | Bin 0 -> 640 bytes images/icons/medal_bronze_2.png | Bin 0 -> 654 bytes images/icons/medal_bronze_3.png | Bin 0 -> 646 bytes images/icons/medal_bronze_add.png | Bin 0 -> 747 bytes images/icons/medal_bronze_delete.png | Bin 0 -> 730 bytes images/icons/medal_gold_1.png | Bin 0 -> 629 bytes images/icons/medal_gold_2.png | Bin 0 -> 641 bytes images/icons/medal_gold_3.png | Bin 0 -> 634 bytes images/icons/medal_gold_add.png | Bin 0 -> 733 bytes images/icons/medal_gold_delete.png | Bin 0 -> 724 bytes images/icons/medal_silver_1.png | Bin 0 -> 589 bytes images/icons/medal_silver_2.png | Bin 0 -> 600 bytes images/icons/medal_silver_3.png | Bin 0 -> 597 bytes images/icons/medal_silver_add.png | Bin 0 -> 727 bytes images/icons/medal_silver_delete.png | Bin 0 -> 714 bytes images/icons/minus.gif | Bin 0 -> 82 bytes images/icons/money.png | Bin 0 -> 738 bytes images/icons/money_add.png | Bin 0 -> 784 bytes images/icons/money_delete.png | Bin 0 -> 806 bytes images/icons/money_dollar.png | Bin 0 -> 630 bytes images/icons/money_euro.png | Bin 0 -> 605 bytes images/icons/money_pound.png | Bin 0 -> 565 bytes images/icons/money_yen.png | Bin 0 -> 562 bytes images/icons/monitor.png | Bin 0 -> 612 bytes images/icons/mouse.png | Bin 0 -> 634 bytes images/icons/mouse_add.png | Bin 0 -> 729 bytes images/icons/mouse_delete.png | Bin 0 -> 741 bytes images/icons/mouse_error.png | Bin 0 -> 790 bytes images/icons/music.png | Bin 0 -> 385 bytes images/icons/new.png | Bin 0 -> 378 bytes images/icons/newspaper.png | Bin 0 -> 658 bytes images/icons/note.gif | Bin 0 -> 588 bytes images/icons/note.png | Bin 0 -> 500 bytes images/icons/overlays.png | Bin 0 -> 716 bytes images/icons/package.png | Bin 0 -> 853 bytes images/icons/page.gif | Bin 0 -> 1068 bytes images/icons/page.png | Bin 0 -> 635 bytes images/icons/page_add.gif | Bin 0 -> 1070 bytes images/icons/page_add.png | Bin 0 -> 739 bytes images/icons/page_attach.png | Bin 0 -> 794 bytes images/icons/page_code.png | Bin 0 -> 818 bytes images/icons/page_copy.gif | Bin 0 -> 1041 bytes images/icons/page_copy.png | Bin 0 -> 663 bytes images/icons/page_delete.png | Bin 0 -> 740 bytes images/icons/page_edit.png | Bin 0 -> 807 bytes images/icons/page_error.png | Bin 0 -> 793 bytes images/icons/page_excel.gif | Bin 0 -> 1060 bytes images/icons/page_excel.png | Bin 0 -> 817 bytes images/icons/page_find.png | Bin 0 -> 879 bytes images/icons/page_gear.png | Bin 0 -> 833 bytes images/icons/page_go.png | Bin 0 -> 779 bytes images/icons/page_green.png | Bin 0 -> 621 bytes images/icons/page_key.png | Bin 0 -> 801 bytes images/icons/page_lightning.png | Bin 0 -> 839 bytes images/icons/page_link.png | Bin 0 -> 830 bytes images/icons/page_paintbrush.png | Bin 0 -> 813 bytes images/icons/page_paste.png | Bin 0 -> 703 bytes images/icons/page_red.png | Bin 0 -> 641 bytes images/icons/page_refresh.gif | Bin 0 -> 1076 bytes images/icons/page_refresh.png | Bin 0 -> 858 bytes images/icons/page_save.png | Bin 0 -> 774 bytes images/icons/page_white.png | Bin 0 -> 294 bytes images/icons/page_white_acrobat.png | Bin 0 -> 591 bytes images/icons/page_white_actionscript.png | Bin 0 -> 664 bytes images/icons/page_white_add.png | Bin 0 -> 512 bytes images/icons/page_white_c.png | Bin 0 -> 587 bytes images/icons/page_white_camera.png | Bin 0 -> 656 bytes images/icons/page_white_cd.png | Bin 0 -> 666 bytes images/icons/page_white_code.png | Bin 0 -> 603 bytes images/icons/page_white_code_red.png | Bin 0 -> 587 bytes images/icons/page_white_copy.png | Bin 0 -> 309 bytes images/icons/page_white_csharp.png | Bin 0 -> 700 bytes images/icons/page_white_cup.png | Bin 0 -> 639 bytes images/icons/page_white_delete.png | Bin 0 -> 536 bytes images/icons/page_white_dvd.png | Bin 0 -> 638 bytes images/icons/page_white_error.png | Bin 0 -> 623 bytes images/icons/page_white_find.png | Bin 0 -> 676 bytes images/icons/page_white_flash.png | Bin 0 -> 582 bytes images/icons/page_white_freehand.png | Bin 0 -> 639 bytes images/icons/page_white_gear.png | Bin 0 -> 402 bytes images/icons/page_white_get.png | Bin 0 -> 516 bytes images/icons/page_white_go.png | Bin 0 -> 612 bytes images/icons/page_white_h.png | Bin 0 -> 603 bytes images/icons/page_white_horizontal.png | Bin 0 -> 296 bytes images/icons/page_white_key.png | Bin 0 -> 616 bytes images/icons/page_white_lightning.png | Bin 0 -> 669 bytes images/icons/page_white_link.png | Bin 0 -> 614 bytes images/icons/page_white_magnify.png | Bin 0 -> 554 bytes images/icons/page_white_medal.png | Bin 0 -> 706 bytes images/icons/page_white_office.png | Bin 0 -> 779 bytes images/icons/page_white_paint.png | Bin 0 -> 688 bytes images/icons/page_white_paintbrush.png | Bin 0 -> 618 bytes images/icons/page_white_paste.png | Bin 0 -> 620 bytes images/icons/page_white_put.png | Bin 0 -> 523 bytes images/icons/page_white_stack.png | Bin 0 -> 317 bytes images/icons/page_white_star.png | Bin 0 -> 565 bytes images/icons/page_white_text.png | Bin 0 -> 342 bytes images/icons/page_white_text_width.png | Bin 0 -> 315 bytes images/icons/page_white_tux.png | Bin 0 -> 668 bytes images/icons/page_white_vector.png | Bin 0 -> 644 bytes images/icons/page_white_visualstudio.png | Bin 0 -> 702 bytes images/icons/page_white_width.png | Bin 0 -> 309 bytes images/icons/page_white_word.png | Bin 0 -> 651 bytes images/icons/page_white_world.png | Bin 0 -> 734 bytes images/icons/page_white_wrench.png | Bin 0 -> 613 bytes images/icons/page_white_zip.png | Bin 0 -> 386 bytes images/icons/page_word.png | Bin 0 -> 777 bytes images/icons/page_world.png | Bin 0 -> 903 bytes images/icons/paintbrush.png | Bin 0 -> 548 bytes images/icons/paintcan.png | Bin 0 -> 707 bytes images/icons/palette.png | Bin 0 -> 856 bytes images/icons/paperclip.gif | Bin 0 -> 384 bytes images/icons/paste_plain.png | Bin 0 -> 605 bytes images/icons/pencil.png | Bin 0 -> 450 bytes images/icons/phone.png | Bin 0 -> 488 bytes images/icons/phone_sound.png | Bin 0 -> 703 bytes images/icons/photo.png | Bin 0 -> 589 bytes images/icons/photos.png | Bin 0 -> 647 bytes images/icons/picture.png | Bin 0 -> 606 bytes images/icons/pictures.png | Bin 0 -> 704 bytes images/icons/pilcrow.png | Bin 0 -> 361 bytes images/icons/pill.png | Bin 0 -> 719 bytes images/icons/plugin.png | Bin 0 -> 591 bytes images/icons/plus.gif | Bin 0 -> 85 bytes images/icons/printer.gif | Bin 0 -> 1035 bytes images/icons/printer.png | Bin 0 -> 731 bytes images/icons/printer_error.png | Bin 0 -> 854 bytes images/icons/question.png | Bin 0 -> 360 bytes images/icons/rainbow.png | Bin 0 -> 655 bytes images/icons/report.png | Bin 0 -> 649 bytes images/icons/resultset_first.gif | Bin 0 -> 553 bytes images/icons/resultset_first.png | Bin 0 -> 522 bytes images/icons/resultset_last.gif | Bin 0 -> 553 bytes images/icons/resultset_last.png | Bin 0 -> 524 bytes images/icons/resultset_next.gif | Bin 0 -> 303 bytes images/icons/resultset_next.png | Bin 0 -> 395 bytes images/icons/resultset_previous.gif | Bin 0 -> 304 bytes images/icons/resultset_previous.png | Bin 0 -> 389 bytes images/icons/rosette.png | Bin 0 -> 673 bytes images/icons/rss.png | Bin 0 -> 530 bytes images/icons/script.png | Bin 0 -> 748 bytes images/icons/server.png | Bin 0 -> 530 bytes images/icons/shading.png | Bin 0 -> 225 bytes images/icons/shield.png | Bin 0 -> 702 bytes images/icons/sitemap.png | Bin 0 -> 278 bytes images/icons/sitemap_color.png | Bin 0 -> 406 bytes images/icons/sort_asc.gif | Bin 0 -> 335 bytes images/icons/sort_desc.gif | Bin 0 -> 327 bytes images/icons/sound.png | Bin 0 -> 610 bytes images/icons/sound_add.png | Bin 0 -> 684 bytes images/icons/sound_delete.png | Bin 0 -> 711 bytes images/icons/sound_low.png | Bin 0 -> 524 bytes images/icons/sound_mute.png | Bin 0 -> 474 bytes images/icons/sound_none.png | Bin 0 -> 417 bytes images/icons/spellcheck.png | Bin 0 -> 603 bytes images/icons/sport_8ball.png | Bin 0 -> 490 bytes images/icons/sport_basketball.png | Bin 0 -> 977 bytes images/icons/sport_football.png | Bin 0 -> 875 bytes images/icons/sport_golf.png | Bin 0 -> 504 bytes images/icons/sport_raquet.png | Bin 0 -> 719 bytes images/icons/sport_shuttlecock.png | Bin 0 -> 683 bytes images/icons/sport_soccer.png | Bin 0 -> 517 bytes images/icons/sport_tennis.png | Bin 0 -> 884 bytes images/icons/star.gif | Bin 0 -> 994 bytes images/icons/star.png | Bin 0 -> 670 bytes images/icons/status_away.png | Bin 0 -> 794 bytes images/icons/status_busy.png | Bin 0 -> 751 bytes images/icons/status_offline.png | Bin 0 -> 422 bytes images/icons/status_online.png | Bin 0 -> 722 bytes images/icons/stop.png | Bin 0 -> 700 bytes images/icons/sum.png | Bin 0 -> 289 bytes images/icons/table.gif | Bin 0 -> 600 bytes images/icons/table.png | Bin 0 -> 566 bytes images/icons/table_edit.png | Bin 0 -> 744 bytes images/icons/table_row_delete.gif | Bin 0 -> 607 bytes images/icons/table_row_delete.png | Bin 0 -> 629 bytes images/icons/table_row_insert.gif | Bin 0 -> 610 bytes images/icons/table_row_insert.png | Bin 0 -> 641 bytes images/icons/table_save.png | Bin 0 -> 723 bytes images/icons/table_sort.png | Bin 0 -> 678 bytes images/icons/tag.png | Bin 0 -> 389 bytes images/icons/tag_blue.png | Bin 0 -> 586 bytes images/icons/tag_green.png | Bin 0 -> 613 bytes images/icons/tag_orange.png | Bin 0 -> 586 bytes images/icons/tag_pink.png | Bin 0 -> 579 bytes images/icons/tag_purple.png | Bin 0 -> 599 bytes images/icons/tag_red.png | Bin 0 -> 592 bytes images/icons/tag_yellow.png | Bin 0 -> 586 bytes images/icons/telephone.png | Bin 0 -> 791 bytes images/icons/television.png | Bin 0 -> 696 bytes images/icons/television_add.png | Bin 0 -> 809 bytes images/icons/television_delete.png | Bin 0 -> 810 bytes images/icons/text_uppercase.png | Bin 0 -> 747 bytes images/icons/textfield.png | Bin 0 -> 153 bytes images/icons/thumb_down.png | Bin 0 -> 601 bytes images/icons/thumb_up.png | Bin 0 -> 619 bytes images/icons/tick.png | Bin 0 -> 537 bytes images/icons/time.png | Bin 0 -> 793 bytes images/icons/timeline_marker.png | Bin 0 -> 327 bytes images/icons/transmit.png | Bin 0 -> 749 bytes images/icons/tux.png | Bin 0 -> 696 bytes images/icons/user.gif | Bin 0 -> 1001 bytes images/icons/user.png | Bin 0 -> 741 bytes images/icons/user_add.png | Bin 0 -> 746 bytes images/icons/user_comment.png | Bin 0 -> 743 bytes images/icons/user_delete.png | Bin 0 -> 767 bytes images/icons/user_edit.png | Bin 0 -> 833 bytes images/icons/user_female.png | Bin 0 -> 663 bytes images/icons/user_go.png | Bin 0 -> 793 bytes images/icons/user_gray.png | Bin 0 -> 706 bytes images/icons/user_green.png | Bin 0 -> 722 bytes images/icons/user_orange.png | Bin 0 -> 723 bytes images/icons/user_red.png | Bin 0 -> 717 bytes images/icons/user_suit.png | Bin 0 -> 748 bytes images/icons/v_sprite.gif | Bin 0 -> 67844 bytes images/icons/vcard.png | Bin 0 -> 533 bytes images/icons/vcard_add.png | Bin 0 -> 661 bytes images/icons/vcard_delete.png | Bin 0 -> 651 bytes images/icons/vcard_edit.png | Bin 0 -> 775 bytes images/icons/vector.png | Bin 0 -> 481 bytes images/icons/vector_add.png | Bin 0 -> 616 bytes images/icons/vector_delete.png | Bin 0 -> 635 bytes images/icons/wand.png | Bin 0 -> 570 bytes images/icons/weather_clouds.png | Bin 0 -> 581 bytes images/icons/weather_cloudy.png | Bin 0 -> 694 bytes images/icons/weather_lightning.png | Bin 0 -> 641 bytes images/icons/weather_rain.png | Bin 0 -> 626 bytes images/icons/weather_snow.png | Bin 0 -> 341 bytes images/icons/weather_sun.png | Bin 0 -> 623 bytes images/icons/webcam.png | Bin 0 -> 728 bytes images/icons/wntoolbar-icons.png | Bin 0 -> 2762 bytes images/icons/world.png | Bin 0 -> 923 bytes images/icons/world_link.png | Bin 0 -> 957 bytes images/icons/wrench.gif | Bin 0 -> 571 bytes images/icons/wrench.png | Bin 0 -> 610 bytes images/icons/wrench_orange.png | Bin 0 -> 584 bytes images/icons/zoom.png | Bin 0 -> 692 bytes images/icons/zoom_in.png | Bin 0 -> 725 bytes images/icons/zoom_out.png | Bin 0 -> 708 bytes images/ui/blue-grad-1.gif | Bin 0 -> 264 bytes images/ui/button-load.gif | Bin 0 -> 723 bytes images/ui/checked_box.gif | Bin 0 -> 928 bytes images/ui/circle-cutout.gif | Bin 0 -> 68 bytes images/ui/down-arrow.gif | Bin 0 -> 189 bytes images/ui/down-arrow1.gif | Bin 0 -> 110 bytes images/ui/loading.gif | Bin 0 -> 1737 bytes images/ui/loading_startup.gif | Bin 0 -> 439 bytes images/ui/next_pointer.gif | Bin 0 -> 165 bytes images/ui/no_img/no_img_f.gif | Bin 0 -> 2662 bytes images/ui/no_img/no_img_m.gif | Bin 0 -> 1996 bytes images/ui/plain_box.gif | Bin 0 -> 100 bytes images/ui/prev_pointer.gif | Bin 0 -> 114 bytes images/ui/rc/comment_top.gif | Bin 0 -> 188 bytes images/ui/rc/tab-left-CCC.gif | Bin 0 -> 121 bytes images/ui/rc/tab-left-EEE.gif | Bin 0 -> 90 bytes images/ui/rc/tab-right-CCC.gif | Bin 0 -> 120 bytes images/ui/rc/tab-right-EEE.gif | Bin 0 -> 122 bytes images/ui/rc/tb-left-bottom.gif | Bin 0 -> 108 bytes images/ui/rc/tb-right-bottom.gif | Bin 0 -> 108 bytes images/ui/rc/tray-left-bottom.gif | Bin 0 -> 70 bytes images/ui/rc/tray-left-top.gif | Bin 0 -> 95 bytes images/ui/right-arrow.gif | Bin 0 -> 187 bytes images/ui/spinner.gif | Bin 0 -> 1737 bytes images/ui/square_loading.gif | Bin 0 -> 404 bytes images/ui/star.gif | Bin 0 -> 354 bytes images/ui/star_plain.gif | Bin 0 -> 210 bytes images/ui/tick.gif | Bin 0 -> 207 bytes images/ui/vote_down.gif | Bin 0 -> 184 bytes images/ui/vote_up.gif | Bin 0 -> 183 bytes index.cgi | 47 + js/app.js | 210 + js/edit_area/autocompletion.js | 491 + js/edit_area/edit_area.css | 530 + js/edit_area/edit_area.js | 525 + js/edit_area/edit_area_compressor.php | 408 + js/edit_area/edit_area_full.gz | Bin 0 -> 29125 bytes js/edit_area/edit_area_full.js | 38 + js/edit_area/edit_area_full_with_plugins.gz | Bin 0 -> 29707 bytes js/edit_area/edit_area_full_with_plugins.js | 39 + js/edit_area/edit_area_functions.js | 1203 ++ js/edit_area/edit_area_loader.js | 1080 ++ js/edit_area/elements_functions.js | 333 + js/edit_area/highlight.js | 391 + js/edit_area/images/autocompletion.gif | Bin 0 -> 359 bytes js/edit_area/images/close.gif | Bin 0 -> 102 bytes js/edit_area/images/fullscreen.gif | Bin 0 -> 198 bytes js/edit_area/images/go_to_line.gif | Bin 0 -> 1053 bytes js/edit_area/images/help.gif | Bin 0 -> 295 bytes js/edit_area/images/highlight.gif | Bin 0 -> 256 bytes js/edit_area/images/load.gif | Bin 0 -> 1041 bytes js/edit_area/images/move.gif | Bin 0 -> 257 bytes js/edit_area/images/newdocument.gif | Bin 0 -> 170 bytes js/edit_area/images/opacity.png | Bin 0 -> 147 bytes js/edit_area/images/processing.gif | Bin 0 -> 825 bytes js/edit_area/images/redo.gif | Bin 0 -> 169 bytes js/edit_area/images/reset_highlight.gif | Bin 0 -> 168 bytes js/edit_area/images/save.gif | Bin 0 -> 285 bytes js/edit_area/images/search.gif | Bin 0 -> 191 bytes js/edit_area/images/smooth_selection.gif | Bin 0 -> 174 bytes js/edit_area/images/spacer.gif | Bin 0 -> 43 bytes js/edit_area/images/statusbar_resize.gif | Bin 0 -> 79 bytes js/edit_area/images/undo.gif | Bin 0 -> 175 bytes js/edit_area/images/word_wrap.gif | Bin 0 -> 951 bytes js/edit_area/keyboard.js | 145 + js/edit_area/langs/bg.js | 73 + js/edit_area/langs/cs.js | 67 + js/edit_area/langs/de.js | 67 + js/edit_area/langs/dk.js | 67 + js/edit_area/langs/en.js | 67 + js/edit_area/langs/eo.js | 67 + js/edit_area/langs/es.js | 64 + js/edit_area/langs/fi.js | 67 + js/edit_area/langs/fr.js | 67 + js/edit_area/langs/hr.js | 67 + js/edit_area/langs/it.js | 67 + js/edit_area/langs/ja.js | 67 + js/edit_area/langs/mk.js | 67 + js/edit_area/langs/nl.js | 67 + js/edit_area/langs/pl.js | 67 + js/edit_area/langs/pt.js | 67 + js/edit_area/langs/ru.js | 67 + js/edit_area/langs/sk.js | 67 + js/edit_area/langs/zh.js | 67 + js/edit_area/license_apache.txt | 7 + js/edit_area/license_bsd.txt | 10 + js/edit_area/license_lgpl.txt | 458 + js/edit_area/manage_area.js | 623 + js/edit_area/plugins/charmap/charmap.js | 90 + js/edit_area/plugins/charmap/css/charmap.css | 64 + .../plugins/charmap/images/charmap.gif | Bin 0 -> 245 bytes js/edit_area/plugins/charmap/jscripts/map.js | 373 + js/edit_area/plugins/charmap/langs/bg.js | 12 + js/edit_area/plugins/charmap/langs/cs.js | 6 + js/edit_area/plugins/charmap/langs/de.js | 6 + js/edit_area/plugins/charmap/langs/dk.js | 6 + js/edit_area/plugins/charmap/langs/en.js | 6 + js/edit_area/plugins/charmap/langs/eo.js | 6 + js/edit_area/plugins/charmap/langs/es.js | 6 + js/edit_area/plugins/charmap/langs/fr.js | 6 + js/edit_area/plugins/charmap/langs/hr.js | 6 + js/edit_area/plugins/charmap/langs/it.js | 6 + js/edit_area/plugins/charmap/langs/ja.js | 6 + js/edit_area/plugins/charmap/langs/mk.js | 6 + js/edit_area/plugins/charmap/langs/nl.js | 6 + js/edit_area/plugins/charmap/langs/pl.js | 6 + js/edit_area/plugins/charmap/langs/pt.js | 6 + js/edit_area/plugins/charmap/langs/ru.js | 6 + js/edit_area/plugins/charmap/langs/sk.js | 6 + js/edit_area/plugins/charmap/langs/zh.js | 6 + js/edit_area/plugins/charmap/popup.html | 24 + js/edit_area/plugins/test/css/test.css | 3 + js/edit_area/plugins/test/images/Thumbs.db | Bin 0 -> 3584 bytes js/edit_area/plugins/test/images/test.gif | Bin 0 -> 87 bytes js/edit_area/plugins/test/langs/bg.js | 10 + js/edit_area/plugins/test/langs/cs.js | 4 + js/edit_area/plugins/test/langs/de.js | 4 + js/edit_area/plugins/test/langs/dk.js | 4 + js/edit_area/plugins/test/langs/en.js | 4 + js/edit_area/plugins/test/langs/eo.js | 4 + js/edit_area/plugins/test/langs/es.js | 4 + js/edit_area/plugins/test/langs/fr.js | 4 + js/edit_area/plugins/test/langs/hr.js | 4 + js/edit_area/plugins/test/langs/it.js | 4 + js/edit_area/plugins/test/langs/ja.js | 4 + js/edit_area/plugins/test/langs/mk.js | 4 + js/edit_area/plugins/test/langs/nl.js | 4 + js/edit_area/plugins/test/langs/pl.js | 4 + js/edit_area/plugins/test/langs/pt.js | 4 + js/edit_area/plugins/test/langs/ru.js | 4 + js/edit_area/plugins/test/langs/sk.js | 4 + js/edit_area/plugins/test/langs/zh.js | 4 + js/edit_area/plugins/test/test.js | 110 + js/edit_area/plugins/test/test2.js | 1 + js/edit_area/reg_syntax.js | 166 + js/edit_area/reg_syntax/basic.js | 69 + js/edit_area/reg_syntax/brainfuck.js | 44 + js/edit_area/reg_syntax/c.js | 62 + js/edit_area/reg_syntax/coldfusion.js | 119 + js/edit_area/reg_syntax/cpp.js | 65 + js/edit_area/reg_syntax/css.js | 84 + js/edit_area/reg_syntax/html.js | 50 + js/edit_area/reg_syntax/java.js | 56 + js/edit_area/reg_syntax/js.js | 93 + js/edit_area/reg_syntax/pas.js | 82 + js/edit_area/reg_syntax/perl.js | 88 + js/edit_area/reg_syntax/php.js | 156 + js/edit_area/reg_syntax/python.js | 144 + js/edit_area/reg_syntax/robotstxt.js | 24 + js/edit_area/reg_syntax/ruby.js | 67 + js/edit_area/reg_syntax/sql.js | 55 + js/edit_area/reg_syntax/tsql.js | 87 + js/edit_area/reg_syntax/vb.js | 52 + js/edit_area/reg_syntax/xml.js | 56 + js/edit_area/regexp.js | 139 + js/edit_area/resize_area.js | 73 + js/edit_area/search_replace.js | 174 + js/edit_area/template.html | 100 + js/form.compressed.js | 497 + js/globals.js | 96 + js/jquery/excanvas.min.js | 1 + .../jqplot-plugins/jqplot.barRenderer.js | 404 + .../jqplot-plugins/jqplot.barRenderer.min.js | 14 + .../jqplot.canvasAxisLabelRenderer.js | 200 + .../jqplot.canvasAxisLabelRenderer.min.js | 14 + .../jqplot.canvasAxisTickRenderer.js | 232 + .../jqplot.canvasAxisTickRenderer.min.js | 14 + .../jqplot.canvasTextRenderer.js | 408 + .../jqplot.canvasTextRenderer.min.js | 14 + .../jqplot.categoryAxisRenderer.js | 238 + .../jqplot.categoryAxisRenderer.min.js | 14 + js/jquery/jqplot-plugins/jqplot.cursor.js | 812 + js/jquery/jqplot-plugins/jqplot.cursor.min.js | 14 + .../jqplot-plugins/jqplot.dateAxisRenderer.js | 313 + .../jqplot.dateAxisRenderer.min.js | 14 + js/jquery/jqplot-plugins/jqplot.dragable.js | 203 + .../jqplot-plugins/jqplot.dragable.min.js | 14 + .../jqplot-plugins/jqplot.highlighter.js | 359 + .../jqplot-plugins/jqplot.highlighter.min.js | 14 + .../jqplot-plugins/jqplot.logAxisRenderer.js | 434 + .../jqplot.logAxisRenderer.min.js | 14 + .../jqplot.mekkoAxisRenderer.js | 595 + .../jqplot.mekkoAxisRenderer.min.js | 14 + .../jqplot-plugins/jqplot.mekkoRenderer.js | 308 + .../jqplot.mekkoRenderer.min.js | 14 + .../jqplot-plugins/jqplot.ohlcRenderer.js | 343 + .../jqplot-plugins/jqplot.ohlcRenderer.min.js | 14 + .../jqplot-plugins/jqplot.pieRenderer.js | 333 + .../jqplot-plugins/jqplot.pieRenderer.min.js | 14 + .../jqplot-plugins/jqplot.pointLabels.js | 307 + .../jqplot-plugins/jqplot.pointLabels.js.orig | 273 + .../jqplot-plugins/jqplot.pointLabels.min.js | 14 + js/jquery/jqplot-plugins/jqplot.trendline.js | 208 + .../jqplot-plugins/jqplot.trendline.min.js | 14 + js/jquery/jquery-ui.min.js | 69 + js/jquery/jquery.corners.min.js | 7 + js/jquery/jquery.flot.js | 2119 +++ js/jquery/jquery.jqplot.min.js | 14 + js/jquery/jquery.min.js | 19 + js/jquery/jquery.tools.min.js | 35 + js/model/doclist.js | 143 + js/model/local_data.js | 373 + js/report.compressed.js | 251 + js/tiny_mce_33/custom_content.css | 3 + js/tiny_mce_33/jquery.tinymce.js | 1 + js/tiny_mce_33/langs/en.js | 170 + js/tiny_mce_33/license.txt | 504 + js/tiny_mce_33/plugins/advhr/css/advhr.css | 5 + js/tiny_mce_33/plugins/advhr/editor_plugin.js | 1 + .../plugins/advhr/editor_plugin_src.js | 57 + js/tiny_mce_33/plugins/advhr/js/rule.js | 43 + js/tiny_mce_33/plugins/advhr/langs/en_dlg.js | 5 + js/tiny_mce_33/plugins/advhr/rule.htm | 57 + .../plugins/advimage/css/advimage.css | 13 + .../plugins/advimage/editor_plugin.js | 1 + .../plugins/advimage/editor_plugin_src.js | 50 + js/tiny_mce_33/plugins/advimage/image.htm | 232 + .../plugins/advimage/img/sample.gif | Bin 0 -> 1624 bytes js/tiny_mce_33/plugins/advimage/js/image.js | 443 + .../plugins/advimage/langs/en_dlg.js | 43 + .../plugins/advlink/css/advlink.css | 8 + .../plugins/advlink/editor_plugin.js | 1 + .../plugins/advlink/editor_plugin_src.js | 61 + js/tiny_mce_33/plugins/advlink/js/advlink.js | 528 + .../plugins/advlink/langs/en_dlg.js | 52 + js/tiny_mce_33/plugins/advlink/link.htm | 333 + .../plugins/advlist/editor_plugin.js | 1 + .../plugins/advlist/editor_plugin_src.js | 154 + .../plugins/autoresize/editor_plugin.js | 1 + .../plugins/autoresize/editor_plugin_src.js | 119 + .../plugins/autosave/editor_plugin.js | 1 + .../plugins/autosave/editor_plugin_src.js | 422 + js/tiny_mce_33/plugins/autosave/langs/en.js | 4 + .../plugins/bbcode/editor_plugin.js | 1 + .../plugins/bbcode/editor_plugin_src.js | 120 + .../plugins/contextmenu/editor_plugin.js | 1 + .../plugins/contextmenu/editor_plugin_src.js | 147 + .../plugins/directionality/editor_plugin.js | 1 + .../directionality/editor_plugin_src.js | 82 + .../plugins/emotions/editor_plugin.js | 1 + .../plugins/emotions/editor_plugin_src.js | 43 + js/tiny_mce_33/plugins/emotions/emotions.htm | 40 + .../plugins/emotions/img/smiley-cool.gif | Bin 0 -> 354 bytes .../plugins/emotions/img/smiley-cry.gif | Bin 0 -> 329 bytes .../emotions/img/smiley-embarassed.gif | Bin 0 -> 331 bytes .../emotions/img/smiley-foot-in-mouth.gif | Bin 0 -> 344 bytes .../plugins/emotions/img/smiley-frown.gif | Bin 0 -> 340 bytes .../plugins/emotions/img/smiley-innocent.gif | Bin 0 -> 336 bytes .../plugins/emotions/img/smiley-kiss.gif | Bin 0 -> 338 bytes .../plugins/emotions/img/smiley-laughing.gif | Bin 0 -> 344 bytes .../emotions/img/smiley-money-mouth.gif | Bin 0 -> 321 bytes .../plugins/emotions/img/smiley-sealed.gif | Bin 0 -> 325 bytes .../plugins/emotions/img/smiley-smile.gif | Bin 0 -> 345 bytes .../plugins/emotions/img/smiley-surprised.gif | Bin 0 -> 342 bytes .../emotions/img/smiley-tongue-out.gif | Bin 0 -> 328 bytes .../plugins/emotions/img/smiley-undecided.gif | Bin 0 -> 337 bytes .../plugins/emotions/img/smiley-wink.gif | Bin 0 -> 351 bytes .../plugins/emotions/img/smiley-yell.gif | Bin 0 -> 336 bytes .../plugins/emotions/js/emotions.js | 22 + .../plugins/emotions/langs/en_dlg.js | 20 + js/tiny_mce_33/plugins/example/dialog.htm | 22 + .../plugins/example/editor_plugin.js | 1 + .../plugins/example/editor_plugin_src.js | 84 + .../plugins/example/img/example.gif | Bin 0 -> 87 bytes js/tiny_mce_33/plugins/example/js/dialog.js | 19 + js/tiny_mce_33/plugins/example/langs/en.js | 3 + .../plugins/example/langs/en_dlg.js | 3 + .../plugins/fullpage/css/fullpage.css | 182 + .../plugins/fullpage/editor_plugin.js | 1 + .../plugins/fullpage/editor_plugin_src.js | 153 + js/tiny_mce_33/plugins/fullpage/fullpage.htm | 571 + .../plugins/fullpage/js/fullpage.js | 471 + .../plugins/fullpage/langs/en_dlg.js | 85 + .../plugins/fullscreen/editor_plugin.js | 1 + .../plugins/fullscreen/editor_plugin_src.js | 151 + .../plugins/fullscreen/fullscreen.htm | 109 + .../plugins/iespell/editor_plugin.js | 1 + .../plugins/iespell/editor_plugin_src.js | 54 + .../plugins/inlinepopups/editor_plugin.js | 1 + .../plugins/inlinepopups/editor_plugin_src.js | 635 + .../skins/clearlooks2/img/alert.gif | Bin 0 -> 818 bytes .../skins/clearlooks2/img/button.gif | Bin 0 -> 280 bytes .../skins/clearlooks2/img/buttons.gif | Bin 0 -> 1195 bytes .../skins/clearlooks2/img/confirm.gif | Bin 0 -> 915 bytes .../skins/clearlooks2/img/corners.gif | Bin 0 -> 911 bytes .../skins/clearlooks2/img/horizontal.gif | Bin 0 -> 769 bytes .../skins/clearlooks2/img/vertical.gif | Bin 0 -> 92 bytes .../inlinepopups/skins/clearlooks2/window.css | 100 + .../plugins/inlinepopups/template.htm | 387 + .../plugins/insertdatetime/editor_plugin.js | 1 + .../insertdatetime/editor_plugin_src.js | 83 + js/tiny_mce_33/plugins/layer/editor_plugin.js | 1 + .../plugins/layer/editor_plugin_src.js | 212 + .../plugins/legacyoutput/editor_plugin.js | 1 + .../plugins/legacyoutput/editor_plugin_src.js | 136 + js/tiny_mce_33/plugins/media/css/content.css | 6 + js/tiny_mce_33/plugins/media/css/media.css | 16 + js/tiny_mce_33/plugins/media/editor_plugin.js | 1 + .../plugins/media/editor_plugin_src.js | 414 + js/tiny_mce_33/plugins/media/img/flash.gif | Bin 0 -> 241 bytes .../plugins/media/img/flv_player.swf | Bin 0 -> 11668 bytes .../plugins/media/img/quicktime.gif | Bin 0 -> 303 bytes .../plugins/media/img/realmedia.gif | Bin 0 -> 439 bytes .../plugins/media/img/shockwave.gif | Bin 0 -> 387 bytes js/tiny_mce_33/plugins/media/img/trans.gif | Bin 0 -> 43 bytes .../plugins/media/img/windowsmedia.gif | Bin 0 -> 415 bytes js/tiny_mce_33/plugins/media/js/embed.js | 73 + js/tiny_mce_33/plugins/media/js/media.js | 630 + js/tiny_mce_33/plugins/media/langs/en_dlg.js | 103 + js/tiny_mce_33/plugins/media/media.htm | 817 + .../plugins/nonbreaking/editor_plugin.js | 1 + .../plugins/nonbreaking/editor_plugin_src.js | 53 + .../plugins/noneditable/editor_plugin.js | 1 + .../plugins/noneditable/editor_plugin_src.js | 90 + .../plugins/pagebreak/css/content.css | 1 + .../plugins/pagebreak/editor_plugin.js | 1 + .../plugins/pagebreak/editor_plugin_src.js | 77 + .../plugins/pagebreak/img/pagebreak.gif | Bin 0 -> 325 bytes .../plugins/pagebreak/img/trans.gif | Bin 0 -> 43 bytes js/tiny_mce_33/plugins/paste/editor_plugin.js | 1 + .../plugins/paste/editor_plugin_src.js | 952 ++ js/tiny_mce_33/plugins/paste/js/pastetext.js | 36 + js/tiny_mce_33/plugins/paste/js/pasteword.js | 51 + js/tiny_mce_33/plugins/paste/langs/en_dlg.js | 5 + js/tiny_mce_33/plugins/paste/pastetext.htm | 27 + js/tiny_mce_33/plugins/paste/pasteword.htm | 21 + .../plugins/preview/editor_plugin.js | 1 + .../plugins/preview/editor_plugin_src.js | 53 + js/tiny_mce_33/plugins/preview/example.html | 28 + .../plugins/preview/jscripts/embed.js | 73 + js/tiny_mce_33/plugins/preview/preview.html | 17 + js/tiny_mce_33/plugins/print/editor_plugin.js | 1 + .../plugins/print/editor_plugin_src.js | 34 + js/tiny_mce_33/plugins/save/editor_plugin.js | 1 + .../plugins/save/editor_plugin_src.js | 101 + .../searchreplace/css/searchreplace.css | 6 + .../plugins/searchreplace/editor_plugin.js | 1 + .../searchreplace/editor_plugin_src.js | 57 + .../plugins/searchreplace/js/searchreplace.js | 138 + .../plugins/searchreplace/langs/en_dlg.js | 16 + .../plugins/searchreplace/searchreplace.htm | 99 + .../plugins/spellchecker/css/content.css | 1 + .../plugins/spellchecker/editor_plugin.js | 1 + .../plugins/spellchecker/editor_plugin_src.js | 417 + .../plugins/spellchecker/img/wline.gif | Bin 0 -> 46 bytes js/tiny_mce_33/plugins/style/css/props.css | 13 + js/tiny_mce_33/plugins/style/editor_plugin.js | 1 + .../plugins/style/editor_plugin_src.js | 55 + js/tiny_mce_33/plugins/style/js/props.js | 641 + js/tiny_mce_33/plugins/style/langs/en_dlg.js | 63 + js/tiny_mce_33/plugins/style/props.htm | 723 + .../plugins/tabfocus/editor_plugin.js | 1 + .../plugins/tabfocus/editor_plugin_src.js | 112 + js/tiny_mce_33/plugins/table/cell.htm | 178 + js/tiny_mce_33/plugins/table/css/cell.css | 17 + js/tiny_mce_33/plugins/table/css/row.css | 25 + js/tiny_mce_33/plugins/table/css/table.css | 13 + js/tiny_mce_33/plugins/table/editor_plugin.js | 1 + .../plugins/table/editor_plugin_src.js | 1139 ++ js/tiny_mce_33/plugins/table/js/cell.js | 286 + .../plugins/table/js/merge_cells.js | 27 + js/tiny_mce_33/plugins/table/js/row.js | 237 + js/tiny_mce_33/plugins/table/js/table.js | 454 + js/tiny_mce_33/plugins/table/langs/en_dlg.js | 74 + js/tiny_mce_33/plugins/table/merge_cells.htm | 32 + js/tiny_mce_33/plugins/table/row.htm | 155 + js/tiny_mce_33/plugins/table/table.htm | 187 + js/tiny_mce_33/plugins/template/blank.htm | 12 + .../plugins/template/css/template.css | 23 + .../plugins/template/editor_plugin.js | 1 + .../plugins/template/editor_plugin_src.js | 159 + .../plugins/template/js/template.js | 106 + .../plugins/template/langs/en_dlg.js | 15 + js/tiny_mce_33/plugins/template/template.htm | 31 + .../plugins/visualchars/editor_plugin.js | 1 + .../plugins/visualchars/editor_plugin_src.js | 83 + .../plugins/wordcount/editor_plugin.js | 1 + .../plugins/wordcount/editor_plugin_src.js | 98 + js/tiny_mce_33/plugins/xhtmlxtras/abbr.htm | 141 + js/tiny_mce_33/plugins/xhtmlxtras/acronym.htm | 141 + .../plugins/xhtmlxtras/attributes.htm | 148 + js/tiny_mce_33/plugins/xhtmlxtras/cite.htm | 141 + .../plugins/xhtmlxtras/css/attributes.css | 11 + .../plugins/xhtmlxtras/css/popup.css | 9 + js/tiny_mce_33/plugins/xhtmlxtras/del.htm | 161 + .../plugins/xhtmlxtras/editor_plugin.js | 1 + .../plugins/xhtmlxtras/editor_plugin_src.js | 132 + js/tiny_mce_33/plugins/xhtmlxtras/ins.htm | 161 + js/tiny_mce_33/plugins/xhtmlxtras/js/abbr.js | 28 + .../plugins/xhtmlxtras/js/acronym.js | 28 + .../plugins/xhtmlxtras/js/attributes.js | 126 + js/tiny_mce_33/plugins/xhtmlxtras/js/cite.js | 28 + js/tiny_mce_33/plugins/xhtmlxtras/js/del.js | 53 + .../plugins/xhtmlxtras/js/element_common.js | 231 + js/tiny_mce_33/plugins/xhtmlxtras/js/ins.js | 52 + .../plugins/xhtmlxtras/langs/en_dlg.js | 32 + js/tiny_mce_33/themes/advanced/about.htm | 54 + js/tiny_mce_33/themes/advanced/anchor.htm | 26 + js/tiny_mce_33/themes/advanced/charmap.htm | 52 + .../themes/advanced/color_picker.htm | 73 + .../themes/advanced/editor_template.js | 1 + .../themes/advanced/editor_template_src.js | 1229 ++ js/tiny_mce_33/themes/advanced/image.htm | 80 + .../themes/advanced/img/colorpicker.jpg | Bin 0 -> 3189 bytes js/tiny_mce_33/themes/advanced/img/icons.gif | Bin 0 -> 11794 bytes js/tiny_mce_33/themes/advanced/js/about.js | 72 + js/tiny_mce_33/themes/advanced/js/anchor.js | 37 + js/tiny_mce_33/themes/advanced/js/charmap.js | 335 + .../themes/advanced/js/color_picker.js | 253 + js/tiny_mce_33/themes/advanced/js/image.js | 245 + js/tiny_mce_33/themes/advanced/js/link.js | 156 + .../themes/advanced/js/source_editor.js | 56 + js/tiny_mce_33/themes/advanced/langs/en.js | 62 + .../themes/advanced/langs/en_dlg.js | 51 + js/tiny_mce_33/themes/advanced/link.htm | 58 + .../themes/advanced/skins/default/content.css | 36 + .../themes/advanced/skins/default/dialog.css | 117 + .../advanced/skins/default/img/buttons.png | Bin 0 -> 3274 bytes .../advanced/skins/default/img/items.gif | Bin 0 -> 70 bytes .../advanced/skins/default/img/menu_arrow.gif | Bin 0 -> 68 bytes .../advanced/skins/default/img/menu_check.gif | Bin 0 -> 70 bytes .../advanced/skins/default/img/progress.gif | Bin 0 -> 1787 bytes .../advanced/skins/default/img/tabs.gif | Bin 0 -> 1326 bytes .../themes/advanced/skins/default/ui.css | 213 + .../themes/advanced/skins/o2k7/content.css | 36 + .../themes/advanced/skins/o2k7/dialog.css | 116 + .../advanced/skins/o2k7/img/button_bg.png | Bin 0 -> 5859 bytes .../skins/o2k7/img/button_bg_black.png | Bin 0 -> 3736 bytes .../skins/o2k7/img/button_bg_silver.png | Bin 0 -> 5358 bytes .../themes/advanced/skins/o2k7/ui.css | 215 + .../themes/advanced/skins/o2k7/ui_black.css | 8 + .../themes/advanced/skins/o2k7/ui_silver.css | 5 + .../themes/advanced/source_editor.htm | 25 + .../themes/simple/editor_template.js | 1 + .../themes/simple/editor_template_src.js | 85 + js/tiny_mce_33/themes/simple/img/icons.gif | Bin 0 -> 1440 bytes js/tiny_mce_33/themes/simple/langs/en.js | 11 + .../themes/simple/skins/default/content.css | 25 + .../themes/simple/skins/default/ui.css | 32 + .../themes/simple/skins/o2k7/content.css | 17 + .../simple/skins/o2k7/img/button_bg.png | Bin 0 -> 5102 bytes .../themes/simple/skins/o2k7/ui.css | 35 + js/tiny_mce_33/tiny_mce.js | 1 + js/tiny_mce_33/tiny_mce_popup.js | 5 + js/tiny_mce_33/tiny_mce_src.js | 13394 ++++++++++++++++ js/tiny_mce_33/utils/editable_selects.js | 70 + js/tiny_mce_33/utils/form_utils.js | 200 + js/tiny_mce_33/utils/mctabs.js | 77 + js/tiny_mce_33/utils/validate.js | 220 + js/user.js | 3 + js/utils/browser_detect.js | 22 + js/utils/datatype.js | 314 + js/utils/datetime.js | 253 + js/utils/dom.js | 771 + js/utils/handler.js | 312 + js/utils/json.js | 481 + js/utils/msgprint.js | 78 + js/utils/printElement.js | 181 + js/utils/rsh.compressed.js | 1 + js/webpage/about.js | 24 + js/webpage/body.js | 184 + js/webpage/docbrowser.js | 745 + js/webpage/error_console.js | 47 + js/webpage/freeze_page.js | 52 + js/webpage/history.js | 162 + js/webpage/loaders.js | 274 + js/webpage/page.js | 76 + js/webpage/page_header.js | 69 + js/webpage/search.js | 185 + js/webpage/spinner.js | 18 + js/webpage/uploader.js | 48 + js/webpage/wntoolbar.js | 286 + js/widgets/autosuggest.js | 562 + js/widgets/calendar.js | 673 + js/widgets/dialog.js | 122 + js/widgets/export_query.js | 40 + js/widgets/form/attachments.js | 203 + js/widgets/form/clientscriptAPI.js | 133 + js/widgets/form/email.js | 140 + js/widgets/form/fields.js | 1210 ++ js/widgets/form/form.js | 1200 ++ js/widgets/form/form_comments.js | 176 + js/widgets/form/form_container.js | 156 + js/widgets/form/form_fields.js | 484 + js/widgets/form/form_grid.js | 244 + js/widgets/form/form_header.js | 221 + js/widgets/form/grid.js | 439 + js/widgets/form/print_format.js | 416 + js/widgets/layout.js | 140 + js/widgets/list_selector.js | 131 + js/widgets/listing.js | 707 + js/widgets/menu.js | 200 + js/widgets/print_query.js | 154 + js/widgets/report_builder/bargraph.js | 227 + js/widgets/report_builder/calculator.js | 69 + js/widgets/report_builder/datatable.js | 565 + js/widgets/report_builder/report_builder.js | 1246 ++ js/widgets/select.js | 15 + js/widgets/tabbedpage.js | 162 + js/widgets/tags.js | 316 + js/widgets/tree.js | 188 + js/wn/modules.js | 49 + js/wn/page_layout.js | 25 + js/wn/widgets/dialog.js | 163 + js/wn/widgets/doc_column_view.js | 293 + js/wn/widgets/filters.js | 46 + js/wn/widgets/follow.js | 119 + js/wn/widgets/footer.js | 26 + js/wn/widgets/form/attachments.js | 137 + js/wn/widgets/form/comments.js | 59 + js/wn/widgets/form/sidebar.js | 113 + js/wn/widgets/listing.js | 160 + js/wn/widgets/page_sidebar.js | 136 + js/wnf.compressed.js | 1470 ++ robots.txt | 5 + sitemap.xml | 21 + transfer.html | 253 + webnotes.manifestold | 5 + 1408 files changed, 128213 insertions(+) create mode 100644 INSTALL.txt create mode 100755 blank.html create mode 100644 blank1.html create mode 100644 cgi-bin/backupall.py create mode 100644 cgi-bin/core/Module Def/Core/Core.txt create mode 100644 cgi-bin/core/Role/Administrator/Administrator.txt create mode 100644 cgi-bin/core/Role/All/All.txt create mode 100644 cgi-bin/core/Role/Guest/Guest.txt create mode 100644 cgi-bin/core/__init__.py create mode 100644 cgi-bin/core/doctype/__init__.py create mode 100644 cgi-bin/core/doctype/comment_widget_record/__init__.py create mode 100644 cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt create mode 100644 cgi-bin/core/doctype/control_panel/__init__.py create mode 100644 cgi-bin/core/doctype/control_panel/control_panel.py create mode 100644 cgi-bin/core/doctype/control_panel/control_panel.txt create mode 100644 cgi-bin/core/doctype/custom_field/__init__.py create mode 100644 cgi-bin/core/doctype/custom_field/custom_field.js create mode 100644 cgi-bin/core/doctype/custom_field/custom_field.py create mode 100644 cgi-bin/core/doctype/custom_field/custom_field.txt create mode 100644 cgi-bin/core/doctype/custom_script/__init__.py create mode 100644 cgi-bin/core/doctype/custom_script/custom_script.txt create mode 100644 cgi-bin/core/doctype/default_home_page/__init__.py create mode 100644 cgi-bin/core/doctype/default_home_page/default_home_page.txt create mode 100644 cgi-bin/core/doctype/defaultvalue/__init__.py create mode 100644 cgi-bin/core/doctype/defaultvalue/defaultvalue.txt create mode 100644 cgi-bin/core/doctype/docfield/__init__.py create mode 100644 cgi-bin/core/doctype/docfield/docfield.txt create mode 100644 cgi-bin/core/doctype/docformat/__init__.py create mode 100644 cgi-bin/core/doctype/docformat/docformat.txt create mode 100644 cgi-bin/core/doctype/docperm/__init__.py create mode 100644 cgi-bin/core/doctype/docperm/docperm.txt create mode 100644 cgi-bin/core/doctype/doctrigger/__init__.py create mode 100644 cgi-bin/core/doctype/doctrigger/doctrigger.txt create mode 100644 cgi-bin/core/doctype/doctype/__init__.py create mode 100644 cgi-bin/core/doctype/doctype/doctype.js create mode 100644 cgi-bin/core/doctype/doctype/doctype.py create mode 100644 cgi-bin/core/doctype/doctype/doctype.txt create mode 100644 cgi-bin/core/doctype/doctype_label/__init__.py create mode 100644 cgi-bin/core/doctype/doctype_label/doctype_label.txt create mode 100644 cgi-bin/core/doctype/doctype_mapper/__init__.py create mode 100644 cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js create mode 100644 cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py create mode 100644 cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt create mode 100644 cgi-bin/core/doctype/event/__init__.py create mode 100644 cgi-bin/core/doctype/event/event.txt create mode 100644 cgi-bin/core/doctype/event_role/__init__.py create mode 100644 cgi-bin/core/doctype/event_role/event_role.txt create mode 100644 cgi-bin/core/doctype/event_user/__init__.py create mode 100644 cgi-bin/core/doctype/event_user/event_user.txt create mode 100644 cgi-bin/core/doctype/field_mapper_detail/__init__.py create mode 100644 cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt create mode 100644 cgi-bin/core/doctype/file_data/__init__.py create mode 100644 cgi-bin/core/doctype/file_data/file_data.txt create mode 100644 cgi-bin/core/doctype/letter_head/__init__.py create mode 100644 cgi-bin/core/doctype/letter_head/letter_head.js create mode 100755 cgi-bin/core/doctype/letter_head/letter_head.py create mode 100644 cgi-bin/core/doctype/letter_head/letter_head.txt create mode 100644 cgi-bin/core/doctype/module_def/__init__.py create mode 100644 cgi-bin/core/doctype/module_def/module_def.py create mode 100644 cgi-bin/core/doctype/module_def/module_def.txt create mode 100644 cgi-bin/core/doctype/module_def_item/__init__.py create mode 100644 cgi-bin/core/doctype/module_def_item/module_def_item.txt create mode 100644 cgi-bin/core/doctype/module_def_role/__init__.py create mode 100644 cgi-bin/core/doctype/module_def_role/module_def_role.txt create mode 100644 cgi-bin/core/doctype/page/__init__.py create mode 100644 cgi-bin/core/doctype/page/page.py create mode 100644 cgi-bin/core/doctype/page/page.txt create mode 100644 cgi-bin/core/doctype/page_role/__init__.py create mode 100644 cgi-bin/core/doctype/page_role/page_role.txt create mode 100644 cgi-bin/core/doctype/page_template/__init__.py create mode 100644 cgi-bin/core/doctype/page_template/page_template.py create mode 100644 cgi-bin/core/doctype/page_template/page_template.txt create mode 100644 cgi-bin/core/doctype/print_format/__init__.py create mode 100644 cgi-bin/core/doctype/print_format/print_format.txt create mode 100644 cgi-bin/core/doctype/profile/__init__.py create mode 100644 cgi-bin/core/doctype/profile/profile.js create mode 100644 cgi-bin/core/doctype/profile/profile.py create mode 100644 cgi-bin/core/doctype/profile/profile.txt create mode 100644 cgi-bin/core/doctype/property_setter/__init__.py create mode 100644 cgi-bin/core/doctype/property_setter/property_setter.comp.js create mode 100644 cgi-bin/core/doctype/property_setter/property_setter.js create mode 100644 cgi-bin/core/doctype/property_setter/property_setter.py create mode 100644 cgi-bin/core/doctype/property_setter/property_setter.txt create mode 100644 cgi-bin/core/doctype/role/__init__.py create mode 100644 cgi-bin/core/doctype/role/role.txt create mode 100644 cgi-bin/core/doctype/search_criteria/__init__.py create mode 100644 cgi-bin/core/doctype/search_criteria/search_criteria.py create mode 100644 cgi-bin/core/doctype/search_criteria/search_criteria.txt create mode 100644 cgi-bin/core/doctype/stylesheet/__init__.py create mode 100644 cgi-bin/core/doctype/stylesheet/stylesheet.py create mode 100644 cgi-bin/core/doctype/stylesheet/stylesheet.txt create mode 100644 cgi-bin/core/doctype/system_console/__init__.py create mode 100644 cgi-bin/core/doctype/system_console/system_console.comp.js create mode 100644 cgi-bin/core/doctype/system_console/system_console.js create mode 100644 cgi-bin/core/doctype/system_console/system_console.py create mode 100644 cgi-bin/core/doctype/system_console/system_console.txt create mode 100644 cgi-bin/core/doctype/table_mapper_detail/__init__.py create mode 100644 cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt create mode 100644 cgi-bin/core/doctype/tag/__init__.py create mode 100644 cgi-bin/core/doctype/tag/tag.txt create mode 100644 cgi-bin/core/doctype/userrole/__init__.py create mode 100644 cgi-bin/core/doctype/userrole/userrole.txt create mode 100644 cgi-bin/core/module.info create mode 100644 cgi-bin/core/page/__init__.py create mode 100644 cgi-bin/core/page/login_page/__init__.py create mode 100644 cgi-bin/core/page/login_page/login_page.html create mode 100644 cgi-bin/core/page/login_page/login_page.js create mode 100644 cgi-bin/core/page/login_page/login_page.txt create mode 100644 cgi-bin/core/page/login_page/login_page_static.html create mode 100755 cgi-bin/getfile.cgi create mode 100755 cgi-bin/getjsfile.cgi create mode 100755 cgi-bin/pypi-setup.py create mode 100644 cgi-bin/webnotes/__init__.py create mode 100644 cgi-bin/webnotes/auth.py create mode 100644 cgi-bin/webnotes/db.py create mode 100644 cgi-bin/webnotes/defs_template.py create mode 100755 cgi-bin/webnotes/handler.py create mode 100644 cgi-bin/webnotes/install_lib/__init__.py create mode 100644 cgi-bin/webnotes/install_lib/db_init.py create mode 100755 cgi-bin/webnotes/install_lib/install.py create mode 100644 cgi-bin/webnotes/model/__init__.py create mode 100644 cgi-bin/webnotes/model/code.py create mode 100644 cgi-bin/webnotes/model/db_schema.py create mode 100644 cgi-bin/webnotes/model/doc.py create mode 100644 cgi-bin/webnotes/model/doclist.py create mode 100644 cgi-bin/webnotes/model/doctype.py create mode 100644 cgi-bin/webnotes/model/import_docs.py create mode 100644 cgi-bin/webnotes/model/meta.py create mode 100644 cgi-bin/webnotes/model/modules.py create mode 100644 cgi-bin/webnotes/model/triggers.py create mode 100644 cgi-bin/webnotes/modules/__init__.py create mode 100644 cgi-bin/webnotes/modules/compress.py create mode 100644 cgi-bin/webnotes/modules/export_module.py create mode 100644 cgi-bin/webnotes/modules/import_module.py create mode 100644 cgi-bin/webnotes/modules/module_manager.py create mode 100644 cgi-bin/webnotes/modules/patch.py create mode 100644 cgi-bin/webnotes/multi_tenant/__init__.py create mode 100644 cgi-bin/webnotes/multi_tenant/query_parser.py create mode 100644 cgi-bin/webnotes/multi_tenant/setup.py create mode 100644 cgi-bin/webnotes/profile.py create mode 100644 cgi-bin/webnotes/session_cache.py create mode 100644 cgi-bin/webnotes/settings/__init__.py create mode 100644 cgi-bin/webnotes/settings/account_map_template.py create mode 100644 cgi-bin/webnotes/utils/__init__.py create mode 100644 cgi-bin/webnotes/utils/archive.py create mode 100644 cgi-bin/webnotes/utils/backups.py create mode 100644 cgi-bin/webnotes/utils/cache.py create mode 100644 cgi-bin/webnotes/utils/email_lib/__init__.py create mode 100644 cgi-bin/webnotes/utils/email_lib/form_email.py create mode 100644 cgi-bin/webnotes/utils/email_lib/html2text.py create mode 100644 cgi-bin/webnotes/utils/email_lib/receive.py create mode 100644 cgi-bin/webnotes/utils/email_lib/send.py create mode 100644 cgi-bin/webnotes/utils/encrypt.py create mode 100644 cgi-bin/webnotes/utils/file_manager.py create mode 100644 cgi-bin/webnotes/utils/jsmin.py create mode 100644 cgi-bin/webnotes/utils/nestedset.py create mode 100644 cgi-bin/webnotes/utils/scheduler.py create mode 100644 cgi-bin/webnotes/utils/sitemap.py create mode 100644 cgi-bin/webnotes/utils/transfer.py create mode 100644 cgi-bin/webnotes/utils/webservice.py create mode 100644 cgi-bin/webnotes/widgets/__init__.py create mode 100644 cgi-bin/webnotes/widgets/auto_master.py create mode 100644 cgi-bin/webnotes/widgets/event.py create mode 100644 cgi-bin/webnotes/widgets/follow.py create mode 100644 cgi-bin/webnotes/widgets/form.py create mode 100644 cgi-bin/webnotes/widgets/menus.py create mode 100644 cgi-bin/webnotes/widgets/page.py create mode 100644 cgi-bin/webnotes/widgets/page_body.py create mode 100644 cgi-bin/webnotes/widgets/query_builder.py create mode 100644 cgi-bin/webnotes/widgets/search.py create mode 100644 cgi-bin/webnotes/widgets/tags.py create mode 100644 cgi-bin/webnotes/widgets/todo.py create mode 100644 change_log.txt create mode 100644 compress.py create mode 100644 css/autosuggest.css create mode 100644 css/body.css create mode 100644 css/bw-icons.css create mode 100644 css/calendar.css create mode 100644 css/default.css create mode 100644 css/dialog.css create mode 100644 css/doc_column_view.css create mode 100644 css/forms.css create mode 100644 css/grid.css create mode 100755 css/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100755 css/images/ui-bg_flat_75_ffffff_40x100.png create mode 100755 css/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100755 css/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100755 css/images/ui-bg_highlight-hard_65_ffffff_1x100.png create mode 100755 css/images/ui-bg_highlight-hard_75_dadada_1x100.png create mode 100755 css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png create mode 100755 css/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100755 css/images/ui-icons_222222_256x240.png create mode 100755 css/images/ui-icons_2e83ff_256x240.png create mode 100755 css/images/ui-icons_454545_256x240.png create mode 100755 css/images/ui-icons_888888_256x240.png create mode 100755 css/images/ui-icons_cd0a0a_256x240.png create mode 100644 css/jqplot.css create mode 100755 css/jquery-ui.css create mode 100644 css/listing.css create mode 100644 css/menus.css create mode 100644 css/messages.css create mode 100644 css/report.css create mode 100644 css/sidebar.css create mode 100644 css/tabs.css create mode 100644 css/user.css create mode 100644 css/wntoolbar.css create mode 100644 data/Framework.sql create mode 100644 data/GeoIP.dat create mode 100644 docs/html/.buildinfo create mode 100644 docs/html/_sources/admin_login.txt create mode 100644 docs/html/_sources/apps_intro.txt create mode 100644 docs/html/_sources/auth.txt create mode 100644 docs/html/_sources/autosuggest.txt create mode 100644 docs/html/_sources/build_app.txt create mode 100644 docs/html/_sources/client_side_cookbook.txt create mode 100644 docs/html/_sources/client_side_script.txt create mode 100644 docs/html/_sources/client_side_widgets.txt create mode 100644 docs/html/_sources/code.txt create mode 100644 docs/html/_sources/concepts.txt create mode 100644 docs/html/_sources/creating_doctypes.txt create mode 100644 docs/html/_sources/creating_entities.txt create mode 100644 docs/html/_sources/creating_pages.txt create mode 100644 docs/html/_sources/creating_profiles.txt create mode 100644 docs/html/_sources/creating_reports.txt create mode 100644 docs/html/_sources/creating_roles.txt create mode 100644 docs/html/_sources/database_api.txt create mode 100644 docs/html/_sources/db.txt create mode 100644 docs/html/_sources/db_schema.txt create mode 100644 docs/html/_sources/dialog.txt create mode 100644 docs/html/_sources/doc.txt create mode 100644 docs/html/_sources/doclist.txt create mode 100644 docs/html/_sources/doctype.txt create mode 100644 docs/html/_sources/email_lib.txt create mode 100644 docs/html/_sources/form_server.txt create mode 100644 docs/html/_sources/form_widget.txt create mode 100644 docs/html/_sources/glossary.txt create mode 100644 docs/html/_sources/index.txt create mode 100644 docs/html/_sources/intro.txt create mode 100644 docs/html/_sources/javascript_utils.txt create mode 100644 docs/html/_sources/listing.txt create mode 100644 docs/html/_sources/local_data.txt create mode 100644 docs/html/_sources/menus_server.txt create mode 100644 docs/html/_sources/module.txt create mode 100644 docs/html/_sources/navigation.txt create mode 100644 docs/html/_sources/page_body.txt create mode 100644 docs/html/_sources/page_cookbook.txt create mode 100644 docs/html/_sources/page_server.txt create mode 100644 docs/html/_sources/profile.txt create mode 100644 docs/html/_sources/report_builder.txt create mode 100644 docs/html/_sources/report_cookbook.txt create mode 100644 docs/html/_sources/save_submit.txt create mode 100644 docs/html/_sources/server_side_api.txt create mode 100644 docs/html/_sources/server_side_cookbook.txt create mode 100644 docs/html/_sources/server_side_internals.txt create mode 100644 docs/html/_sources/server_side_script.txt create mode 100644 docs/html/_sources/sitemap.txt create mode 100644 docs/html/_sources/tabbed_page.txt create mode 100644 docs/html/_sources/tree.txt create mode 100644 docs/html/_sources/utils_server.txt create mode 100644 docs/html/_sources/webnotes.txt create mode 100644 docs/html/_sources/webnotes_intro.txt create mode 100644 docs/html/_sources/webservice.txt create mode 100644 docs/html/_sources/what_is_an_app.txt create mode 100644 docs/html/_sources/writing_scripts.txt create mode 100644 docs/html/_static/banner300910.gif create mode 100644 docs/html/_static/basic.css create mode 100644 docs/html/_static/contents.png create mode 100644 docs/html/_static/default.css create mode 100644 docs/html/_static/doctools.js create mode 100644 docs/html/_static/file.png create mode 100644 docs/html/_static/jquery.js create mode 100644 docs/html/_static/minus.png create mode 100644 docs/html/_static/navigation.png create mode 100644 docs/html/_static/plus.png create mode 100644 docs/html/_static/pygments.css create mode 100644 docs/html/_static/searchtools.js create mode 100644 docs/html/_static/sphinxdoc.css create mode 100644 docs/html/admin_login.html create mode 100644 docs/html/apps_intro.html create mode 100644 docs/html/auth.html create mode 100644 docs/html/autosuggest.html create mode 100644 docs/html/build_app.html create mode 100644 docs/html/client_side_cookbook.html create mode 100644 docs/html/client_side_script.html create mode 100644 docs/html/client_side_widgets.html create mode 100644 docs/html/code.html create mode 100644 docs/html/concepts.html create mode 100644 docs/html/creating_doctypes.html create mode 100644 docs/html/creating_entities.html create mode 100644 docs/html/creating_pages.html create mode 100644 docs/html/creating_profiles.html create mode 100644 docs/html/creating_reports.html create mode 100644 docs/html/creating_roles.html create mode 100644 docs/html/database_api.html create mode 100644 docs/html/db.html create mode 100644 docs/html/db_schema.html create mode 100644 docs/html/dialog.html create mode 100644 docs/html/doc.html create mode 100644 docs/html/doclist.html create mode 100644 docs/html/doctype.html create mode 100644 docs/html/email_lib.html create mode 100644 docs/html/form_server.html create mode 100644 docs/html/form_widget.html create mode 100644 docs/html/genindex.html create mode 100644 docs/html/glossary.html create mode 100644 docs/html/index.html create mode 100644 docs/html/intro.html create mode 100644 docs/html/javascript_utils.html create mode 100644 docs/html/listing.html create mode 100644 docs/html/local_data.html create mode 100644 docs/html/menus_server.html create mode 100644 docs/html/modindex.html create mode 100644 docs/html/module.html create mode 100644 docs/html/navigation.html create mode 100644 docs/html/objects.inv create mode 100644 docs/html/page_body.html create mode 100644 docs/html/page_cookbook.html create mode 100644 docs/html/page_server.html create mode 100644 docs/html/profile.html create mode 100644 docs/html/report_builder.html create mode 100644 docs/html/report_cookbook.html create mode 100644 docs/html/save_submit.html create mode 100644 docs/html/search.html create mode 100644 docs/html/searchindex.js create mode 100644 docs/html/server_side_api.html create mode 100644 docs/html/server_side_cookbook.html create mode 100644 docs/html/server_side_internals.html create mode 100644 docs/html/server_side_script.html create mode 100644 docs/html/sitemap.html create mode 100644 docs/html/tabbed_page.html create mode 100644 docs/html/tree.html create mode 100644 docs/html/utils_server.html create mode 100644 docs/html/webnotes.html create mode 100644 docs/html/webnotes_intro.html create mode 100644 docs/html/webservice.html create mode 100644 docs/html/what_is_an_app.html create mode 100644 docs/html/writing_scripts.html create mode 100755 images/icons/Accounts.gif create mode 100755 images/icons/Accounts.png create mode 100755 images/icons/Analysis.gif create mode 100755 images/icons/Analysis.png create mode 100755 images/icons/Buying.gif create mode 100755 images/icons/Buying.png create mode 100755 images/icons/HR.gif create mode 100755 images/icons/HR.png create mode 100755 images/icons/Home.gif create mode 100755 images/icons/Home.png create mode 100755 images/icons/Maintenance.gif create mode 100755 images/icons/Maintenance.png create mode 100755 images/icons/Production.gif create mode 100755 images/icons/Production.png create mode 100755 images/icons/Projects.gif create mode 100755 images/icons/Projects.png create mode 100755 images/icons/Selling.gif create mode 100755 images/icons/Selling.png create mode 100755 images/icons/Setup.gif create mode 100755 images/icons/Setup.png create mode 100755 images/icons/Stock.gif create mode 100755 images/icons/Stock.png create mode 100644 images/icons/accept.gif create mode 100755 images/icons/accept.png create mode 100644 images/icons/add.gif create mode 100755 images/icons/add.png create mode 100755 images/icons/anchor.png create mode 100644 images/icons/application.gif create mode 100755 images/icons/application.png create mode 100755 images/icons/application_add.png create mode 100755 images/icons/application_cascade.png create mode 100755 images/icons/application_delete.png create mode 100755 images/icons/application_double.png create mode 100755 images/icons/application_form.png create mode 100755 images/icons/application_go.png create mode 100755 images/icons/application_side_list.png create mode 100755 images/icons/application_side_tree.png create mode 100755 images/icons/application_split.png create mode 100755 images/icons/application_tile_horizontal.png create mode 100755 images/icons/application_tile_vertical.png create mode 100755 images/icons/application_view_columns.png create mode 100755 images/icons/application_view_detail.png create mode 100755 images/icons/application_view_tile.png create mode 100755 images/icons/application_xp.png create mode 100755 images/icons/application_xp_terminal.png create mode 100755 images/icons/arrow_branch.png create mode 100755 images/icons/arrow_divide.png create mode 100644 images/icons/arrow_down.gif create mode 100755 images/icons/arrow_down.png create mode 100755 images/icons/arrow_in.png create mode 100755 images/icons/arrow_inout.png create mode 100755 images/icons/arrow_join.png create mode 100644 images/icons/arrow_left.gif create mode 100755 images/icons/arrow_left.png create mode 100755 images/icons/arrow_merge.png create mode 100755 images/icons/arrow_out.png create mode 100755 images/icons/arrow_redo.png create mode 100755 images/icons/arrow_refresh.png create mode 100755 images/icons/arrow_refresh_small.png create mode 100644 images/icons/arrow_right.gif create mode 100755 images/icons/arrow_right.png create mode 100755 images/icons/arrow_rotate_anticlockwise.png create mode 100755 images/icons/arrow_rotate_clockwise.png create mode 100755 images/icons/arrow_switch.png create mode 100755 images/icons/arrow_turn_left.png create mode 100755 images/icons/arrow_turn_right.png create mode 100755 images/icons/arrow_undo.png create mode 100644 images/icons/arrow_up.gif create mode 100755 images/icons/arrow_up.png create mode 100755 images/icons/asterisk_orange.png create mode 100755 images/icons/asterisk_yellow.png create mode 100755 images/icons/attach.png create mode 100755 images/icons/award_star_add.png create mode 100755 images/icons/award_star_bronze_1.png create mode 100755 images/icons/award_star_bronze_2.png create mode 100755 images/icons/award_star_bronze_3.png create mode 100755 images/icons/award_star_delete.png create mode 100755 images/icons/award_star_gold_1.png create mode 100755 images/icons/award_star_gold_2.png create mode 100755 images/icons/award_star_gold_3.png create mode 100755 images/icons/award_star_silver_1.png create mode 100755 images/icons/award_star_silver_2.png create mode 100755 images/icons/award_star_silver_3.png create mode 100755 images/icons/basket.png create mode 100755 images/icons/bell.png create mode 100755 images/icons/bin.png create mode 100755 images/icons/bin_closed.png create mode 100755 images/icons/bin_empty.png create mode 100755 images/icons/bomb.png create mode 100755 images/icons/book.png create mode 100755 images/icons/book_add.png create mode 100755 images/icons/book_addresses.png create mode 100755 images/icons/box.png create mode 100755 images/icons/brick.png create mode 100755 images/icons/bricks.png create mode 100755 images/icons/briefcase.png create mode 100755 images/icons/bug.png create mode 100755 images/icons/building.png create mode 100755 images/icons/bullet_add.png create mode 100755 images/icons/bullet_arrow_bottom.png create mode 100755 images/icons/bullet_arrow_down.png create mode 100755 images/icons/bullet_arrow_top.png create mode 100755 images/icons/bullet_arrow_up.png create mode 100755 images/icons/bullet_black.png create mode 100755 images/icons/bullet_blue.png create mode 100755 images/icons/bullet_delete.png create mode 100755 images/icons/bullet_green.png create mode 100755 images/icons/bullet_key.png create mode 100755 images/icons/bullet_orange.png create mode 100755 images/icons/bullet_picture.png create mode 100755 images/icons/bullet_pink.png create mode 100755 images/icons/bullet_purple.png create mode 100755 images/icons/bullet_red.png create mode 100755 images/icons/bullet_star.png create mode 100755 images/icons/bullet_toggle_minus.png create mode 100755 images/icons/bullet_toggle_plus.png create mode 100755 images/icons/bullet_white.png create mode 100755 images/icons/bullet_wrench.png create mode 100755 images/icons/bullet_yellow.png create mode 100755 images/icons/cake.png create mode 100644 images/icons/calculator.gif create mode 100755 images/icons/calculator.png create mode 100644 images/icons/calendar.gif create mode 100755 images/icons/calendar.png create mode 100755 images/icons/calendar_view_day.png create mode 100755 images/icons/calendar_view_month.png create mode 100755 images/icons/calendar_view_week.png create mode 100755 images/icons/camera.png create mode 100644 images/icons/cancel.gif create mode 100755 images/icons/cancel.png create mode 100755 images/icons/car.png create mode 100755 images/icons/car_add.png create mode 100755 images/icons/car_delete.png create mode 100755 images/icons/cart.png create mode 100755 images/icons/cart_add.png create mode 100755 images/icons/cart_delete.png create mode 100755 images/icons/cart_edit.png create mode 100755 images/icons/cart_error.png create mode 100755 images/icons/cart_go.png create mode 100755 images/icons/cart_put.png create mode 100755 images/icons/cart_remove.png create mode 100755 images/icons/cd.png create mode 100644 images/icons/chart_bar.gif create mode 100755 images/icons/chart_bar.png create mode 100755 images/icons/chart_curve.png create mode 100755 images/icons/chart_line.png create mode 100755 images/icons/chart_organisation.png create mode 100755 images/icons/chart_pie.png create mode 100755 images/icons/clock.png create mode 100755 images/icons/clock_play.png create mode 100755 images/icons/clock_red.png create mode 100755 images/icons/clock_stop.png create mode 100644 images/icons/close.gif create mode 100755 images/icons/cog.png create mode 100755 images/icons/coins.png create mode 100755 images/icons/coins_add.png create mode 100755 images/icons/coins_delete.png create mode 100755 images/icons/color_swatch.png create mode 100755 images/icons/color_wheel.png create mode 100755 images/icons/comment.png create mode 100755 images/icons/comment_add.png create mode 100755 images/icons/comment_delete.png create mode 100755 images/icons/comment_edit.png create mode 100644 images/icons/comments.gif create mode 100755 images/icons/comments.png create mode 100755 images/icons/comments_add.png create mode 100755 images/icons/comments_delete.png create mode 100755 images/icons/compress.png create mode 100755 images/icons/computer.png create mode 100755 images/icons/connect.png create mode 100755 images/icons/contrast.png create mode 100755 images/icons/control_eject.png create mode 100755 images/icons/control_eject_blue.png create mode 100755 images/icons/control_end.png create mode 100755 images/icons/control_end_blue.png create mode 100755 images/icons/control_equalizer.png create mode 100755 images/icons/control_equalizer_blue.png create mode 100755 images/icons/control_fastforward.png create mode 100755 images/icons/control_fastforward_blue.png create mode 100755 images/icons/control_pause.png create mode 100755 images/icons/control_pause_blue.png create mode 100755 images/icons/control_play.png create mode 100755 images/icons/control_play_blue.png create mode 100755 images/icons/control_repeat.png create mode 100755 images/icons/control_repeat_blue.png create mode 100755 images/icons/control_rewind.png create mode 100755 images/icons/control_rewind_blue.png create mode 100755 images/icons/control_start.png create mode 100755 images/icons/control_start_blue.png create mode 100755 images/icons/controller.png create mode 100755 images/icons/creditcards.png create mode 100755 images/icons/cross.png create mode 100755 images/icons/css.png create mode 100755 images/icons/cup.png create mode 100755 images/icons/cursor.png create mode 100755 images/icons/cut.png create mode 100755 images/icons/cut_red.png create mode 100755 images/icons/database.png create mode 100755 images/icons/date.png create mode 100755 images/icons/date_magnify.png create mode 100755 images/icons/date_next.png create mode 100755 images/icons/date_previous.png create mode 100755 images/icons/delete.png create mode 100755 images/icons/disconnect.png create mode 100644 images/icons/disk.gif create mode 100755 images/icons/disk.png create mode 100755 images/icons/disk_multiple.png create mode 100755 images/icons/door.png create mode 100755 images/icons/door_in.png create mode 100755 images/icons/door_open.png create mode 100755 images/icons/door_out.png create mode 100644 images/icons/down-arrow.gif create mode 100755 images/icons/drink.png create mode 100755 images/icons/drink_empty.png create mode 100755 images/icons/drive.png create mode 100755 images/icons/dvd.png create mode 100644 images/icons/email.gif create mode 100755 images/icons/email.png create mode 100755 images/icons/email_add.png create mode 100755 images/icons/email_attach.png create mode 100755 images/icons/email_delete.png create mode 100755 images/icons/email_edit.png create mode 100755 images/icons/email_error.png create mode 100755 images/icons/email_go.png create mode 100755 images/icons/email_link.png create mode 100755 images/icons/email_open.png create mode 100755 images/icons/email_open_image.png create mode 100755 images/icons/emoticon_evilgrin.png create mode 100755 images/icons/emoticon_grin.png create mode 100755 images/icons/emoticon_happy.png create mode 100644 images/icons/emoticon_smile.gif create mode 100755 images/icons/emoticon_smile.png create mode 100755 images/icons/emoticon_surprised.png create mode 100755 images/icons/emoticon_tongue.png create mode 100755 images/icons/emoticon_unhappy.png create mode 100755 images/icons/emoticon_waii.png create mode 100755 images/icons/emoticon_wink.png create mode 100644 images/icons/error.gif create mode 100755 images/icons/error.png create mode 100755 images/icons/error_add.png create mode 100755 images/icons/error_delete.png create mode 100755 images/icons/error_go.png create mode 100755 images/icons/exclamation.png create mode 100755 images/icons/eye.png create mode 100755 images/icons/feed.png create mode 100755 images/icons/female.png create mode 100755 images/icons/film.png create mode 100755 images/icons/find.png create mode 100755 images/icons/flag_blue.png create mode 100755 images/icons/flag_green.png create mode 100755 images/icons/flag_orange.png create mode 100755 images/icons/flag_pink.png create mode 100755 images/icons/flag_purple.png create mode 100755 images/icons/flag_red.png create mode 100755 images/icons/flag_yellow.png create mode 100644 images/icons/folder.gif create mode 100755 images/icons/folder.png create mode 100755 images/icons/folder_delete.png create mode 100755 images/icons/folder_error.png create mode 100755 images/icons/folder_link.png create mode 100755 images/icons/folder_page_white.png create mode 100755 images/icons/folder_star.png create mode 100755 images/icons/folder_user.png create mode 100755 images/icons/font.png create mode 100755 images/icons/font_add.png create mode 100755 images/icons/font_delete.png create mode 100755 images/icons/font_go.png create mode 100644 images/icons/group.gif create mode 100755 images/icons/group.png create mode 100755 images/icons/heart.png create mode 100755 images/icons/heart_add.png create mode 100755 images/icons/heart_delete.png create mode 100644 images/icons/help.gif create mode 100755 images/icons/help.png create mode 100755 images/icons/hourglass.png create mode 100644 images/icons/house.gif create mode 100755 images/icons/house.png create mode 100755 images/icons/house_go.png create mode 100755 images/icons/house_link.png create mode 100755 images/icons/html.png create mode 100644 images/icons/icon-recommend.gif create mode 100644 images/icons/icons.png create mode 100755 images/icons/image.png create mode 100755 images/icons/image_add.png create mode 100755 images/icons/image_delete.png create mode 100755 images/icons/image_edit.png create mode 100755 images/icons/image_link.png create mode 100755 images/icons/images.png create mode 100755 images/icons/information.png create mode 100755 images/icons/ipod.png create mode 100755 images/icons/joystick.png create mode 100755 images/icons/key.png create mode 100755 images/icons/key_add.png create mode 100755 images/icons/key_delete.png create mode 100755 images/icons/key_go.png create mode 100755 images/icons/keyboard.png create mode 100755 images/icons/layers.png create mode 100755 images/icons/layout.png create mode 100755 images/icons/layout_add.png create mode 100755 images/icons/layout_content.png create mode 100644 images/icons/lightbulb.gif create mode 100755 images/icons/lightbulb.png create mode 100755 images/icons/lightbulb_off.png create mode 100755 images/icons/lightning.png create mode 100755 images/icons/link.png create mode 100755 images/icons/lock.png create mode 100755 images/icons/lock_open.png create mode 100755 images/icons/lorry.png create mode 100755 images/icons/magifier_zoom_out.png create mode 100644 images/icons/magnifier.gif create mode 100755 images/icons/magnifier.png create mode 100755 images/icons/magnifier_zoom_in.png create mode 100755 images/icons/male.png create mode 100755 images/icons/map.png create mode 100755 images/icons/medal_bronze_1.png create mode 100755 images/icons/medal_bronze_2.png create mode 100755 images/icons/medal_bronze_3.png create mode 100755 images/icons/medal_bronze_add.png create mode 100755 images/icons/medal_bronze_delete.png create mode 100755 images/icons/medal_gold_1.png create mode 100755 images/icons/medal_gold_2.png create mode 100755 images/icons/medal_gold_3.png create mode 100755 images/icons/medal_gold_add.png create mode 100755 images/icons/medal_gold_delete.png create mode 100755 images/icons/medal_silver_1.png create mode 100755 images/icons/medal_silver_2.png create mode 100755 images/icons/medal_silver_3.png create mode 100755 images/icons/medal_silver_add.png create mode 100755 images/icons/medal_silver_delete.png create mode 100755 images/icons/minus.gif create mode 100755 images/icons/money.png create mode 100755 images/icons/money_add.png create mode 100755 images/icons/money_delete.png create mode 100755 images/icons/money_dollar.png create mode 100755 images/icons/money_euro.png create mode 100755 images/icons/money_pound.png create mode 100755 images/icons/money_yen.png create mode 100755 images/icons/monitor.png create mode 100755 images/icons/mouse.png create mode 100755 images/icons/mouse_add.png create mode 100755 images/icons/mouse_delete.png create mode 100755 images/icons/mouse_error.png create mode 100755 images/icons/music.png create mode 100755 images/icons/new.png create mode 100755 images/icons/newspaper.png create mode 100644 images/icons/note.gif create mode 100755 images/icons/note.png create mode 100755 images/icons/overlays.png create mode 100755 images/icons/package.png create mode 100644 images/icons/page.gif create mode 100755 images/icons/page.png create mode 100644 images/icons/page_add.gif create mode 100755 images/icons/page_add.png create mode 100755 images/icons/page_attach.png create mode 100755 images/icons/page_code.png create mode 100644 images/icons/page_copy.gif create mode 100755 images/icons/page_copy.png create mode 100755 images/icons/page_delete.png create mode 100755 images/icons/page_edit.png create mode 100755 images/icons/page_error.png create mode 100644 images/icons/page_excel.gif create mode 100755 images/icons/page_excel.png create mode 100755 images/icons/page_find.png create mode 100755 images/icons/page_gear.png create mode 100755 images/icons/page_go.png create mode 100755 images/icons/page_green.png create mode 100755 images/icons/page_key.png create mode 100755 images/icons/page_lightning.png create mode 100755 images/icons/page_link.png create mode 100755 images/icons/page_paintbrush.png create mode 100755 images/icons/page_paste.png create mode 100755 images/icons/page_red.png create mode 100644 images/icons/page_refresh.gif create mode 100755 images/icons/page_refresh.png create mode 100755 images/icons/page_save.png create mode 100755 images/icons/page_white.png create mode 100755 images/icons/page_white_acrobat.png create mode 100755 images/icons/page_white_actionscript.png create mode 100755 images/icons/page_white_add.png create mode 100755 images/icons/page_white_c.png create mode 100755 images/icons/page_white_camera.png create mode 100755 images/icons/page_white_cd.png create mode 100755 images/icons/page_white_code.png create mode 100755 images/icons/page_white_code_red.png create mode 100755 images/icons/page_white_copy.png create mode 100755 images/icons/page_white_csharp.png create mode 100755 images/icons/page_white_cup.png create mode 100755 images/icons/page_white_delete.png create mode 100755 images/icons/page_white_dvd.png create mode 100755 images/icons/page_white_error.png create mode 100755 images/icons/page_white_find.png create mode 100755 images/icons/page_white_flash.png create mode 100755 images/icons/page_white_freehand.png create mode 100755 images/icons/page_white_gear.png create mode 100755 images/icons/page_white_get.png create mode 100755 images/icons/page_white_go.png create mode 100755 images/icons/page_white_h.png create mode 100755 images/icons/page_white_horizontal.png create mode 100755 images/icons/page_white_key.png create mode 100755 images/icons/page_white_lightning.png create mode 100755 images/icons/page_white_link.png create mode 100755 images/icons/page_white_magnify.png create mode 100755 images/icons/page_white_medal.png create mode 100755 images/icons/page_white_office.png create mode 100755 images/icons/page_white_paint.png create mode 100755 images/icons/page_white_paintbrush.png create mode 100755 images/icons/page_white_paste.png create mode 100755 images/icons/page_white_put.png create mode 100755 images/icons/page_white_stack.png create mode 100755 images/icons/page_white_star.png create mode 100755 images/icons/page_white_text.png create mode 100755 images/icons/page_white_text_width.png create mode 100755 images/icons/page_white_tux.png create mode 100755 images/icons/page_white_vector.png create mode 100755 images/icons/page_white_visualstudio.png create mode 100755 images/icons/page_white_width.png create mode 100755 images/icons/page_white_word.png create mode 100755 images/icons/page_white_world.png create mode 100755 images/icons/page_white_wrench.png create mode 100755 images/icons/page_white_zip.png create mode 100755 images/icons/page_word.png create mode 100755 images/icons/page_world.png create mode 100755 images/icons/paintbrush.png create mode 100755 images/icons/paintcan.png create mode 100755 images/icons/palette.png create mode 100644 images/icons/paperclip.gif create mode 100755 images/icons/paste_plain.png create mode 100755 images/icons/pencil.png create mode 100755 images/icons/phone.png create mode 100755 images/icons/phone_sound.png create mode 100755 images/icons/photo.png create mode 100755 images/icons/photos.png create mode 100755 images/icons/picture.png create mode 100755 images/icons/pictures.png create mode 100755 images/icons/pilcrow.png create mode 100755 images/icons/pill.png create mode 100755 images/icons/plugin.png create mode 100755 images/icons/plus.gif create mode 100644 images/icons/printer.gif create mode 100755 images/icons/printer.png create mode 100755 images/icons/printer_error.png create mode 100644 images/icons/question.png create mode 100755 images/icons/rainbow.png create mode 100755 images/icons/report.png create mode 100644 images/icons/resultset_first.gif create mode 100755 images/icons/resultset_first.png create mode 100644 images/icons/resultset_last.gif create mode 100755 images/icons/resultset_last.png create mode 100644 images/icons/resultset_next.gif create mode 100755 images/icons/resultset_next.png create mode 100644 images/icons/resultset_previous.gif create mode 100755 images/icons/resultset_previous.png create mode 100755 images/icons/rosette.png create mode 100755 images/icons/rss.png create mode 100755 images/icons/script.png create mode 100755 images/icons/server.png create mode 100755 images/icons/shading.png create mode 100755 images/icons/shield.png create mode 100755 images/icons/sitemap.png create mode 100755 images/icons/sitemap_color.png create mode 100644 images/icons/sort_asc.gif create mode 100644 images/icons/sort_desc.gif create mode 100755 images/icons/sound.png create mode 100755 images/icons/sound_add.png create mode 100755 images/icons/sound_delete.png create mode 100755 images/icons/sound_low.png create mode 100755 images/icons/sound_mute.png create mode 100755 images/icons/sound_none.png create mode 100755 images/icons/spellcheck.png create mode 100755 images/icons/sport_8ball.png create mode 100755 images/icons/sport_basketball.png create mode 100755 images/icons/sport_football.png create mode 100755 images/icons/sport_golf.png create mode 100755 images/icons/sport_raquet.png create mode 100755 images/icons/sport_shuttlecock.png create mode 100755 images/icons/sport_soccer.png create mode 100755 images/icons/sport_tennis.png create mode 100644 images/icons/star.gif create mode 100755 images/icons/star.png create mode 100755 images/icons/status_away.png create mode 100755 images/icons/status_busy.png create mode 100755 images/icons/status_offline.png create mode 100755 images/icons/status_online.png create mode 100755 images/icons/stop.png create mode 100755 images/icons/sum.png create mode 100644 images/icons/table.gif create mode 100755 images/icons/table.png create mode 100755 images/icons/table_edit.png create mode 100644 images/icons/table_row_delete.gif create mode 100755 images/icons/table_row_delete.png create mode 100644 images/icons/table_row_insert.gif create mode 100755 images/icons/table_row_insert.png create mode 100755 images/icons/table_save.png create mode 100755 images/icons/table_sort.png create mode 100755 images/icons/tag.png create mode 100755 images/icons/tag_blue.png create mode 100755 images/icons/tag_green.png create mode 100755 images/icons/tag_orange.png create mode 100755 images/icons/tag_pink.png create mode 100755 images/icons/tag_purple.png create mode 100755 images/icons/tag_red.png create mode 100755 images/icons/tag_yellow.png create mode 100755 images/icons/telephone.png create mode 100755 images/icons/television.png create mode 100755 images/icons/television_add.png create mode 100755 images/icons/television_delete.png create mode 100755 images/icons/text_uppercase.png create mode 100755 images/icons/textfield.png create mode 100755 images/icons/thumb_down.png create mode 100755 images/icons/thumb_up.png create mode 100755 images/icons/tick.png create mode 100755 images/icons/time.png create mode 100755 images/icons/timeline_marker.png create mode 100755 images/icons/transmit.png create mode 100755 images/icons/tux.png create mode 100644 images/icons/user.gif create mode 100755 images/icons/user.png create mode 100755 images/icons/user_add.png create mode 100755 images/icons/user_comment.png create mode 100755 images/icons/user_delete.png create mode 100755 images/icons/user_edit.png create mode 100755 images/icons/user_female.png create mode 100755 images/icons/user_go.png create mode 100755 images/icons/user_gray.png create mode 100755 images/icons/user_green.png create mode 100755 images/icons/user_orange.png create mode 100755 images/icons/user_red.png create mode 100755 images/icons/user_suit.png create mode 100644 images/icons/v_sprite.gif create mode 100755 images/icons/vcard.png create mode 100755 images/icons/vcard_add.png create mode 100755 images/icons/vcard_delete.png create mode 100755 images/icons/vcard_edit.png create mode 100755 images/icons/vector.png create mode 100755 images/icons/vector_add.png create mode 100755 images/icons/vector_delete.png create mode 100755 images/icons/wand.png create mode 100755 images/icons/weather_clouds.png create mode 100755 images/icons/weather_cloudy.png create mode 100755 images/icons/weather_lightning.png create mode 100755 images/icons/weather_rain.png create mode 100755 images/icons/weather_snow.png create mode 100755 images/icons/weather_sun.png create mode 100755 images/icons/webcam.png create mode 100644 images/icons/wntoolbar-icons.png create mode 100755 images/icons/world.png create mode 100755 images/icons/world_link.png create mode 100644 images/icons/wrench.gif create mode 100755 images/icons/wrench.png create mode 100755 images/icons/wrench_orange.png create mode 100755 images/icons/zoom.png create mode 100755 images/icons/zoom_in.png create mode 100755 images/icons/zoom_out.png create mode 100644 images/ui/blue-grad-1.gif create mode 100644 images/ui/button-load.gif create mode 100644 images/ui/checked_box.gif create mode 100644 images/ui/circle-cutout.gif create mode 100644 images/ui/down-arrow.gif create mode 100644 images/ui/down-arrow1.gif create mode 100644 images/ui/loading.gif create mode 100644 images/ui/loading_startup.gif create mode 100644 images/ui/next_pointer.gif create mode 100644 images/ui/no_img/no_img_f.gif create mode 100644 images/ui/no_img/no_img_m.gif create mode 100644 images/ui/plain_box.gif create mode 100644 images/ui/prev_pointer.gif create mode 100644 images/ui/rc/comment_top.gif create mode 100644 images/ui/rc/tab-left-CCC.gif create mode 100644 images/ui/rc/tab-left-EEE.gif create mode 100644 images/ui/rc/tab-right-CCC.gif create mode 100644 images/ui/rc/tab-right-EEE.gif create mode 100644 images/ui/rc/tb-left-bottom.gif create mode 100644 images/ui/rc/tb-right-bottom.gif create mode 100644 images/ui/rc/tray-left-bottom.gif create mode 100644 images/ui/rc/tray-left-top.gif create mode 100644 images/ui/right-arrow.gif create mode 100644 images/ui/spinner.gif create mode 100644 images/ui/square_loading.gif create mode 100644 images/ui/star.gif create mode 100644 images/ui/star_plain.gif create mode 100644 images/ui/tick.gif create mode 100644 images/ui/vote_down.gif create mode 100644 images/ui/vote_up.gif create mode 100755 index.cgi create mode 100644 js/app.js create mode 100755 js/edit_area/autocompletion.js create mode 100755 js/edit_area/edit_area.css create mode 100755 js/edit_area/edit_area.js create mode 100755 js/edit_area/edit_area_compressor.php create mode 100755 js/edit_area/edit_area_full.gz create mode 100755 js/edit_area/edit_area_full.js create mode 100755 js/edit_area/edit_area_full_with_plugins.gz create mode 100755 js/edit_area/edit_area_full_with_plugins.js create mode 100755 js/edit_area/edit_area_functions.js create mode 100755 js/edit_area/edit_area_loader.js create mode 100755 js/edit_area/elements_functions.js create mode 100755 js/edit_area/highlight.js create mode 100755 js/edit_area/images/autocompletion.gif create mode 100755 js/edit_area/images/close.gif create mode 100755 js/edit_area/images/fullscreen.gif create mode 100755 js/edit_area/images/go_to_line.gif create mode 100755 js/edit_area/images/help.gif create mode 100755 js/edit_area/images/highlight.gif create mode 100755 js/edit_area/images/load.gif create mode 100755 js/edit_area/images/move.gif create mode 100755 js/edit_area/images/newdocument.gif create mode 100755 js/edit_area/images/opacity.png create mode 100755 js/edit_area/images/processing.gif create mode 100755 js/edit_area/images/redo.gif create mode 100755 js/edit_area/images/reset_highlight.gif create mode 100755 js/edit_area/images/save.gif create mode 100755 js/edit_area/images/search.gif create mode 100755 js/edit_area/images/smooth_selection.gif create mode 100755 js/edit_area/images/spacer.gif create mode 100755 js/edit_area/images/statusbar_resize.gif create mode 100755 js/edit_area/images/undo.gif create mode 100755 js/edit_area/images/word_wrap.gif create mode 100755 js/edit_area/keyboard.js create mode 100755 js/edit_area/langs/bg.js create mode 100755 js/edit_area/langs/cs.js create mode 100755 js/edit_area/langs/de.js create mode 100755 js/edit_area/langs/dk.js create mode 100755 js/edit_area/langs/en.js create mode 100755 js/edit_area/langs/eo.js create mode 100755 js/edit_area/langs/es.js create mode 100755 js/edit_area/langs/fi.js create mode 100755 js/edit_area/langs/fr.js create mode 100755 js/edit_area/langs/hr.js create mode 100755 js/edit_area/langs/it.js create mode 100755 js/edit_area/langs/ja.js create mode 100755 js/edit_area/langs/mk.js create mode 100755 js/edit_area/langs/nl.js create mode 100755 js/edit_area/langs/pl.js create mode 100755 js/edit_area/langs/pt.js create mode 100755 js/edit_area/langs/ru.js create mode 100755 js/edit_area/langs/sk.js create mode 100755 js/edit_area/langs/zh.js create mode 100755 js/edit_area/license_apache.txt create mode 100755 js/edit_area/license_bsd.txt create mode 100755 js/edit_area/license_lgpl.txt create mode 100755 js/edit_area/manage_area.js create mode 100755 js/edit_area/plugins/charmap/charmap.js create mode 100755 js/edit_area/plugins/charmap/css/charmap.css create mode 100755 js/edit_area/plugins/charmap/images/charmap.gif create mode 100755 js/edit_area/plugins/charmap/jscripts/map.js create mode 100755 js/edit_area/plugins/charmap/langs/bg.js create mode 100755 js/edit_area/plugins/charmap/langs/cs.js create mode 100755 js/edit_area/plugins/charmap/langs/de.js create mode 100755 js/edit_area/plugins/charmap/langs/dk.js create mode 100755 js/edit_area/plugins/charmap/langs/en.js create mode 100755 js/edit_area/plugins/charmap/langs/eo.js create mode 100755 js/edit_area/plugins/charmap/langs/es.js create mode 100755 js/edit_area/plugins/charmap/langs/fr.js create mode 100755 js/edit_area/plugins/charmap/langs/hr.js create mode 100755 js/edit_area/plugins/charmap/langs/it.js create mode 100755 js/edit_area/plugins/charmap/langs/ja.js create mode 100755 js/edit_area/plugins/charmap/langs/mk.js create mode 100755 js/edit_area/plugins/charmap/langs/nl.js create mode 100755 js/edit_area/plugins/charmap/langs/pl.js create mode 100755 js/edit_area/plugins/charmap/langs/pt.js create mode 100755 js/edit_area/plugins/charmap/langs/ru.js create mode 100755 js/edit_area/plugins/charmap/langs/sk.js create mode 100755 js/edit_area/plugins/charmap/langs/zh.js create mode 100755 js/edit_area/plugins/charmap/popup.html create mode 100755 js/edit_area/plugins/test/css/test.css create mode 100755 js/edit_area/plugins/test/images/Thumbs.db create mode 100755 js/edit_area/plugins/test/images/test.gif create mode 100755 js/edit_area/plugins/test/langs/bg.js create mode 100755 js/edit_area/plugins/test/langs/cs.js create mode 100755 js/edit_area/plugins/test/langs/de.js create mode 100755 js/edit_area/plugins/test/langs/dk.js create mode 100755 js/edit_area/plugins/test/langs/en.js create mode 100755 js/edit_area/plugins/test/langs/eo.js create mode 100755 js/edit_area/plugins/test/langs/es.js create mode 100755 js/edit_area/plugins/test/langs/fr.js create mode 100755 js/edit_area/plugins/test/langs/hr.js create mode 100755 js/edit_area/plugins/test/langs/it.js create mode 100755 js/edit_area/plugins/test/langs/ja.js create mode 100755 js/edit_area/plugins/test/langs/mk.js create mode 100755 js/edit_area/plugins/test/langs/nl.js create mode 100755 js/edit_area/plugins/test/langs/pl.js create mode 100755 js/edit_area/plugins/test/langs/pt.js create mode 100755 js/edit_area/plugins/test/langs/ru.js create mode 100755 js/edit_area/plugins/test/langs/sk.js create mode 100755 js/edit_area/plugins/test/langs/zh.js create mode 100755 js/edit_area/plugins/test/test.js create mode 100755 js/edit_area/plugins/test/test2.js create mode 100755 js/edit_area/reg_syntax.js create mode 100755 js/edit_area/reg_syntax/basic.js create mode 100755 js/edit_area/reg_syntax/brainfuck.js create mode 100755 js/edit_area/reg_syntax/c.js create mode 100755 js/edit_area/reg_syntax/coldfusion.js create mode 100755 js/edit_area/reg_syntax/cpp.js create mode 100755 js/edit_area/reg_syntax/css.js create mode 100755 js/edit_area/reg_syntax/html.js create mode 100755 js/edit_area/reg_syntax/java.js create mode 100755 js/edit_area/reg_syntax/js.js create mode 100755 js/edit_area/reg_syntax/pas.js create mode 100755 js/edit_area/reg_syntax/perl.js create mode 100755 js/edit_area/reg_syntax/php.js create mode 100755 js/edit_area/reg_syntax/python.js create mode 100755 js/edit_area/reg_syntax/robotstxt.js create mode 100755 js/edit_area/reg_syntax/ruby.js create mode 100755 js/edit_area/reg_syntax/sql.js create mode 100755 js/edit_area/reg_syntax/tsql.js create mode 100755 js/edit_area/reg_syntax/vb.js create mode 100755 js/edit_area/reg_syntax/xml.js create mode 100755 js/edit_area/regexp.js create mode 100755 js/edit_area/resize_area.js create mode 100755 js/edit_area/search_replace.js create mode 100755 js/edit_area/template.html create mode 100644 js/form.compressed.js create mode 100644 js/globals.js create mode 100644 js/jquery/excanvas.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.barRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.barRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.categoryAxisRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.categoryAxisRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.cursor.js create mode 100644 js/jquery/jqplot-plugins/jqplot.cursor.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.dragable.js create mode 100644 js/jquery/jqplot-plugins/jqplot.dragable.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.highlighter.js create mode 100644 js/jquery/jqplot-plugins/jqplot.highlighter.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.logAxisRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.logAxisRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.mekkoAxisRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.mekkoAxisRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.mekkoRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.mekkoRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.ohlcRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.ohlcRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.pieRenderer.js create mode 100644 js/jquery/jqplot-plugins/jqplot.pieRenderer.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.pointLabels.js create mode 100644 js/jquery/jqplot-plugins/jqplot.pointLabels.js.orig create mode 100644 js/jquery/jqplot-plugins/jqplot.pointLabels.min.js create mode 100644 js/jquery/jqplot-plugins/jqplot.trendline.js create mode 100644 js/jquery/jqplot-plugins/jqplot.trendline.min.js create mode 100755 js/jquery/jquery-ui.min.js create mode 100644 js/jquery/jquery.corners.min.js create mode 100644 js/jquery/jquery.flot.js create mode 100644 js/jquery/jquery.jqplot.min.js create mode 100755 js/jquery/jquery.min.js create mode 100644 js/jquery/jquery.tools.min.js create mode 100644 js/model/doclist.js create mode 100644 js/model/local_data.js create mode 100644 js/report.compressed.js create mode 100644 js/tiny_mce_33/custom_content.css create mode 100644 js/tiny_mce_33/jquery.tinymce.js create mode 100644 js/tiny_mce_33/langs/en.js create mode 100644 js/tiny_mce_33/license.txt create mode 100644 js/tiny_mce_33/plugins/advhr/css/advhr.css create mode 100644 js/tiny_mce_33/plugins/advhr/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/advhr/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/advhr/js/rule.js create mode 100644 js/tiny_mce_33/plugins/advhr/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/advhr/rule.htm create mode 100644 js/tiny_mce_33/plugins/advimage/css/advimage.css create mode 100644 js/tiny_mce_33/plugins/advimage/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/advimage/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/advimage/image.htm create mode 100644 js/tiny_mce_33/plugins/advimage/img/sample.gif create mode 100644 js/tiny_mce_33/plugins/advimage/js/image.js create mode 100644 js/tiny_mce_33/plugins/advimage/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/advlink/css/advlink.css create mode 100644 js/tiny_mce_33/plugins/advlink/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/advlink/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/advlink/js/advlink.js create mode 100644 js/tiny_mce_33/plugins/advlink/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/advlink/link.htm create mode 100644 js/tiny_mce_33/plugins/advlist/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/advlist/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/autoresize/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/autoresize/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/autosave/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/autosave/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/autosave/langs/en.js create mode 100644 js/tiny_mce_33/plugins/bbcode/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/bbcode/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/contextmenu/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/contextmenu/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/directionality/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/directionality/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/emotions/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/emotions/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/emotions/emotions.htm create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-cool.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-cry.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-embarassed.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-foot-in-mouth.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-frown.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-innocent.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-kiss.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-laughing.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-money-mouth.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-sealed.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-smile.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-surprised.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-tongue-out.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-undecided.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-wink.gif create mode 100644 js/tiny_mce_33/plugins/emotions/img/smiley-yell.gif create mode 100644 js/tiny_mce_33/plugins/emotions/js/emotions.js create mode 100644 js/tiny_mce_33/plugins/emotions/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/example/dialog.htm create mode 100644 js/tiny_mce_33/plugins/example/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/example/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/example/img/example.gif create mode 100644 js/tiny_mce_33/plugins/example/js/dialog.js create mode 100644 js/tiny_mce_33/plugins/example/langs/en.js create mode 100644 js/tiny_mce_33/plugins/example/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/fullpage/css/fullpage.css create mode 100644 js/tiny_mce_33/plugins/fullpage/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/fullpage/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/fullpage/fullpage.htm create mode 100644 js/tiny_mce_33/plugins/fullpage/js/fullpage.js create mode 100644 js/tiny_mce_33/plugins/fullpage/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/fullscreen/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/fullscreen/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/fullscreen/fullscreen.htm create mode 100644 js/tiny_mce_33/plugins/iespell/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/iespell/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/inlinepopups/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/inlinepopups/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/alert.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/button.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/corners.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif create mode 100644 js/tiny_mce_33/plugins/inlinepopups/skins/clearlooks2/window.css create mode 100644 js/tiny_mce_33/plugins/inlinepopups/template.htm create mode 100644 js/tiny_mce_33/plugins/insertdatetime/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/insertdatetime/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/layer/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/layer/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/legacyoutput/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/legacyoutput/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/media/css/content.css create mode 100644 js/tiny_mce_33/plugins/media/css/media.css create mode 100644 js/tiny_mce_33/plugins/media/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/media/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/media/img/flash.gif create mode 100644 js/tiny_mce_33/plugins/media/img/flv_player.swf create mode 100644 js/tiny_mce_33/plugins/media/img/quicktime.gif create mode 100644 js/tiny_mce_33/plugins/media/img/realmedia.gif create mode 100644 js/tiny_mce_33/plugins/media/img/shockwave.gif create mode 100644 js/tiny_mce_33/plugins/media/img/trans.gif create mode 100644 js/tiny_mce_33/plugins/media/img/windowsmedia.gif create mode 100644 js/tiny_mce_33/plugins/media/js/embed.js create mode 100644 js/tiny_mce_33/plugins/media/js/media.js create mode 100644 js/tiny_mce_33/plugins/media/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/media/media.htm create mode 100644 js/tiny_mce_33/plugins/nonbreaking/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/nonbreaking/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/noneditable/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/noneditable/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/pagebreak/css/content.css create mode 100644 js/tiny_mce_33/plugins/pagebreak/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/pagebreak/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/pagebreak/img/pagebreak.gif create mode 100644 js/tiny_mce_33/plugins/pagebreak/img/trans.gif create mode 100644 js/tiny_mce_33/plugins/paste/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/paste/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/paste/js/pastetext.js create mode 100644 js/tiny_mce_33/plugins/paste/js/pasteword.js create mode 100644 js/tiny_mce_33/plugins/paste/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/paste/pastetext.htm create mode 100644 js/tiny_mce_33/plugins/paste/pasteword.htm create mode 100644 js/tiny_mce_33/plugins/preview/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/preview/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/preview/example.html create mode 100644 js/tiny_mce_33/plugins/preview/jscripts/embed.js create mode 100644 js/tiny_mce_33/plugins/preview/preview.html create mode 100644 js/tiny_mce_33/plugins/print/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/print/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/save/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/save/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/searchreplace/css/searchreplace.css create mode 100644 js/tiny_mce_33/plugins/searchreplace/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/searchreplace/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/searchreplace/js/searchreplace.js create mode 100644 js/tiny_mce_33/plugins/searchreplace/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/searchreplace/searchreplace.htm create mode 100644 js/tiny_mce_33/plugins/spellchecker/css/content.css create mode 100644 js/tiny_mce_33/plugins/spellchecker/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/spellchecker/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/spellchecker/img/wline.gif create mode 100644 js/tiny_mce_33/plugins/style/css/props.css create mode 100644 js/tiny_mce_33/plugins/style/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/style/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/style/js/props.js create mode 100644 js/tiny_mce_33/plugins/style/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/style/props.htm create mode 100644 js/tiny_mce_33/plugins/tabfocus/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/tabfocus/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/table/cell.htm create mode 100644 js/tiny_mce_33/plugins/table/css/cell.css create mode 100644 js/tiny_mce_33/plugins/table/css/row.css create mode 100644 js/tiny_mce_33/plugins/table/css/table.css create mode 100644 js/tiny_mce_33/plugins/table/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/table/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/table/js/cell.js create mode 100644 js/tiny_mce_33/plugins/table/js/merge_cells.js create mode 100644 js/tiny_mce_33/plugins/table/js/row.js create mode 100644 js/tiny_mce_33/plugins/table/js/table.js create mode 100644 js/tiny_mce_33/plugins/table/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/table/merge_cells.htm create mode 100644 js/tiny_mce_33/plugins/table/row.htm create mode 100644 js/tiny_mce_33/plugins/table/table.htm create mode 100644 js/tiny_mce_33/plugins/template/blank.htm create mode 100644 js/tiny_mce_33/plugins/template/css/template.css create mode 100644 js/tiny_mce_33/plugins/template/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/template/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/template/js/template.js create mode 100644 js/tiny_mce_33/plugins/template/langs/en_dlg.js create mode 100644 js/tiny_mce_33/plugins/template/template.htm create mode 100644 js/tiny_mce_33/plugins/visualchars/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/visualchars/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/wordcount/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/wordcount/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/abbr.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/acronym.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/attributes.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/cite.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/css/attributes.css create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/css/popup.css create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/del.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/editor_plugin.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/editor_plugin_src.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/ins.htm create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/abbr.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/acronym.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/attributes.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/cite.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/del.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/element_common.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/js/ins.js create mode 100644 js/tiny_mce_33/plugins/xhtmlxtras/langs/en_dlg.js create mode 100644 js/tiny_mce_33/themes/advanced/about.htm create mode 100644 js/tiny_mce_33/themes/advanced/anchor.htm create mode 100644 js/tiny_mce_33/themes/advanced/charmap.htm create mode 100644 js/tiny_mce_33/themes/advanced/color_picker.htm create mode 100644 js/tiny_mce_33/themes/advanced/editor_template.js create mode 100644 js/tiny_mce_33/themes/advanced/editor_template_src.js create mode 100644 js/tiny_mce_33/themes/advanced/image.htm create mode 100644 js/tiny_mce_33/themes/advanced/img/colorpicker.jpg create mode 100644 js/tiny_mce_33/themes/advanced/img/icons.gif create mode 100644 js/tiny_mce_33/themes/advanced/js/about.js create mode 100644 js/tiny_mce_33/themes/advanced/js/anchor.js create mode 100644 js/tiny_mce_33/themes/advanced/js/charmap.js create mode 100644 js/tiny_mce_33/themes/advanced/js/color_picker.js create mode 100644 js/tiny_mce_33/themes/advanced/js/image.js create mode 100644 js/tiny_mce_33/themes/advanced/js/link.js create mode 100644 js/tiny_mce_33/themes/advanced/js/source_editor.js create mode 100644 js/tiny_mce_33/themes/advanced/langs/en.js create mode 100644 js/tiny_mce_33/themes/advanced/langs/en_dlg.js create mode 100644 js/tiny_mce_33/themes/advanced/link.htm create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/content.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/dialog.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/buttons.png create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/items.gif create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/menu_arrow.gif create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/menu_check.gif create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/progress.gif create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/img/tabs.gif create mode 100644 js/tiny_mce_33/themes/advanced/skins/default/ui.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/content.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/dialog.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/img/button_bg.png create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/img/button_bg_black.png create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/img/button_bg_silver.png create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/ui.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/ui_black.css create mode 100644 js/tiny_mce_33/themes/advanced/skins/o2k7/ui_silver.css create mode 100644 js/tiny_mce_33/themes/advanced/source_editor.htm create mode 100644 js/tiny_mce_33/themes/simple/editor_template.js create mode 100644 js/tiny_mce_33/themes/simple/editor_template_src.js create mode 100644 js/tiny_mce_33/themes/simple/img/icons.gif create mode 100644 js/tiny_mce_33/themes/simple/langs/en.js create mode 100644 js/tiny_mce_33/themes/simple/skins/default/content.css create mode 100644 js/tiny_mce_33/themes/simple/skins/default/ui.css create mode 100644 js/tiny_mce_33/themes/simple/skins/o2k7/content.css create mode 100644 js/tiny_mce_33/themes/simple/skins/o2k7/img/button_bg.png create mode 100644 js/tiny_mce_33/themes/simple/skins/o2k7/ui.css create mode 100644 js/tiny_mce_33/tiny_mce.js create mode 100644 js/tiny_mce_33/tiny_mce_popup.js create mode 100644 js/tiny_mce_33/tiny_mce_src.js create mode 100644 js/tiny_mce_33/utils/editable_selects.js create mode 100644 js/tiny_mce_33/utils/form_utils.js create mode 100644 js/tiny_mce_33/utils/mctabs.js create mode 100644 js/tiny_mce_33/utils/validate.js create mode 100644 js/user.js create mode 100644 js/utils/browser_detect.js create mode 100644 js/utils/datatype.js create mode 100644 js/utils/datetime.js create mode 100644 js/utils/dom.js create mode 100644 js/utils/handler.js create mode 100644 js/utils/json.js create mode 100644 js/utils/msgprint.js create mode 100644 js/utils/printElement.js create mode 100755 js/utils/rsh.compressed.js create mode 100644 js/webpage/about.js create mode 100644 js/webpage/body.js create mode 100644 js/webpage/docbrowser.js create mode 100644 js/webpage/error_console.js create mode 100644 js/webpage/freeze_page.js create mode 100644 js/webpage/history.js create mode 100644 js/webpage/loaders.js create mode 100644 js/webpage/page.js create mode 100644 js/webpage/page_header.js create mode 100644 js/webpage/search.js create mode 100644 js/webpage/spinner.js create mode 100644 js/webpage/uploader.js create mode 100644 js/webpage/wntoolbar.js create mode 100644 js/widgets/autosuggest.js create mode 100644 js/widgets/calendar.js create mode 100644 js/widgets/dialog.js create mode 100644 js/widgets/export_query.js create mode 100644 js/widgets/form/attachments.js create mode 100644 js/widgets/form/clientscriptAPI.js create mode 100644 js/widgets/form/email.js create mode 100644 js/widgets/form/fields.js create mode 100644 js/widgets/form/form.js create mode 100644 js/widgets/form/form_comments.js create mode 100644 js/widgets/form/form_container.js create mode 100644 js/widgets/form/form_fields.js create mode 100644 js/widgets/form/form_grid.js create mode 100644 js/widgets/form/form_header.js create mode 100644 js/widgets/form/grid.js create mode 100644 js/widgets/form/print_format.js create mode 100644 js/widgets/layout.js create mode 100644 js/widgets/list_selector.js create mode 100644 js/widgets/listing.js create mode 100644 js/widgets/menu.js create mode 100644 js/widgets/print_query.js create mode 100644 js/widgets/report_builder/bargraph.js create mode 100644 js/widgets/report_builder/calculator.js create mode 100644 js/widgets/report_builder/datatable.js create mode 100644 js/widgets/report_builder/report_builder.js create mode 100644 js/widgets/select.js create mode 100644 js/widgets/tabbedpage.js create mode 100644 js/widgets/tags.js create mode 100644 js/widgets/tree.js create mode 100644 js/wn/modules.js create mode 100644 js/wn/page_layout.js create mode 100644 js/wn/widgets/dialog.js create mode 100644 js/wn/widgets/doc_column_view.js create mode 100644 js/wn/widgets/filters.js create mode 100644 js/wn/widgets/follow.js create mode 100644 js/wn/widgets/footer.js create mode 100644 js/wn/widgets/form/attachments.js create mode 100644 js/wn/widgets/form/comments.js create mode 100644 js/wn/widgets/form/sidebar.js create mode 100644 js/wn/widgets/listing.js create mode 100644 js/wn/widgets/page_sidebar.js create mode 100644 js/wnf.compressed.js create mode 100644 robots.txt create mode 100644 sitemap.xml create mode 100644 transfer.html create mode 100644 webnotes.manifestold diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000000..58bfec90b6 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,81 @@ +INSTALL.txt +=========== + +Web Notes Framework Installation guide + +Web Notes Framework (WNF) is a meta-data driven web app framework. After install, you build +and configure your application from the web browser. + +WNF requires the following applications + +1. Python +2. MySQL +3. MySQL-Python (connector) +4. simplejson (for Python 2.4 or lower) +5. email (for Python 2.4 or lower) +6. pytz (easy_install pytz) +7. Apache +8. PIL (optional - for image processing (thumbnails etc) + - yum install libjpeg-devel + - yum install python-imaging + ) + +------------------------------------------------------------------------ +1. Create a databse instance for your application + + Call the install script with the following options. For more options use -h + + python [folder]/cgi-bin/webnotes/install_lib/install.py MYSQL_ROOT_LOGIN MYSQL_ROOT_PASSWORD DBNAME + +------------------------------------------------------------------------ +2. Setup defs.py + + The framework picks up the database details from cgi-bin/webnotes/defs.py + + You need to edit this file and set your database name and other options + +------------------------------------------------------------------------ +3. Configuring Apache + +a. You must set Apache to execute index.cgi file, one way to do this is to add cgi handler + and add ExecCGI in the options directive. + +b. You can also add couple of lines below to block Apache from rendering .py files + + RewriteEngine on + RewriteRule \.py - [F] + +c. Add "index.cgi" to DirectoryIndex + + +------------------------------------------------------------------------ +4. Login to application + +Start Apache, go to your web-browser and point to the folder where you installed the framework + +The default logins are: + +login: Administrator +password: admin + +------------------------------------------------------------------------ + +Step by step instructions on CentOS/Fedora: + 0.Check out the source code. + 1. Modify the v170/cgi-bin/webnotes/defs file to your required settings and rename it to defs.py + 2. yum install mysql + 3. yum install httpd + 4. yum install MySQL-python + 5. yum install python-setuptools + 6. easy_install pytz + 7. easy_install email + 8. easy_install simplejson suds + 9. easy_install pygeoip (optional for geo ip) + 9. yum install libjpeg-devel (optional) + 10.yum install python-imaging (optional) + + 11. Edit /etc/httpd/conf/httpd.conf and add the options as mentioned above. + 12. from the trunk/v170/cgi-bin folder run python webnotes/install_lib/install.py install + + + diff --git a/blank.html b/blank.html new file mode 100755 index 0000000000..2488c5be1c --- /dev/null +++ b/blank.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + +

blank.html - Needed for Internet Explorer's hidden iframe

+

+ + + diff --git a/blank1.html b/blank1.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/backupall.py b/cgi-bin/backupall.py new file mode 100644 index 0000000000..eb4954b0c6 --- /dev/null +++ b/cgi-bin/backupall.py @@ -0,0 +1,24 @@ +import os + +# go to current directory +os.chdir(__file__[:-12]) + +import webnotes.utils.backups + +webnotes.utils.backups.backup_all() + +# send the daily backup to the pair server +import webnotes.defs +if hasattr(webnotes.defs,'ps_host'): + import ftplib, time + + ftp = ftplib.FTP(webnotes.defs.ps_host, webnotes.defs.ps_login, webnotes.defs.ps_pwd) + ftp.cwd('pair_backups') + fname = 'daily-' + time.strftime('%Y-%m-%d') + '.tar.gz' + f = open('/backups/daily/' + fname, 'rb') + ftp.storbinary('STOR ' + webnotes.defs.server_prefix + '-' + fname, f) + ftp.quit() + + # delete from local pair directory + if hasattr(webnotes.defs, 'pair_dir') and len(os.listdir(webnotes.defs.pair_dir)) > 3: + delete_oldest_file(webnotes.defs.pair_dir) \ No newline at end of file diff --git a/cgi-bin/core/Module Def/Core/Core.txt b/cgi-bin/core/Module Def/Core/Core.txt new file mode 100644 index 0000000000..0316ef09cc --- /dev/null +++ b/cgi-bin/core/Module Def/Core/Core.txt @@ -0,0 +1,84 @@ +[ + { + 'creation': '2011-02-12 10:07:59', + 'disabled': 'No', + 'docstatus': 0, + 'doctype': 'Module Def', + 'doctype_list': None, + 'file_list': None, + 'idx': None, + 'is_hidden': 'Yes', + 'last_updated_date': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'module_desc': None, + 'module_icon': None, + 'module_label': 'Core', + 'module_name': 'Core', + 'module_page': None, + 'module_seq': None, + 'name': 'Core', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'trash_reason': None, + 'widget_code': None + }, + { + 'click_function': None, + 'creation': '2011-02-12 10:07:59', + 'description': None, + 'display_name': None, + 'doc_name': 'Pages', + 'doc_type': 'Separator', + 'docstatus': 0, + 'doctype': 'Module Def Item', + 'fields': None, + 'hide': None, + 'icon': None, + 'idx': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDI00288', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'items', + 'parenttype': 'Module Def' + }, + { + 'click_function': None, + 'creation': '2011-02-12 10:07:59', + 'description': None, + 'display_name': 'Manage Users', + 'doc_name': 'Manage Users', + 'doc_type': 'Pages', + 'docstatus': 0, + 'doctype': 'Module Def Item', + 'fields': None, + 'hide': None, + 'icon': None, + 'idx': None, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDI00289', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'items', + 'parenttype': 'Module Def' + }, + { + 'creation': '2011-02-12 10:07:59', + 'docstatus': 0, + 'doctype': 'Module Def Role', + 'idx': 1, + 'modified': '2011-02-12 10:07:59', + 'modified_by': 'Administrator', + 'name': 'MDR00076', + 'owner': 'Administrator', + 'parent': 'Core', + 'parentfield': 'roles', + 'parenttype': 'Module Def', + 'role': 'Administrator' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/Administrator/Administrator.txt b/cgi-bin/core/Role/Administrator/Administrator.txt new file mode 100644 index 0000000000..d052c03f94 --- /dev/null +++ b/cgi-bin/core/Role/Administrator/Administrator.txt @@ -0,0 +1,17 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': 0, + 'modified': '2011-06-03 10:08:30', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Administrator', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'Administrator' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/All/All.txt b/cgi-bin/core/Role/All/All.txt new file mode 100644 index 0000000000..ac6e7f06cf --- /dev/null +++ b/cgi-bin/core/Role/All/All.txt @@ -0,0 +1,17 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': None, + 'modified': '2011-06-03 10:08:41', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'All', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'All' + } +] \ No newline at end of file diff --git a/cgi-bin/core/Role/Guest/Guest.txt b/cgi-bin/core/Role/Guest/Guest.txt new file mode 100644 index 0000000000..52c23570bd --- /dev/null +++ b/cgi-bin/core/Role/Guest/Guest.txt @@ -0,0 +1,47 @@ +[ + { + 'creation': '2010-08-08 17:08:51', + 'docstatus': 0, + 'doctype': 'Role', + 'idx': None, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Guest', + 'owner': 'Administrator', + 'parent': None, + 'parentfield': None, + 'parenttype': None, + 'role_name': 'Guest' + }, + { + 'creation': '2010-08-08 17:08:51', + 'defkey': 'hide_webnotes_toolbar', + 'defvalue': '1', + 'docstatus': 0, + 'doctype': 'DefaultValue', + 'idx': 1, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'name': 'DEF000004', + 'owner': 'Administrator', + 'parent': 'Guest', + 'parentfield': 'defaults', + 'parenttype': 'Role' + }, + { + 'creation': '2010-08-08 17:08:51', + 'defkey': 'hide_sidebars', + 'defvalue': '1', + 'docstatus': 0, + 'doctype': 'DefaultValue', + 'idx': 2, + 'modified': '2011-06-03 10:08:51', + 'modified_by': 'Administrator', + 'name': 'DEF000005', + 'owner': 'Administrator', + 'parent': 'Guest', + 'parentfield': 'defaults', + 'parenttype': 'Role' + } +] \ No newline at end of file diff --git a/cgi-bin/core/__init__.py b/cgi-bin/core/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/__init__.py b/cgi-bin/core/doctype/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/comment_widget_record/__init__.py b/cgi-bin/core/doctype/comment_widget_record/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt b/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt new file mode 100644 index 0000000000..7b83186625 --- /dev/null +++ b/cgi-bin/core/doctype/comment_widget_record/comment_widget_record.txt @@ -0,0 +1,358 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'CWR/.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:55', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:10:05', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Comment Widget Record', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 10 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-08-08 17:08:55', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:08:55', + 'modified_by': 'Administrator', + 'name': '_PERM00118', + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Comment', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00686', + 'no_copy': None, + 'oldfieldname': 'comment', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_by', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Comment By', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00687', + 'no_copy': None, + 'oldfieldname': 'comment_by', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_by_fullname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Comment By Fullname', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00688', + 'no_copy': None, + 'oldfieldname': 'comment_by_fullname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_date', + 'fieldtype': 'Date', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Comment Date', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00689', + 'no_copy': None, + 'oldfieldname': 'comment_date', + 'oldfieldtype': 'Date', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_time', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Comment Time', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00690', + 'no_copy': None, + 'oldfieldname': 'comment_time', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_doctype', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Comment Doctype', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00691', + 'no_copy': None, + 'oldfieldname': 'comment_doctype', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'comment_docname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Comment Docname', + 'modified': '2011-04-05 09:58:09', + 'modified_by': 'Administrator', + 'name': '_FL00692', + 'no_copy': None, + 'oldfieldname': 'comment_docname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'post_topic', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Post Topic', + 'modified': '2010-08-08 17:08:55', + 'modified_by': 'Administrator', + 'name': '_FL00693', + 'no_copy': None, + 'oldfieldname': 'post_topic', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Comment Widget Record', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/control_panel/__init__.py b/cgi-bin/core/doctype/control_panel/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/control_panel/control_panel.py b/cgi-bin/core/doctype/control_panel/control_panel.py new file mode 100644 index 0000000000..da1786b2ea --- /dev/null +++ b/cgi-bin/core/doctype/control_panel/control_panel.py @@ -0,0 +1,36 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import cint, flt +from webnotes.model.doc import Document +from webnotes.model.code import get_obj +from webnotes import session, form, is_testing, msgprint, errprint + +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist): + self.doc = doc + self.doclist = doclist + + def on_update(self): + # clear cache on save + sql("delete from __SessionCache") + + def upload_many(self,form): + pass + + def upload_callback(self,form): + pass + + def execute_test(self, arg=''): + if webnotes.user.name=='Guest': + raise Exception, 'Guest cannot call execute test!' + out = '' + exec(arg and arg or self.doc.test_code) + webnotes.msgprint('that worked!') + return out diff --git a/cgi-bin/core/doctype/control_panel/control_panel.txt b/cgi-bin/core/doctype/control_panel/control_panel.txt new file mode 100644 index 0000000000..eff2a542d4 --- /dev/null +++ b/cgi-bin/core/doctype/control_panel/control_panel.txt @@ -0,0 +1,1933 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 1, + 'istable': 0, + 'max_attachments': None, + 'menu_index': 5, + 'modified': '2010-11-10 13:05:51', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Control Panel', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 1, + 'smallicon': 'controller.png', + 'use_template': None, + 'version': 18 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_PERM00001', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'General', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00001', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'date_format', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Date Format', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00002', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'currency_format', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Currency Format', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00421', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': 'Millions\nLacs', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-29 14:06:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'password_expiry_days', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Password Expires in (days)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00243', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-07-09 13:55:51', + 'default': None, + 'depends_on': None, + 'description': 'Format: hh:mm example for one hour expiry set as 01:00. \nMax expiry will be 72 hours. Default is 24 hours', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'session_expiry', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Session Expires in (time)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00303', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': '', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-08 14:18:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'new_style_search', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'New Style Search', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00264', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'title', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Title', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00004', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'account_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Account Id', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00005', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'company_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Company Name', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00422', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'industry', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Industry', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00423', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'time_zone', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Time Zone', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00424', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'country', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Country', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00425', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-07-09 14:53:42', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'sync_with_gateway', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Sync with Gateway', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00304', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_manager', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'System Manager', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00006', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'Profile', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_manager_email', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'System Manager Email', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00007', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'total_sms_sent', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Total SMS Sent', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00305', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Home Pages', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00306', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:14:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default_home_pages', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Default Home Pages', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00356', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Default Home Page', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'home_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Home Page', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00008', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-20 10:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Startup', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00289', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-20 10:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'startup_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Startup Code (JS)', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00288', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'startup_css', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Startup CSS', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00429', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Display', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00009', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Display Options', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00010', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '100%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': '', + 'description': 'Default page width is auto', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'Page WIdth', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00011', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_webnotes_toolbar', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Hide WebNotes Toolbar', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00012', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:12:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'background_color', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Background Color', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00278', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 28, + 'in_filter': None, + 'label': 'Header / Footer', + 'modified': '2009-11-25 10:13:38', + 'modified_by': 'Administrator', + 'name': '_FL00013', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'Default header height is 40px', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'header_height', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 29, + 'in_filter': None, + 'label': 'Header Height', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00014', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'client_name', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 30, + 'in_filter': None, + 'label': 'Header HTML', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00015', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'footer_height', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 31, + 'in_filter': None, + 'label': 'Footer Height', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00016', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'footer_html', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 32, + 'in_filter': None, + 'label': 'Footer HTML', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00017', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head_image', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 33, + 'in_filter': None, + 'label': 'Letter Head Image', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00426', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 34, + 'in_filter': None, + 'label': 'Letter Head', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00018', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': 1, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'client_logo', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 35, + 'in_filter': None, + 'label': 'Client Logo', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00019', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'File', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 36, + 'in_filter': None, + 'label': 'Mail Server', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00020', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': 'Enter Email Id to receive Error Report sent by users.\nE.g.: support@iwebnotes.com', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'support_email_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 37, + 'in_filter': None, + 'label': 'Support Email Id', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00427', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': 'automail@notesandreports.com', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'auto_email_id', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 38, + 'in_filter': None, + 'label': 'Auto Email Id', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00003', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': 'e.g. mail.webnotestech.com', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'outgoing_mail_server', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 39, + 'in_filter': None, + 'label': 'Outgoing Mail Server', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00279', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': '', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-11-25 10:13:39', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_port', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 40, + 'in_filter': None, + 'label': 'Mail Port', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00388', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-11-25 10:13:39', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'use_ssl', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 41, + 'in_filter': None, + 'label': 'Use SSL', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00389', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_login', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 42, + 'in_filter': None, + 'label': 'Login Id', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00280', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-12 10:19:16', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_password', + 'fieldtype': 'Password', + 'hidden': None, + 'icon': None, + 'idx': 43, + 'in_filter': None, + 'label': 'Mail Password', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00281', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:25:34', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'mail_footer', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 44, + 'in_filter': None, + 'label': 'Mail Footer', + 'modified': '2010-11-30 17:25:34', + 'modified_by': 'Administrator', + 'name': '_FL00428', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'rushabh@webnotestech.com', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 45, + 'in_filter': None, + 'label': 'Defaults', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00022', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'system_defaults', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 46, + 'in_filter': None, + 'label': 'System Defaults', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00023', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'DefaultValue', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 47, + 'in_filter': None, + 'label': 'Sidebars', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00024', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'To hide the left sidebar, leave this blank or 0', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'left_sidebar_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 48, + 'in_filter': None, + 'label': 'Left Sidebar Width', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00025', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'To hide the right sidebar, leave this blank or 0', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'right_sidebar_width', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 49, + 'in_filter': None, + 'label': 'Right Sidebar Width', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00026', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 50, + 'in_filter': None, + 'label': 'Test Script', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00027', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': '', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 14:36:22', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Button', + 'hidden': None, + 'icon': None, + 'idx': 51, + 'in_filter': None, + 'label': 'Execute Local', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00308', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': '', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Button', + 'hidden': None, + 'icon': 'accept.png', + 'idx': 52, + 'in_filter': None, + 'label': 'Execute (Careful!)', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00029', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': 'execute_test', + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '150px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'test_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 53, + 'in_filter': None, + 'label': 'Test Code', + 'modified': '2009-11-25 10:13:39', + 'modified_by': 'Administrator', + 'name': '_FL00028', + 'no_copy': None, + 'oldfieldname': '', + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Control Panel', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_field/__init__.py b/cgi-bin/core/doctype/custom_field/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/custom_field/custom_field.js b/cgi-bin/core/doctype/custom_field/custom_field.js new file mode 100644 index 0000000000..dfd226d4fc --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.js @@ -0,0 +1,54 @@ +//168 +// Refresh +// -------- +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(!doc.__islocal) get_field(doc.doctype, 'dt' , doc.name).permlevel = 1; + cur_frm.cscript.dt(doc, cdt, cdn); +} + + +cur_frm.cscript.has_special_chars = function(t) { + var iChars = "!@#$%^&*()+=-[]\\\';,./{}|\":<>?"; + for (var i = 0; i < t.length; i++) { + if (iChars.indexOf(t.charAt(i)) != -1) { + return true; + } + } + return false; +} + + +// Label +// ------ +cur_frm.cscript.label = function(doc){ + if(doc.label && cur_frm.cscript.has_special_chars(doc.label)){ + cur_frm.fields_dict['Label Help'].disp_area.innerHTML = 'Special Characters are not allowed'; + doc.label = ''; + refresh_field('label'); + } + else + cur_frm.fields_dict['Label Help'].disp_area.innerHTML = ''; +} + + +// Get Field Label based on DocType +// --------------------------------- +cur_frm.cscript.dt = function(doc, cdt, cdn) { + var callback = function(r, rt){ + + set_field_options('insert_after', r.message); + } + $c_obj([doc], 'get_fields_label', '', callback); +} + + +cur_frm.fields_dict['dt'].get_query = function(doc, dt, dn) { + return 'SELECT tabDocType.name FROM tabDocType WHERE IFNULL(tabDocType.issingle,0)=0 AND tabDocType.name LIKE "%s" ORDER BY name ASC LIMIT 50' +} + + +cur_frm.cscript.fieldtype = function(doc, dt, dn) { + if(doc.fieldtype == 'Link') cur_frm.fields_dict['Options Help'].disp_area.innerHTML = 'Please enter name of the document you want this field to be linked to in Options.
Eg.: Customer'; + else if(doc.fieldtype == 'Select') cur_frm.fields_dict['Options Help'].disp_area.innerHTML = 'Please enter values in Options separated by enter.
Eg.: Field: Country
Options:
China
India
United States

OR
You can also link it to existing Documents.
Eg.: link:Customer'; + else cur_frm.fields_dict['Options Help'].disp_area.innerHTML = ''; +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_field/custom_field.py b/cgi-bin/core/doctype/custom_field/custom_field.py new file mode 100644 index 0000000000..9426c5e52d --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.py @@ -0,0 +1,100 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import cint, cstr, flt, formatdate, now +from webnotes.model.doc import Document +from webnotes import msgprint, errprint + +sql = webnotes.conn.sql + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + + # Get Fields + # ----------- + def get_fields_label(self): + label_name = [] + for i in sql("SELECT idx, label FROM tabDocField WHERE parent = '%s' and ifnull(hidden,0) = 0 and fieldname != '%s' order by idx" % (self.doc.dt, cstr(self.doc.fieldname))): i[1] and i[0] and label_name.append(i[1]+' - '+cstr(i[0])) + return "\n".join(label_name) + + +# *************************** Validate ******************************* + # Set Field name + # ---------------- + def set_fieldname(self): + if not self.doc.fieldname: + # remove special characters from fieldname + self.doc.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_', cstr(self.doc.label).lower().replace(' ','_')) + + + # Validate Field + # --------------- + def validate_field(self): + if self.doc.__islocal == 1 and sql("select name from tabDocField where parent = %s and (label = %s or fieldname = %s)" , (self.doc.dt, self.doc.label, self.doc.fieldname)): + msgprint("%s field already exists in Document : %s" % (self.doc.label, self.doc.dt)) + raise Exception + + if self.doc.fieldtype=='Link' and self.doc.options: + if not sql("select name from tabDocType where name=%s", self.doc.options): + msgprint("%s is not a valid Document" % self.doc.options) + raise Exception + + + # Update Field + # ------------- + def update_field(self, df, new): + import webnotes.model + sql("update tabDocField set idx = idx + 1, modified = %s where parent = %s and idx > %s", (now(),self.doc.dt, self.idx)) + for k in self.doc.fields: + if k not in webnotes.model.default_fields and k not in self.ignore_fields and not k.startswith('_'): + df.fields[k] = self.doc.fields[k] + df.parent = self.doc.dt + df.parenttype = 'DocType' + df.parentfield = 'fields' + df.idx = self.idx+1 + df.save(new) + + + # Add Field + # ---------- + def add_field(self): + field_exists = sql("select name from tabDocField where parent = %s and (label = %s or fieldname = %s)" , (self.doc.dt, self.doc.label, self.doc.fieldname)) + field_exists = field_exists and field_exists[0][0] or '' + self.ignore_fields = ['dt','trash_reason','insert_after','index','customfield1','length'] + if field_exists: + df = Document('DocField',field_exists) + self.update_field(df, new = 0) + else: + df = Document('DocField') + self.update_field(df, new = 1) + + + # Validate + # --------- + def validate(self): + self.set_fieldname() + self.validate_field() + self.idx = cint((self.doc.insert_after).split(' - ')[1]) + self.add_field() + + # update the schema + from webnotes.model.db_schema import updatedb + updatedb(self.doc.dt) + + # Trash + # ------ + def on_trash(self): + sql("update tabDocField set idx = idx - 1 where parent = %s and idx > %s" , (self.doc.dt, cint((self.doc.insert_after).split(' - ')[1]))) + sql("delete from tabDocField where parent = %s and fieldname = %s", (self.doc.dt, self.doc.fieldname)) + + + # Restore + # -------- + def on_restore(self): + self.validate_field() + self.idx = cint((self.doc.insert_after).split(' - ')[1]) + self.add_field() diff --git a/cgi-bin/core/doctype/custom_field/custom_field.txt b/cgi-bin/core/doctype/custom_field/custom_field.txt new file mode 100644 index 0000000000..36ce318e79 --- /dev/null +++ b/cgi-bin/core/doctype/custom_field/custom_field.txt @@ -0,0 +1,929 @@ +[ + { + '_last_update': '1305006253', + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': 1, + 'autoname': "eval:doc.dt+'-'+doc.label", + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'description': 'Add a custom field to a DocType', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Custom Field', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': 'dt,label,fieldtype', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': '%(label)s (%(fieldtype)s) on %(dt)s', + 'tag_fields': 'dt,fieldtype', + 'use_template': None, + 'version': 159 + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00695', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00696', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 3, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00697', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 2, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 4, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00698', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-10-13 16:39:01', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 5, + 'match': None, + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_PERM00699', + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Details', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03961', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trash_reason', + 'fieldtype': 'Small Text', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Trash Reason', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03962', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'trash_reason', + 'oldfieldtype': 'Small Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': 1, + 'label': 'Document', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03963', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Link', + 'options': 'DocType', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': 1, + 'label': 'Label', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03964', + 'no_column': None, + 'no_copy': 1, + 'oldfieldname': 'label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-14 09:28:31', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Label Help', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03981', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldtype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': 1, + 'label': 'Field Type', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03965', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldtype', + 'oldfieldtype': 'Select', + 'options': '\nButton\nCheck\nColumn Break\nCurrency\nData\nDate\nFloat\nHTML\nInt\nLink\nRead Only\nSection Break\nSelect\nSmall Text\nText\nText Editor\nTime', + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 0, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Options Help', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03966', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'options', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03967', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'options', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Field Description', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03968', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Properties', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03969', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': 'Select the label after which you want to insert new field.', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'insert_after', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Insert After', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03970', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'insert_after', + 'oldfieldtype': 'Select', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Default Value', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03971', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'default', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldname', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Fieldname', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03972', + 'no_column': None, + 'no_copy': 1, + 'oldfieldname': 'fieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 2, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'width', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Width', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03973', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'width', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'reqd', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Is Mandatory Field', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03974', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'reqd', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_filter', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'In Report Filter', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03975', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_filter', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_copy', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'No Copy', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03976', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'no_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Print Hide', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03977', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'report_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Report Hide', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03978', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'report_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_on_submit', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Allow on Submit', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03979', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_on_submit', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'saumil@webnotestech.com', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-13 16:39:01', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Permission Level', + 'modified': '2011-05-18 11:07:49', + 'modified_by': 'Administrator', + 'name': '_FL03980', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Custom Field', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/custom_script/__init__.py b/cgi-bin/core/doctype/custom_script/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/custom_script/custom_script.txt b/cgi-bin/core/doctype/custom_script/custom_script.txt new file mode 100644 index 0000000000..446881a302 --- /dev/null +++ b/cgi-bin/core/doctype/custom_script/custom_script.txt @@ -0,0 +1,189 @@ +[ + { + '_last_update': '1305701384', + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': "eval:doc.dt + '-' + doc.script_type", + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:56', + 'description': 'Add a custom script (client or server) to a DocType', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Custom Script', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': ' ', + 'tag_fields': 'dt,script_type', + 'use_template': None, + 'version': 8 + }, + { + 'amend': None, + 'cancel': 1, + 'create': 1, + 'creation': '2010-08-08 17:08:56', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_PERM00149', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': 1, + 'label': 'DocType', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00824', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Link', + 'options': 'DocType', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': 1, + 'label': 'Script Type', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00825', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'script_type', + 'oldfieldtype': 'Select', + 'options': 'Server\nClient', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:56', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Script', + 'modified': '2011-05-18 12:19:44', + 'modified_by': 'Administrator', + 'name': '_FL00826', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'script', + 'oldfieldtype': 'Code', + 'options': 'Script', + 'owner': 'Administrator', + 'parent': 'Custom Script', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/default_home_page/__init__.py b/cgi-bin/core/doctype/default_home_page/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/default_home_page/default_home_page.txt b/cgi-bin/core/doctype/default_home_page/default_home_page.txt new file mode 100644 index 0000000000..da898dba4e --- /dev/null +++ b/cgi-bin/core/doctype/default_home_page/default_home_page.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-10-28 11:12:48', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Default Home Page', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:12:48', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-10-28 11:22:02', + 'modified_by': 'Administrator', + 'name': '_FL00354', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Default Home Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 11:12:48', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'home_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Home Page', + 'modified': '2009-10-28 11:22:02', + 'modified_by': 'Administrator', + 'name': '_FL00355', + 'no_copy': None, + 'oldfieldname': 'home_page', + 'oldfieldtype': 'Link', + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Default Home Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/defaultvalue/__init__.py b/cgi-bin/core/doctype/defaultvalue/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt b/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt new file mode 100644 index 0000000000..b3f5b3ca1f --- /dev/null +++ b/cgi-bin/core/doctype/defaultvalue/defaultvalue.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'DEF.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DefaultValue', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'defkey', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Key', + 'modified': '2009-05-12 11:19:11', + 'modified_by': 'Administrator', + 'name': '_FL00030', + 'no_copy': None, + 'oldfieldname': 'defkey', + 'oldfieldtype': 'Data', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DefaultValue', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 0, + 'trigger': '', + 'width': '200px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:11', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'defvalue', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Value', + 'modified': '2009-05-12 11:19:11', + 'modified_by': 'Administrator', + 'name': '_FL00031', + 'no_copy': None, + 'oldfieldname': 'defvalue', + 'oldfieldtype': 'Text', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DefaultValue', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '200px' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docfield/__init__.py b/cgi-bin/core/doctype/docfield/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docfield/docfield.txt b/cgi-bin/core/doctype/docfield/docfield.txt new file mode 100644 index 0000000000..ab184c21af --- /dev/null +++ b/cgi-bin/core/doctype/docfield/docfield.txt @@ -0,0 +1,907 @@ +[ + { + '_last_update': '1304505340', + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FL.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocField', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 4 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 0, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_PERM00003', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 0, + 'role': 'Administrator', + 'submit': 0, + 'write': 0 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'label', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Label', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00032', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldtype', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Type', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00033', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldtype', + 'oldfieldtype': 'Select', + 'options': 'Data\nSelect\nText\nSmall Text\nText Editor\nLink\nInt\nDate\nTime\nCurrency\nTable\nFloat\nCheck\nSection Break\nColumn Break\nButton\nRead Only\nCode\nHTML\nImage\nBlob\nPassword', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fieldname', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Name', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00034', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': 'For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'options', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00035', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'options', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Perm Level', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00036', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'width', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Width', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00037', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'width', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'reqd', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Reqd', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00038', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'reqd', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'search_index', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Index', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00039', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'search_index', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_filter', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'In Filter', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00390', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_filter', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'nabin@webnotestech.com', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hidden', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Hidden', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00040', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hidden', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-05 14:00:58', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_column', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'No Column', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '000000705', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_hide', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Print Hide', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00041', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:11', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'no_copy', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'No Copy', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00042', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'no_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'report_hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Report Hide', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00043', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'report_hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_on_submit', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Allow on Submit', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00044', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_on_submit', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'depends_on', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Depends On', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00045', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'depends_on', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00046', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trigger', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Trigger', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00047', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'trigger', + 'oldfieldtype': 'Select', + 'options': '\nClient\nServer', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'default', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Default', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00048', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'default', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'colour', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Colour', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00049', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'colour', + 'oldfieldtype': 'Select', + 'options': 'White:FFF\nLight Blue:DEF\nLight Green:DFE\nPeach:FEF3C5\nPink:FEF2EA\nLilac:FDEAFE\nAqua:EAFEFA', + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00050', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'oldfieldname', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00051', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'oldfieldname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'oldfieldtype', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': None, + 'modified': '2011-05-05 14:00:58', + 'modified_by': 'Administrator', + 'name': '_FL00052', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'oldfieldtype', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocField', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docformat/__init__.py b/cgi-bin/core/doctype/docformat/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docformat/docformat.txt b/cgi-bin/core/doctype/docformat/docformat.txt new file mode 100644 index 0000000000..5468599a6f --- /dev/null +++ b/cgi-bin/core/doctype/docformat/docformat.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'DF.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocFormat', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': None, + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'format', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Format', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00054', + 'no_copy': None, + 'oldfieldname': 'format', + 'oldfieldtype': 'Link', + 'options': 'Print Format', + 'owner': 'Administrator', + 'parent': 'DocFormat', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/docperm/__init__.py b/cgi-bin/core/doctype/docperm/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/docperm/docperm.txt b/cgi-bin/core/doctype/docperm/docperm.txt new file mode 100644 index 0000000000..3290aa228c --- /dev/null +++ b/cgi-bin/core/doctype/docperm/docperm.txt @@ -0,0 +1,405 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'PERM.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocPerm', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permlevel', + 'fieldtype': 'Int', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Level', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00055', + 'no_copy': None, + 'oldfieldname': 'permlevel', + 'oldfieldtype': 'Int', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '40px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00056', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '150px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Read', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00057', + 'no_copy': None, + 'oldfieldname': 'read', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'write', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Write', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00058', + 'no_copy': None, + 'oldfieldname': 'write', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'create', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Create', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00059', + 'no_copy': None, + 'oldfieldname': 'create', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'submit', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Submit', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00060', + 'no_copy': None, + 'oldfieldname': 'submit', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'cancel', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Cancel', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00061', + 'no_copy': None, + 'oldfieldname': 'cancel', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'execute', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Execute', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00062', + 'no_copy': None, + 'oldfieldname': 'execute', + 'oldfieldtype': 'Check', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '32px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'amend', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Amend', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00063', + 'no_copy': None, + 'oldfieldname': 'amend', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'match', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Match', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00064', + 'no_copy': None, + 'oldfieldname': 'match', + 'oldfieldtype': 'Data', + 'options': '', + 'owner': 'Administrator', + 'parent': 'DocPerm', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctrigger/__init__.py b/cgi-bin/core/doctype/doctrigger/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctrigger/doctrigger.txt b/cgi-bin/core/doctype/doctrigger/doctrigger.txt new file mode 100644 index 0000000000..666f2ca355 --- /dev/null +++ b/cgi-bin/core/doctype/doctrigger/doctrigger.txt @@ -0,0 +1,196 @@ +[ + { + '_last_update': None, + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': '_TRIGGER.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2011-05-09 11:04:24', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-03-31 15:23:46', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocTrigger', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 1, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_type', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Doc Type', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000396', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Doc Name', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000397', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Event Name', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000398', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 11:04:24', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'method', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Method', + 'modified': '2011-05-09 11:04:24', + 'modified_by': 'Administrator', + 'name': '000000399', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocTrigger', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype/__init__.py b/cgi-bin/core/doctype/doctype/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype/doctype.js b/cgi-bin/core/doctype/doctype/doctype.js new file mode 100644 index 0000000000..9218b58f0e --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.js @@ -0,0 +1,75 @@ +// ------------- +// Menu Display +// ------------- + +cur_frm.cscript.issingle = function(doc, cdt, cdn) { + if(doc.issingle) + unhide_field('show_in_menu'); + else { + doc.show_in_menu = 0; + hide_field('show_in_menu'); + hide_field('parent_node'); + hide_field('Parent HTML'); + hide_field('Menu HTML'); + hide_field('menu_index'); + hide_field('smallicon'); + } +} + +cur_frm.cscript.show_in_menu = function(doc, cdt, cdn) { + if(doc.show_in_menu) { + unhide_field('parent_node'); + unhide_field('Parent HTML'); + unhide_field('Menu HTML'); + unhide_field('menu_index'); + unhide_field('smallicon'); + } else { + hide_field('parent_node'); + hide_field('Parent HTML'); + hide_field('Menu HTML'); + hide_field('menu_index'); + hide_field('smallicon'); + } +} + +// Attachment + +cur_frm.cscript.allow_attach = function(doc, cdt, cdn) { + if(doc.allow_attach) { + unhide_field('max_attachments'); + } else { + hide_field('max_attachments'); + } +} + +cur_frm.cscript.onload = function(doc, cdt, cdn) { + this.issingle(doc, cdt, cdn); + this.allow_attach(doc, cdt, cdn); + this.show_in_menu(doc, cdt, cdn); +} + +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(in_list(user_roles, 'System Manager') && !in_list(user_roles, 'Administrator')) { + // make the document read-only + cur_frm.perm = [[1,0,0]] + + // make help heading + cur_frm.tip_wrapper.innerHTML = ''; + $a(cur_frm.tip_wrapper, 'div', 'help_box','','Cannot Edit DocType directly: To edit DocType properties, create / update Custom Field, Custom Script and Property Setter') + } + + + // show button for import + cur_frm.add_custom_button('Import from File', cur_frm.cscript.do_import); +} + +cur_frm.cscript.validate = function(doc, cdt, cdn) { + doc.server_code_compiled = null; +} + +cur_frm.cscript.do_import = function(doc, cdt, cdn) { + callback = function(r,rt) { + cur_frm.refresh_doc(); + } + $c_obj([doc], 'import_doctype', '', callback) +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype/doctype.py b/cgi-bin/core/doctype/doctype/doctype.py new file mode 100644 index 0000000000..b7238cf1c1 --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.py @@ -0,0 +1,94 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import now, cint +sql = webnotes.conn.sql +msgprint = webnotes.msgprint + + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc=None, doclist=[]): + self.doc = doc + self.doclist = doclist + + def change_modified_of_parent(self): + parent_list = sql('SELECT parent from tabDocField where fieldtype="Table" and options="%s"' % self.doc.name) + for p in parent_list: + sql('UPDATE tabDocType SET modified="%s" WHERE `name`="%s"' % (now(), p[0])) + + def scrub_field_names(self): + restricted = ('name','parent','idx','owner','creation','modified','modified_by','parentfield','parenttype') + for d in self.doclist: + if d.parent and d.fieldtype: + if (not d.fieldname) and (d.fieldtype.lower() in ('data', 'select', 'int', 'float', 'currency', 'table', 'text', 'link', 'date', 'code', 'check', 'read only', 'small_text', 'time')): + d.fieldname = d.label.strip().lower().replace(' ','_') + if d.fieldname in restricted: + d.fieldname = d.fieldname + '1' + + def set_version(self): + self.doc.version = cint(self.doc.version) + 1 + + # + # check if this series is not used elsewhere + # + def validate_series(self, autoname=None, name=None): + if not autoname: autoname = self.doc.autoname + if not name: name = self.doc.name + + if autoname and (not autoname.startswith('field:')) and (not autoname.startswith('eval:')) and (not autoname=='Prompt'): + prefix = autoname.split('.')[0] + used_in = sql('select name from tabDocType where substring_index(autoname, ".", 1) = %s and name!=%s', (prefix, name)) + if used_in: + msgprint('Series already in use: The series "%s" is already used in "%s"' % (prefix, used_in[0][0]), raise_exception=1) + + # + # field validations + # + def validate_fields(self): + "validates fields for incorrect properties and double entries" + fieldnames = {} + for d in self.doclist: + if d.parent and d.fieldtype and d.parent == self.doc.name: + # check if not double + if d.fieldname: + if fieldnames.get(d.fieldname): + webnotes.msgprint('Fieldname %s appears twice (rows %s and %s). Please rectify' \ + % (d.fieldname, str(d.idx + 1), str(fieldnames[d.fieldname] + 1)), raise_exception=1) + fieldnames[d.fieldname] = d.idx + + # check illegal mandatory + if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd: + webnotes.msgprint('%(lable)s [%(fieldtype)s] cannot be mandatory', raise_exception=1) + + # validate if allow attach, then file_list must be present + if self.doc.allow_attach and not fieldnames.get('file_list'): + webnotes.msgprint('To allow attachments, a field with fieldname "file_list" of type text must be present', raise_exception = 1) + + def validate(self): + self.validate_series() + self.scrub_field_names() + self.validate_fields() + self.set_version() + + def on_update(self): + # make schma changes + from webnotes.model.db_schema import updatedb + updatedb(self.doc.name) + + self.change_modified_of_parent() + + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + self.export_doc() + sql("delete from __DocTypeCache") + + def export_doc(self): + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[['DocType', self.doc.name]]) + + def import_doc(self): + from webnotes.modules.import_module import import_from_files + import_from_files(record_list=[[self.doc.module, 'doctype', self.doc.name]]) diff --git a/cgi-bin/core/doctype/doctype/doctype.txt b/cgi-bin/core/doctype/doctype/doctype.txt new file mode 100644 index 0000000000..2905663ea4 --- /dev/null +++ b/cgi-bin/core/doctype/doctype/doctype.txt @@ -0,0 +1,1796 @@ +[ + { + '_last_update': '1305026481', + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'Prompt', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': 'Yes', + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'autoname', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'subject': None, + 'tag_fields': None, + 'use_template': None, + 'version': 9 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_PERM00004', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_PERM00005', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Options', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000398', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Settings', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000399', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00067', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Link', + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'version', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Version', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00068', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'version', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'name', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Name', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00309', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'autoname', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Auto Name', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00069', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'autoname', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'owner', + 'fieldtype': 'Link', + 'hidden': 1, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Owner', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00310', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'owner', + 'oldfieldtype': 'Link', + 'options': 'Profile', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'name_case', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Name Case', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00070', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'name_case', + 'oldfieldtype': 'Select', + 'options': '\nTitle Case\nUPPER CASE', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'search_fields', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Search Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00071', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'search_fields', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2011-05-10 14:02:46', + 'default': None, + 'depends_on': None, + 'description': 'Subject will appear as a string in the docbrowser: eg.\n[%(status)s] %(description)s\nIf it is a JS Expression, use "eval:"', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'subject', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Subject', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000757', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2011-05-10 16:51:20', + 'default': None, + 'depends_on': None, + 'description': 'Fields separated by (,) that will be set as tags', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'tag_fields', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'tag_fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000758', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'istable', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Is Table', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00072', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'istable', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read_only', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Not In Search', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00073', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'read_only', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_create', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Not In Create', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00074', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_create', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'issingle', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Is Single', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00075', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'issingle', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-04-01 12:38:02', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'read_only_onload', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Show Print First', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00410', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'read_only_onload', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'show_in_menu', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Show In Pages', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00418', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'show_in_menu', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-09-20 12:44:07', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'document_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Document Type', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL03897', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'document_type', + 'oldfieldtype': 'Select', + 'options': '\nMaster\nTransaction\nSystem\nOther', + 'owner': 'harshada@webnotestech.com', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Display', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000400', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 09:58:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_transaction_doc', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Is Transaction Doc', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000384', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'is_transaction_doc', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'use_template', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Use Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00082', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'use_template', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'print_outline', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Print Outline', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00083', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'print_outline', + 'oldfieldtype': 'Select', + 'options': '\nNo\nYes', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_print', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Hide Print', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00084', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_print', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_email', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Hide Email', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00085', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_email', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'in_dialog', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'In Dialog', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00420', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'in_dialog', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_copy', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Hide Copy', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00086', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_copy', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_toolbar', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Hide Toolbar', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00087', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hide_toolbar', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide_heading', + 'fieldtype': 'Check', + 'hidden': 0, + 'icon': None, + 'idx': 28, + 'in_filter': None, + 'label': 'Hide Heading', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00088', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'hide_heading', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': 'allow_attach', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 29, + 'in_filter': None, + 'label': 'Allow Attach', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00089', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_attach', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'max_attachments', + 'fieldtype': 'Int', + 'hidden': 1, + 'icon': None, + 'idx': 30, + 'in_filter': None, + 'label': 'Max Attachments', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00090', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'max_attachments', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_rename', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 31, + 'in_filter': None, + 'label': 'Allow Rename', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00091', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_rename', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'section_style', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 32, + 'in_filter': None, + 'label': 'Section Style', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00092', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'section_style', + 'oldfieldtype': 'Select', + 'options': 'Simple\nPaged\nTabbed\nTray', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'colour', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 33, + 'in_filter': None, + 'label': 'Colour', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00093', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'colour', + 'oldfieldtype': 'Select', + 'options': 'White:FFF\nLight Blue:DEF\nLight Green:DFE\nPeach:FEF3C5\nPink:FEF2EA\nLilac:FDEAFE\nAqua:EAFEFA', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'smallicon', + 'fieldtype': 'Select', + 'hidden': 0, + 'icon': None, + 'idx': 34, + 'in_filter': None, + 'label': 'Small Icon', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00094', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'smallicon', + 'oldfieldtype': 'Select', + 'options': '\naccept.png\nadd.png\napplication.png\nbell.png\nbox.png\ncalendar.png\ncalculator.png\ncancel.png\ncart.png\ncd.png\nchart_bar.png\nclock.png\ncoins.png\ncomputer.png\ncontroller.png\ndisk.png\nemail.png\nerror.png\nfolder.png\ngroup.png\nhouse.png\nimages.png\nlock_open.png\nlock.png\nlorry.png\nmagnifier.png\nmap.png\nmoney.png\nnew.png\npage.png\nprinter.png\nreport.png\nserver.png\nshield.png\ntable.png\nuser.png', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 35, + 'in_filter': None, + 'label': 'Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000401', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 36, + 'in_filter': None, + 'label': 'Roles and Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000402', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '70%' + }, + { + 'allow_on_submit': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'permissions', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 37, + 'in_filter': None, + 'label': 'Permissions', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00097', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'permissions', + 'oldfieldtype': 'Table', + 'options': 'DocPerm', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 16:51:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'allow_trash', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 38, + 'in_filter': None, + 'label': 'Allow Trash', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00419', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'allow_trash', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': None, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 39, + 'in_filter': None, + 'label': 'Print Formats', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000403', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '30%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'formats', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 40, + 'in_filter': None, + 'label': 'Formats', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00099', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'formats', + 'oldfieldtype': 'Table', + 'options': 'DocFormat', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 41, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000404', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': 0, + 'icon': None, + 'idx': 42, + 'in_filter': None, + 'label': 'Document Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000405', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fields', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 43, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00102', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'fields', + 'oldfieldtype': 'Table', + 'options': 'DocField', + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': 0, + 'icon': None, + 'idx': 44, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000406', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': 0, + 'icon': None, + 'idx': 45, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00104', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': '300px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:38', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 46, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '000000410', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt_template', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 47, + 'in_filter': None, + 'label': 'DocType Template', + 'modified': '2011-05-18 12:04:17', + 'modified_by': 'Administrator', + 'name': '_FL00116', + 'no_column': None, + 'no_copy': None, + 'oldfieldname': 'dt_template', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype_label/__init__.py b/cgi-bin/core/doctype/doctype_label/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype_label/doctype_label.txt b/cgi-bin/core/doctype/doctype_label/doctype_label.txt new file mode 100644 index 0000000000..a7ab55b424 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_label/doctype_label.txt @@ -0,0 +1,148 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:dt', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-11-30 17:30:00', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType Label', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-11-30 17:30:00', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_PERM00045', + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Select DocType', + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_FL00494', + 'no_copy': None, + 'oldfieldname': 'dt', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'dt_label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'DocType Label', + 'modified': '2010-11-30 17:30:00', + 'modified_by': 'Administrator', + 'name': '_FL00495', + 'no_copy': None, + 'oldfieldname': 'dt_label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'DocType Label', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/doctype_mapper/__init__.py b/cgi-bin/core/doctype/doctype_mapper/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js new file mode 100644 index 0000000000..a084a981a3 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.js @@ -0,0 +1,9 @@ +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if(doc.from_doctype) { + get_field(doc.doctype, 'from_doctype', doc.name).permlevel = 1; + refresh_field('from_doctype'); + + get_field(doc.doctype, 'to_doctype', doc.name).permlevel = 1; + refresh_field('to_doctype'); + } +} diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py new file mode 100644 index 0000000000..7fb0f61766 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.py @@ -0,0 +1,247 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add +from webnotes.model import db_exists +from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType +from webnotes.model.doclist import getlist, copy_doclist +from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax +from webnotes import session, form, is_testing, msgprint, errprint + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + self.prefix = is_testing and 'test' or 'tab' + self.ref_doc = '' + # Autoname + #--------- + def autoname(self): + self.doc.name = make_autoname(self.doc.from_doctype + '-' + self.doc.to_doctype) + + # Map Custom Fields + # ------------------ + def map_custom_fields(self, from_doctype, to_doctype, from_doc, to_doc): + fld_list = [] + for d in sql("select fieldname from `tabCustom Field` where dt = %s and docstatus != 2",from_doctype): + if sql("select fieldname from `tabCustom Field` where dt = %s and fieldname = %s and docstatus != 2",(to_doctype, d[0])): + fld_list.append([d[0], d[0]]) + self.set_value(fld_list, from_doc, to_doc) + + # Maps the fields in 'To DocType' + #-------------------------------- + def dt_map(self, from_doctype, to_doctype, from_docname, to_doc, doclist, from_to_list = '[]'): + + # definition of arguments + ''' + String : contains the name of DocType initiating the function + String : contains the name of DocType created by the function + String : contains ID(name) of 'from_doctype' + String : contains doc of 'to_doctype' + String : contains doclist of 'to_doctype' + String : contains list of tables which will be mapped + ''' + # Validate reference doc docstatus + self.ref_doc = from_docname + self.check_ref_docstatus() + + if not doclist: + doclist.append(to_doc) + + tbl_list = sql("select from_table, to_table, from_field, to_field, match_id, validation_logic from `tabTable Mapper Detail` where parent ='%s' order by match_id" % (from_doctype + "-" + to_doctype)) + + for t in tbl_list: + from_table_name = t[0] + to_table_name = t[1] + from_table_fname = t[2] + to_table_fname = t[3] + match_id = t[4] + validation_logic = t[5] + + + from_to = [from_table_name, to_table_name] + + if from_to in eval(from_to_list): + fld_list = sql("select from_field, to_field from `tabField Mapper Detail` where parent = '%s' and match_id = %s and map = 'Yes'" % (from_doctype + "-" + to_doctype, match_id)) + if fld_list: + if not from_docname: + msgprint(from_doctype + " not selected for mapping") + raise Exception + + # Parent to parent mapping + if from_table_name == self.doc.from_doctype and to_table_name == self.doc.to_doctype: + + # Check validation + nm = sql("select name from `tab%s` where name = '%s' and %s" % (from_doctype, from_docname, validation_logic)) + nm = nm and nm[0][0] or '' + + # If validation failed raise exception + if not nm: + msgprint("Validation failed in doctype mapper. Please contact Administrator.") + raise Exception + + from_doc = Document(from_doctype, nm) + # Maps field in parent + self.set_value(fld_list, from_doc, to_doc) + # Map custom fields + self.map_custom_fields(from_doctype, to_doctype, from_doc, to_doc) + + # Parent to child OR child to child mapping + else: + dnlist = () + if from_table_name == self.doc.from_doctype: + dnlist = ((from_docname,),) + else: + dnlist = sql("select name from `tab%s` where parent='%s' and parenttype = '%s' and %s order by idx" % (from_table_name, from_docname, self.doc.from_doctype, validation_logic)) + + for dn in dnlist: + # Add a row in target table in 'To DocType' and returns obj + ch = addchild(to_doc, t[3], t[1], 1, doclist) + # Creates object for 'From DocType', it can be parent or child + d = Document(t[0], dn[0]) + # Map values + self.set_value(fld_list, d, ch) + # Map custom fields + self.map_custom_fields(from_table_name, t[1], d, ch) + + # Required when called from server side for refreshing table + return doclist + + # Assigns value to "To Doctype" + #------------------------------ + def set_value(self, fld_list, obj, to_doc): + for f in fld_list: + if f[0].startswith('eval:'): + to_doc.fields[f[1]] = eval(f[0][5:]) + else: + to_doc.fields[f[1]] = obj.fields.get(f[0]) + + # Validate + #--------- + def validate(self): + for d in getlist(self.doclist, 'field_mapper_details'): + # Automatically assigns default value if not entered + if not d.match_id: + d.match_id = 0 + if not d.map: + d.map = 'Yes' + for d in getlist(self.doclist, 'table_mapper_details'): + if not d.reference_doctype_key: + d.reference_doctype_key = '' + if not d.reference_key: + d.reference_key = '' + + # Check wrong field name + self.check_fields_in_dt() + + # Check if any wrong fieldname entered + #-------------------------------------- + def check_fields_in_dt(self): + for d in getlist(self.doclist, 'field_mapper_details'): + table_name = sql("select from_table, to_table from `tabTable Mapper Detail` where parent ='%s' and match_id = '%s'" % (self.doc.name, d.match_id)) + + if table_name: + exists1 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][0], d.from_field)) + exists2 = sql("select name from tabDocField where parent = '%s' and fieldname = '%s'" % (table_name[0][1], d.to_field)) + + # Default fields like name, parent, owner does not exists in DocField + if not exists1 and d.from_field not in default_fields: + msgprint('"' + cstr(d.from_field) + '" does not exists in DocType "' + cstr(table_name[0][0]) + '"') + if not exists2 and d.to_field not in default_fields: + msgprint('"' + cstr(d.to_field) + '" does not exists in DocType "' + cstr(table_name[0][1]) + '"') + + # Check consistency of value with reference document + #--------------------------------------------------- + def validate_reference_value(self, obj, to_docname): + for t in getlist(self.doclist, 'table_mapper_details'): + # Reference key is the fieldname which will relate to the from_table + if t.reference_doctype_key: + for d in getlist(obj.doclist, t.to_field): + if d.fields[t.reference_doctype_key] == self.doc.from_doctype: + self.check_consistency(obj.doc, d, to_docname) + self.check_ref_docstatus() + + # Make list of fields whose value will be consistent with prevdoc + #----------------------------------------------------------------- + def get_checklist(self): + checklist = [] + for f in getlist(self.doclist, 'field_mapper_details'): + + # Check which field's value will be compared + if f.checking_operator: + checklist.append([f.from_field, f.to_field, f.checking_operator, f.match_id]) + return checklist + + def check_fld_type(self, tbl, fld, cur_val): + ft = sql("select fieldtype from tabDocField where fieldname = '%s' and parent = '%s'" % (fld,tbl)) + ft = ft and ft[0][0] or '' + if ft == 'Currency' or ft == 'Float': + cur_val = '%.2f' % cur_val + return cur_val, ft + + # Check consistency + #------------------- + def check_consistency(self, par_obj, child_obj, to_docname): + checklist = self.get_checklist() + self.ref_doc = '' + for t in getlist(self.doclist, 'table_mapper_details'): + if t.reference_key and child_obj.fields[t.reference_key]: + for cl in checklist: + if cl[3] == t.match_id: + if t.to_field: + cur_val = child_obj.fields[cl[1]] + else: + cur_val = par_obj.fields[cl[1]] + + ft = self.check_fld_type(t.to_table, cl[1], cur_val) + cur_val = ft[0] + + if cl[2] == '=' and (ft[1] == 'Currency' or ft[1] == 'Float'): + consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' - %s <= 0.5" % (cl[0], t.from_table, child_obj.fields[t.reference_key], flt(cur_val), cl[0])) + else: + #consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s %s" % (cl[0], t.from_table, child_obj.fields[t.reference_key], cur_val, cl[2], cl[0])) + consistent = sql("select name, %s from `tab%s` where name = '%s' and '%s' %s ifnull(%s, '')" % (cl[0], t.from_table, child_obj.fields[t.reference_key], ft[1] in ('Currency', 'Float', 'Int') and flt(cur_val) or cstr(cur_val), cl[2], cl[0])) + + if not self.ref_doc: + det = sql("select name, parent from `tab%s` where name = '%s'" % (t.from_table, child_obj.fields[t.reference_key])) + self.ref_doc = det[0][1] and det[0][1] or det[0][0] + + if not consistent: + self.give_message(t.from_table, t.to_table, cl[0], cl[1], child_obj.fields[t.reference_key], cl[2]) + + # Gives message and raise exception + #----------------------------------- + def give_message(self, from_table, to_table, from_field, to_field, ref_value, operator): + # Select label of the field + to_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (to_table, to_field)) + from_fld_label = sql("select label from tabDocField where parent = '%s' and fieldname = '%s'" % (from_table, from_field)) + + op_in_words = {'=':'equal to ', '>=':'greater than equal to ', '>':'greater than ', '<=':'less than equal to ', '<':'less than '} + msgprint(to_fld_label[0][0] + " should be " + op_in_words[operator] + from_fld_label[0][0] + " of " + self.doc.from_doctype + ": " + self.ref_doc) + raise Exception, "Validation Error." + + def check_ref_docstatus(self): + if self.ref_doc: + det = sql("select name, docstatus from `tab%s` where name = '%s'" % (self.doc.from_doctype, self.ref_doc)) + if not det: + msgprint(self.doc.from_doctype + ": " + self.ref_doc + " does not exists in the system") + raise Exception, "Validation Error." + elif self.doc.ref_doc_submitted and det[0][1] != 1: + msgprint(self.doc.from_doctype + ": " + self.ref_doc + " is not Submitted Document.") + raise Exception, "Validation Error." + + def on_update(self): + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[[self.doc.doctype, self.doc.name]]) + diff --git a/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt new file mode 100644 index 0000000000..e9f4cb67b5 --- /dev/null +++ b/cgi-bin/core/doctype/doctype_mapper/doctype_mapper.txt @@ -0,0 +1,311 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:08:59', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': None, + 'max_attachments': None, + 'menu_index': 12, + 'modified': '2010-12-16 18:13:25', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'DocType Mapper', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 10 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-08-08 17:08:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:08:59', + 'modified_by': 'Administrator', + 'name': '_PERM00192', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'amend': None, + 'cancel': None, + 'create': None, + 'creation': '2010-08-08 17:08:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 2, + 'match': None, + 'modified': '2010-08-08 17:08:59', + 'modified_by': 'Administrator', + 'name': '_PERM00193', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 1, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01049', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'from_doctype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'From DocType', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01050', + 'no_copy': 1, + 'oldfieldname': 'from_doctype', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'to_doctype', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'To DocType', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01051', + 'no_copy': 1, + 'oldfieldname': 'to_doctype', + 'oldfieldtype': 'Select', + 'options': 'link:DocType', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_doc_submitted', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Ref Doc should be submitted?', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01052', + 'no_copy': None, + 'oldfieldname': 'ref_doc_submitted', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'nabin@webnotestech.com', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'field_mapper_details', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Field Mapper Details', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01053', + 'no_copy': None, + 'oldfieldname': 'field_mapper_details', + 'oldfieldtype': 'Table', + 'options': 'Field Mapper Detail', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:08:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'table_mapper_details', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Table Mapper Details', + 'modified': '2011-04-05 10:01:38', + 'modified_by': 'Administrator', + 'name': '_FL01054', + 'no_copy': None, + 'oldfieldname': 'table_mapper_details', + 'oldfieldtype': 'Table', + 'options': 'Table Mapper Detail', + 'owner': 'Administrator', + 'parent': 'DocType Mapper', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event/__init__.py b/cgi-bin/core/doctype/event/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event/event.txt b/cgi-bin/core/doctype/event/event.txt new file mode 100644 index 0000000000..298210b1c9 --- /dev/null +++ b/cgi-bin/core/doctype/event/event.txt @@ -0,0 +1,603 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'EV.#####', + 'change_log': None, + 'client_script': "cur_frm.cscript.onload = function(doc, cdt, cdn) {\n var df = get_field('Event', 'Intro HTML', doc.name);\n if(doc.ref_type) {\n ref = repl(cur_frm.cstring.ref_html, {'dt': doc.ref_type, 'dn':doc.ref_name});\n } else var ref = '';\n \n df.options = repl(cur_frm.cstring.intro_html, {'ref': ref});\n refresh_fields('Intro HTML');\n}", + 'client_script_core': None, + 'client_string': '---intro_html---\n\n
\n %(ref)s\n Go To Calendar\n
\n\n---ref_html---\n\nReference : %(dn)s

', + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': 1, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 1, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tabbed', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': 'owner', + 'modified': '2009-05-12 11:19:22', + 'modified_by': 'Administrator', + 'name': '_PERM00006', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'All', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Details', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00117', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Intro HTML', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00118', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'HTML', + 'options': '', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_date', + 'fieldtype': 'Date', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Event Date', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00119', + 'no_copy': None, + 'oldfieldname': 'event_date', + 'oldfieldtype': 'Date', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_hour', + 'fieldtype': 'Time', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Event Time', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00120', + 'no_copy': None, + 'oldfieldname': 'event_hour', + 'oldfieldtype': 'Time', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 22:44:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_name', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Event', + 'modified': '2010-11-30 22:44:59', + 'modified_by': 'Administrator', + 'name': '_FL03481', + 'no_copy': None, + 'oldfieldname': 'event_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Description', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00121', + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'notes', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Notes', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00122', + 'no_copy': None, + 'oldfieldname': 'notes', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Event Type', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00123', + 'no_copy': None, + 'oldfieldname': 'event_type', + 'oldfieldtype': 'Select', + 'options': 'Private\nPublic\nCancel', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Participants', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00124', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Individuals', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00125', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_individuals', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Event Individuals', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00126', + 'no_copy': None, + 'oldfieldname': 'event_individuals', + 'oldfieldtype': 'Table', + 'options': 'Event User', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Groups', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00127', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Column Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50%' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'event_roles', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Event Roles', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00128', + 'no_copy': None, + 'oldfieldname': 'event_roles', + 'oldfieldtype': 'Table', + 'options': 'Event Role', + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_type', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Ref Type', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00129', + 'no_copy': None, + 'oldfieldname': 'ref_type', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'ref_name', + 'fieldtype': 'Data', + 'hidden': 0, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Ref Name', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00130', + 'no_copy': None, + 'oldfieldname': 'ref_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Event', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event_role/__init__.py b/cgi-bin/core/doctype/event_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event_role/event_role.txt b/cgi-bin/core/doctype/event_role/event_role.txt new file mode 100644 index 0000000000..10c0de2c68 --- /dev/null +++ b/cgi-bin/core/doctype/event_role/event_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': '__EVR.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event Role', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00131', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Event Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/event_user/__init__.py b/cgi-bin/core/doctype/event_user/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/event_user/event_user.txt b/cgi-bin/core/doctype/event_user/event_user.txt new file mode 100644 index 0000000000..54bba6a6de --- /dev/null +++ b/cgi-bin/core/doctype/event_user/event_user.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'EVP.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Event User', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'person', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Person', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00132', + 'no_copy': None, + 'oldfieldname': 'person', + 'oldfieldtype': 'Select', + 'options': 'link:Profile', + 'owner': 'Administrator', + 'parent': 'Event User', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/field_mapper_detail/__init__.py b/cgi-bin/core/doctype/field_mapper_detail/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt b/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt new file mode 100644 index 0000000000..1ec71d3d37 --- /dev/null +++ b/cgi-bin/core/doctype/field_mapper_detail/field_mapper_detail.txt @@ -0,0 +1,230 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FMD/.#####', + 'change_log': None, + 'client_script': '', + 'client_script_core': '', + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-11-30 17:30:01', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Field Mapper Detail', + 'name_case': '', + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': '', + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tray', + 'server_code': '', + 'server_code_compiled': None, + 'server_code_core': '', + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': '', + 'use_template': None, + 'version': 10 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'from_field', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'From Field', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00503', + 'no_copy': None, + 'oldfieldname': 'from_field', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'to_field', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'To Field', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00504', + 'no_copy': None, + 'oldfieldname': 'to_field', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': '0', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'match_id', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Match Id', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00505', + 'no_copy': None, + 'oldfieldname': 'match_id', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'map', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Map', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00506', + 'no_copy': None, + 'oldfieldname': 'map', + 'oldfieldtype': 'Select', + 'options': 'Yes\nNo', + 'owner': 'nabin@webnotestech.com', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '50px' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-11-30 17:30:01', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'checking_operator', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Checking Operator (To Fld, Operator, From Fld)', + 'modified': '2010-11-30 17:30:01', + 'modified_by': 'Administrator', + 'name': '_FL00507', + 'no_copy': None, + 'oldfieldname': 'checking_operator', + 'oldfieldtype': 'Select', + 'options': '\n=\n>\n>=\n<\n<=', + 'owner': 'nabin@webnotestech.com', + 'parent': 'Field Mapper Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': '180px' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/file_data/__init__.py b/cgi-bin/core/doctype/file_data/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/file_data/file_data.txt b/cgi-bin/core/doctype/file_data/file_data.txt new file mode 100644 index 0000000000..1a7bcd945a --- /dev/null +++ b/cgi-bin/core/doctype/file_data/file_data.txt @@ -0,0 +1,125 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'FileData/.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'File Data', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'file_name', + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'File Name', + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'name': '_FL00133', + 'no_copy': None, + 'oldfieldname': 'file_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'File Data', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-01 13:35:53', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module', + 'modified': '2010-12-01 13:35:53', + 'modified_by': 'Administrator', + 'name': '_FL03754', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Link', + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'File Data', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/__init__.py b/cgi-bin/core/doctype/letter_head/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/letter_head/letter_head.js b/cgi-bin/core/doctype/letter_head/letter_head.js new file mode 100644 index 0000000000..24ddcca23e --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.js @@ -0,0 +1,26 @@ +cur_frm.cscript.validate = function(doc, dt, dn) { + return 1; +} + +cur_frm.cscript['Set From Image'] = function(doc, dt, dn) { + if(!doc.file_list) { + msgprint('Please attach an image file first'); + return; + } + if(doc.content) { + if(!confirm('Are you sure you want to overwrite the existing HTML?')) + return; + } + + var file_name = doc.file_list.split(',')[0] + + if(!in_list(['gif','jpg','jpeg','png'], file_name.split('.')[1].toLowerCase())) { + msgprint("Please upload a web friendly (GIF, JPG or PNG) image file for the letter head"); + return; + } + + img_link = '
' + + doc.content = img_link; + refresh_field('content'); +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/letter_head.py b/cgi-bin/core/doctype/letter_head/letter_head.py new file mode 100755 index 0000000000..4e64b69d11 --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.py @@ -0,0 +1,31 @@ +# Please edit this list and import only required elements +import webnotes +from webnotes import msgprint + +sql = webnotes.conn.sql + +class DocType: + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + + # + # on update + # + def on_update(self): + # clear the cache so that the new letter head is uploaded + sql("delete from __SessionCache") + + self.set_as_default() + + # + # this is default, un-set everyone else + # + def set_as_default(self): + from webnotes.utils import set_default + if self.doc.is_default: + sql("update `tabLetter Head` set is_default=0 where name != %s", self.doc.name) + set_default('letter_head', self.doc.name) + + # update control panel - so it loads new letter directly + webnotes.conn.set_value('Control Panel', None, 'letter_head', self.doc.content) \ No newline at end of file diff --git a/cgi-bin/core/doctype/letter_head/letter_head.txt b/cgi-bin/core/doctype/letter_head/letter_head.txt new file mode 100644 index 0000000000..a7c3d8b3f5 --- /dev/null +++ b/cgi-bin/core/doctype/letter_head/letter_head.txt @@ -0,0 +1,324 @@ +[ + { + '_last_update': None, + 'allow_attach': 1, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:letter_head_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-12-14 10:32:59', + 'description': 'Create a Letter Head for Print Formats. The letter head must be in HTML.\nYou can also set the letter head from an attachment.\nIf you click on "Set from Image" then, the HTML Content will be overwritten.', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': 3, + 'menu_index': None, + 'modified': '2011-04-14 10:25:09', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Letter Head', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 11 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2010-12-14 10:32:59', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-12-14 10:32:59', + 'modified_by': 'Administrator', + 'name': '_PERM00735', + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'System Manager', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'letter_head_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': 0, + 'label': 'Letter Head Name', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04150', + 'no_copy': None, + 'oldfieldname': 'letter_head_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'disabled', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Disabled', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04151', + 'no_copy': None, + 'oldfieldname': 'disabled', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-21 18:32:42', + 'default': None, + 'depends_on': None, + 'description': 'Check this to make this the default letter head in all prints', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_default', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Is Default', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04428', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 10:50:46', + 'default': None, + 'depends_on': None, + 'description': 'To update your HTML from attachment, click here', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'set_from_image', + 'fieldtype': 'Button', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Set From Image', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '000000156', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': 'Your letter head content in HTML.', + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'content', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Content', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04152', + 'no_copy': None, + 'oldfieldname': 'content', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-05-09 10:50:46', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'url', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'URL', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '000000157', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-14 10:32:59', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'File LIst', + 'modified': '2011-05-09 10:50:46', + 'modified_by': 'Administrator', + 'name': '_FL04153', + 'no_copy': None, + 'oldfieldname': 'file_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Letter Head', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def/__init__.py b/cgi-bin/core/doctype/module_def/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def/module_def.py b/cgi-bin/core/doctype/module_def/module_def.py new file mode 100644 index 0000000000..6a13a6dbca --- /dev/null +++ b/cgi-bin/core/doctype/module_def/module_def.py @@ -0,0 +1,50 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add +from webnotes.model import db_exists +from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType +from webnotes.model.doclist import getlist, copy_doclist +from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax +from webnotes import session, form, is_testing, msgprint, errprint + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self,d,dl): + self.doc, self.doclist = d,dl + + def on_update(self): + if not getlist(self.doclist,'items') and not self.doc.widget_code: + obj = Document(self.doc.doctype, self.doc.name) + + doc_type = [['DocType','name','name','Forms',"(istable is null or istable=0) and (issingle is null or issingle=0)"],['Page','name','page_name','Pages','(show_in_menu=1 or show_in_menu=0)'],['Search Criteria','doc_type','criteria_name','Reports',"(disabled is null or disabled=0)"]] + for dt in doc_type: + dn = [[d[0] or '', d[1] or ''] for d in sql("select %s,%s from `tab%s` where module = '%s' and %s" % (dt[1],dt[2],dt[0],self.doc.name,dt[4]))] + + if dn: + r = addchild(obj,'items','Module Def Item',1) + r.doc_type = 'Separator' + r.doc_name = dt[3] + r.save(1) + + for d in dn: + r = addchild(obj,'items','Module Def Item',1) + r.doc_type = dt[3] + r.doc_name = d[0] + r.display_name = d[1] + r.save(1) + + def on_update(self): + import webnotes.defs + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + from webnotes.modules.export_module import export_to_files + export_to_files(record_list=[[self.doc.doctype, self.doc.name]]) + \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def/module_def.txt b/cgi-bin/core/doctype/module_def/module_def.txt new file mode 100644 index 0000000000..427e32426e --- /dev/null +++ b/cgi-bin/core/doctype/module_def/module_def.txt @@ -0,0 +1,708 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:module_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-27 11:16:33', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': 'doctype_list', + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 2 + }, + { + 'amend': None, + 'cancel': None, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': None, + 'idx': 1, + 'match': None, + 'modified': '2010-08-08 17:16:13', + 'modified_by': 'Administrator', + 'name': '_PERM00007', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': None, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'trash_reason', + 'fieldtype': 'Small Text', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Trash Reason', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01996', + 'no_copy': None, + 'oldfieldname': 'trash_reason', + 'oldfieldtype': 'Small Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 1, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module Details', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000462', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'disabled', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Disabled', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01998', + 'no_copy': None, + 'oldfieldname': 'disabled', + 'oldfieldtype': 'Select', + 'options': 'No\nYes', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Module Name', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL00135', + 'no_copy': None, + 'oldfieldname': 'module_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_label', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Module Label', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL01999', + 'no_copy': None, + 'oldfieldname': 'module_label', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doctype_list', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'DocType List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL00136', + 'no_copy': None, + 'oldfieldname': 'doctype_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_page', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Module Page', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02000', + 'no_copy': None, + 'oldfieldname': 'module_page', + 'oldfieldtype': 'Link', + 'options': 'Page', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_desc', + 'fieldtype': 'Text Editor', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Module Description', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02001', + 'no_copy': None, + 'oldfieldname': 'module_desc', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_icon', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Module Icon', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02002', + 'no_copy': None, + 'oldfieldname': 'module_icon', + 'oldfieldtype': 'Select', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module_seq', + 'fieldtype': 'Int', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': 1, + 'label': 'Module Sequence', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02003', + 'no_copy': None, + 'oldfieldname': 'module_seq', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Item List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000463', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'items', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Items', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02005', + 'no_copy': None, + 'oldfieldname': 'items', + 'oldfieldtype': 'Table', + 'options': 'Module Def Item', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Role List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000464', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'roles', + 'fieldtype': 'Table', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Roles', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02007', + 'no_copy': None, + 'oldfieldname': 'roles', + 'oldfieldtype': 'Table', + 'options': 'Module Def Role', + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'File List', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02008', + 'no_copy': None, + 'oldfieldname': 'file_list', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': 1, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:47', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Widget Script', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '000000465', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'widget_code', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Widget Code', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL02010', + 'no_copy': None, + 'oldfieldname': 'widget_code', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-01 19:01:13', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'is_hidden', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Is Hidden', + 'modified': '2011-04-05 10:01:47', + 'modified_by': 'Administrator', + 'name': '_FL03943', + 'no_copy': None, + 'oldfieldname': 'is_hidden', + 'oldfieldtype': 'Select', + 'options': 'No\nYes', + 'owner': 'yogesh@webnotestech.com', + 'parent': 'Module Def', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def_item/__init__.py b/cgi-bin/core/doctype/module_def_item/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def_item/module_def_item.txt b/cgi-bin/core/doctype/module_def_item/module_def_item.txt new file mode 100644 index 0000000000..2c3244e627 --- /dev/null +++ b/cgi-bin/core/doctype/module_def_item/module_def_item.txt @@ -0,0 +1,335 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'MDI.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:09:10', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:42:16', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def Item', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 21 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_type', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Doc Type', + 'modified': '2011-04-05 10:01:39', + 'modified_by': 'Administrator', + 'name': '_FL02011', + 'no_copy': None, + 'oldfieldname': 'doc_type', + 'oldfieldtype': 'Select', + 'options': 'Forms\nPages\nReports\nSeparator\nMore Reports\nSetup Forms\nSetup Pages\nSingle DocType', + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'doc_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Doc Name', + 'modified': '2011-04-05 10:01:39', + 'modified_by': 'Administrator', + 'name': '_FL02012', + 'no_copy': None, + 'oldfieldname': 'doc_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'display_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Display Name', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02013', + 'no_copy': None, + 'oldfieldname': 'display_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02014', + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Select', + 'options': '\naccept.gif\nadd.gif\napplication.gif\narrow_down.gif\narrow_left.gif\narrow_right.gif\narrow_up.gif\ncalculator.gif\ncalendar.gif\ncancel.gif\nchart_bar.gif\nclose.gif\ncomments.gif\ndisk.gif\ndown-arrow.gif\nemail.gif\nerror.gif\nfolder.gif\ngroup.gif\nhelp.gif\nicon-recommend.gif\nlightbulb.gif\nmagnifier.gif\nminus.gif\nnote.gif\npage.gif\npage_add.gif\npage_copy.gif\npage_excel.gif\npage_refresh.gif\npaperclip.gif\nplus.gif\nprinter.gif\nresultset_first.gif\nresultset_last.gif\nresultset_next.gif\nresultset_previous.gif\nsort_asc.gif\nsort_desc.gif\nstar.gif\ntable.gif\ntable_row_delete.gif\ntable_row_insert.gif\nuser.gif\nwrench.gif', + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'description', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Description', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02015', + 'no_copy': None, + 'oldfieldname': 'description', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'fields', + 'fieldtype': 'Text', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Fields', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02016', + 'no_copy': None, + 'oldfieldname': 'fields', + 'oldfieldtype': 'Text', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-10-04 17:46:19', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'click_function', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': 'Click Function', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL03944', + 'no_copy': None, + 'oldfieldname': 'click_function', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'harshada@webnotestech.com', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-12-24 17:46:27', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'hide', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Hide', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL04430', + 'no_copy': None, + 'oldfieldname': 'hide', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Module Def Item', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/module_def_role/__init__.py b/cgi-bin/core/doctype/module_def_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/module_def_role/module_def_role.txt b/cgi-bin/core/doctype/module_def_role/module_def_role.txt new file mode 100644 index 0000000000..f0e2461ca4 --- /dev/null +++ b/cgi-bin/core/doctype/module_def_role/module_def_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'MDR.#####', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2010-08-08 17:09:10', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:42:16', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Module Def Role', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-08-08 17:09:10', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL02017', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Module Def Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page/__init__.py b/cgi-bin/core/doctype/page/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page/page.py b/cgi-bin/core/doctype/page/page.py new file mode 100644 index 0000000000..5e2b873b99 --- /dev/null +++ b/cgi-bin/core/doctype/page/page.py @@ -0,0 +1,49 @@ +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d,dl + + def autoname(self): + if (self.doc.name and self.doc.name.startswith('New Page')) or not self.doc.name: + self.doc.name = self.doc.page_name.lower().replace(' ', '-') + + def onload(self): + import os + from webnotes.modules import get_module_path, scrub + + # load content + try: + file = open(os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name) + '.html'), 'r') + self.doc.content = file.read() or '' + file.close() + except IOError, e: # no file / permission + if e.args[0]!=2: + raise e + + # replace $image + # ------------------ + def validate(self): + import re + p = re.compile('\$image\( (?P [^)]*) \)', re.VERBOSE) + if self.doc.content: + self.doc.content = p.sub(self.replace_by_img, self.doc.content) + + def replace_by_img(self, match): + import webnotes + name = match.group('name') + return '' % (webnotes.conn.get('Control Panel', None, 'account_id'), name) + + # export + def on_update(self): + from webnotes.modules.export_module import export_to_files + from webnotes.modules import get_module_path, scrub + import os + from webnotes import defs + + if getattr(defs,'developer_mode', 0): + export_to_files(record_list=[['Page', self.doc.name]]) + + if self.doc.write_content and self.doc.content: + file = open(os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name), scrub(self.doc.name) + '.html'), 'w') + file.write(self.doc.content) + file.close() + diff --git a/cgi-bin/core/doctype/page/page.txt b/cgi-bin/core/doctype/page/page.txt new file mode 100644 index 0000000000..9d906d1bc2 --- /dev/null +++ b/cgi-bin/core/doctype/page/page.txt @@ -0,0 +1,1023 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:page_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:43:43', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Tabbed', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 7 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_PERM00008', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Page HTML', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000429', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': 'Section Break', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-10-28 10:51:29', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Page Name', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00353', + 'no_copy': None, + 'oldfieldname': 'page_name', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-30 16:18:42', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00291', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 4, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000415', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Page Template', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'stylesheet', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 5, + 'in_filter': None, + 'label': 'Stylesheet', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000416', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Stylesheet', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'standard', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 6, + 'in_filter': None, + 'label': 'Standard', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00319', + 'no_copy': None, + 'oldfieldname': 'standard', + 'oldfieldtype': 'Select', + 'options': '\nYes\nNo', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Column Break', + 'hidden': None, + 'icon': None, + 'idx': 7, + 'in_filter': None, + 'label': None, + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000430', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'author', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 8, + 'in_filter': None, + 'label': 'Author', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000418', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'category', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 9, + 'in_filter': None, + 'label': 'Category', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000419', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': '\nStandard\nBlog', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'publish', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 10, + 'in_filter': None, + 'label': 'Publish', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000420', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'page_title', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 11, + 'in_filter': None, + 'label': 'Page Title', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000421', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'style', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 12, + 'in_filter': None, + 'label': 'Style', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00321', + 'no_copy': None, + 'oldfieldname': 'style', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'keywords', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 13, + 'in_filter': None, + 'label': 'Keywords', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000422', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'site_description', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 14, + 'in_filter': None, + 'label': 'Site Description', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000423', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:22:00', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'static_content', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 15, + 'in_filter': None, + 'label': 'Static Content', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00323', + 'no_copy': None, + 'oldfieldname': 'static_content', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 16, + 'in_filter': None, + 'label': 'Page Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000431', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'write_content', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 17, + 'in_filter': None, + 'label': 'Write Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000425', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'show_in_menu', + 'fieldtype': 'Check', + 'hidden': None, + 'icon': None, + 'idx': 18, + 'in_filter': None, + 'label': 'Show In Start', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00145', + 'no_copy': None, + 'oldfieldname': 'show_in_menu', + 'oldfieldtype': 'Check', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': 'Client', + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'content', + 'fieldtype': 'Text Editor', + 'hidden': 0, + 'icon': None, + 'idx': 19, + 'in_filter': None, + 'label': 'Content', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00138', + 'no_copy': None, + 'oldfieldname': 'content', + 'oldfieldtype': 'Text Editor', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'parent_node', + 'fieldtype': 'Data', + 'hidden': 1, + 'icon': None, + 'idx': 20, + 'in_filter': None, + 'label': 'Parent Node', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00395', + 'no_copy': None, + 'oldfieldname': 'parent_node', + 'oldfieldtype': 'Data', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'icon', + 'fieldtype': 'Select', + 'hidden': 1, + 'icon': None, + 'idx': 21, + 'in_filter': None, + 'label': 'Icon', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00397', + 'no_copy': None, + 'oldfieldname': 'icon', + 'oldfieldtype': 'Select', + 'options': '\naccept.png\nadd.png\napplication.png\nbell.png\nbox.png\ncalendar.png\ncalculator.png\ncancel.png\ncart.png\ncd.png\nchart_bar.png\nclock.png\ncoins.png\ncomputer.png\ncontroller.png\ndisk.png\nemail.png\nerror.png\nfolder.png\ngroup.png\nhouse.png\nimages.png\nlock_open.png\nlock.png\nlorry.png\nmagnifier.png\nmap.png\nmoney.png\nnew.png\npage.png\nprinter.png\nreport.png\nserver.png\nshield.png\ntable.png\nuser.png', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'HTML', + 'hidden': None, + 'icon': None, + 'idx': 22, + 'in_filter': None, + 'label': 'Image List', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000432', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': None, + 'fieldtype': 'Section Break', + 'hidden': None, + 'icon': None, + 'idx': 23, + 'in_filter': None, + 'label': 'Page Script', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000433', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-05-12 11:19:12', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'script', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 24, + 'in_filter': None, + 'label': 'Script', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '_FL00140', + 'no_copy': None, + 'oldfieldname': 'script', + 'oldfieldtype': 'Code', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:40', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'file_list', + 'fieldtype': 'Text', + 'hidden': 1, + 'icon': None, + 'idx': 25, + 'in_filter': None, + 'label': 'File List', + 'modified': '2011-04-05 10:01:40', + 'modified_by': 'Administrator', + 'name': '000000428', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2010-01-20 11:09:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'menu_index', + 'fieldtype': 'Int', + 'hidden': 1, + 'icon': None, + 'idx': 26, + 'in_filter': None, + 'label': 'Menu Index', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00398', + 'no_copy': None, + 'oldfieldname': 'menu_index', + 'oldfieldtype': 'Int', + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'roles', + 'fieldtype': 'Table', + 'hidden': 0, + 'icon': None, + 'idx': 27, + 'in_filter': None, + 'label': 'Roles', + 'modified': '2010-08-08 16:49:29', + 'modified_by': 'Administrator', + 'name': '_FL00143', + 'no_copy': None, + 'oldfieldname': 'roles', + 'oldfieldtype': 'Table', + 'options': 'Page Role', + 'owner': 'Administrator', + 'parent': 'Page', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_role/__init__.py b/cgi-bin/core/doctype/page_role/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page_role/page_role.txt b/cgi-bin/core/doctype/page_role/page_role.txt new file mode 100644 index 0000000000..41322d430f --- /dev/null +++ b/cgi-bin/core/doctype/page_role/page_role.txt @@ -0,0 +1,90 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'PR.######', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 1, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page Role', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': None, + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': None + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'role', + 'fieldtype': 'Link', + 'hidden': 0, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Role', + 'modified': '2009-05-12 11:19:12', + 'modified_by': 'Administrator', + 'name': '_FL00151', + 'no_copy': None, + 'oldfieldname': 'role', + 'oldfieldtype': 'Link', + 'options': 'Role', + 'owner': 'Administrator', + 'parent': 'Page Role', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_template/__init__.py b/cgi-bin/core/doctype/page_template/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/page_template/page_template.py b/cgi-bin/core/doctype/page_template/page_template.py new file mode 100644 index 0000000000..550367e5df --- /dev/null +++ b/cgi-bin/core/doctype/page_template/page_template.py @@ -0,0 +1,20 @@ +import webnotes + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d,dl + + # export + def on_update(self): + import webnotes.defs + from webnotes.modules.export_module import export_to_files + from webnotes.modules import get_module_path, scrub + import os + + if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode: + + export_to_files(record_list=[['Page Template', self.doc.name]]) + + file = open(os.path.join(get_module_path(self.doc.module), 'Page Template', self.doc.name, self.doc.name + '.html'), 'w') + file.write(self.doc.content) + file.close() \ No newline at end of file diff --git a/cgi-bin/core/doctype/page_template/page_template.txt b/cgi-bin/core/doctype/page_template/page_template.txt new file mode 100644 index 0000000000..a1b0bfc577 --- /dev/null +++ b/cgi-bin/core/doctype/page_template/page_template.txt @@ -0,0 +1,160 @@ +[ + { + 'allow_attach': None, + 'allow_copy': None, + 'allow_email': None, + 'allow_print': None, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'field:template_name', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2011-04-05 10:01:43', + 'description': 'Page Template is used in the CMS. In Page, if you select a template, the page appears within the template.\n\nNote: The template must have a "%(content)s" for string replacement and all % must be %%!\n\nIn developer_mode, the template is saved to the file system. ', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': None, + 'hide_toolbar': None, + 'idx': None, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': None, + 'istable': None, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2011-02-21 17:10:06', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Page Template', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': None, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': None, + 'show_in_menu': None, + 'smallicon': None, + 'use_template': None, + 'version': 6 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template_name', + 'fieldtype': 'Data', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Template Name', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000434', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Link', + 'hidden': None, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'Module', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000435', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': 'Module Def', + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2011-04-05 10:01:43', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'template', + 'fieldtype': 'Code', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Template', + 'modified': '2011-04-05 10:01:43', + 'modified_by': 'Administrator', + 'name': '000000436', + 'no_copy': None, + 'oldfieldname': None, + 'oldfieldtype': None, + 'options': None, + 'owner': 'Administrator', + 'parent': 'Page Template', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': None, + 'search_index': None, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/print_format/__init__.py b/cgi-bin/core/doctype/print_format/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/print_format/print_format.txt b/cgi-bin/core/doctype/print_format/print_format.txt new file mode 100644 index 0000000000..8794c48e60 --- /dev/null +++ b/cgi-bin/core/doctype/print_format/print_format.txt @@ -0,0 +1,183 @@ +[ + { + 'allow_attach': None, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': 'Prompt', + 'change_log': None, + 'client_script': None, + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': None, + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': None, + 'menu_index': None, + 'modified': '2010-09-20 14:06:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Print Format', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': None, + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': None, + 'section_style': 'Simple', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': ' ', + 'show_in_menu': 0, + 'smallicon': None, + 'use_template': None, + 'version': 3 + }, + { + 'amend': None, + 'cancel': 0, + 'create': 1, + 'creation': '2009-05-12 11:19:22', + 'docstatus': 0, + 'doctype': 'DocPerm', + 'execute': 0, + 'idx': 1, + 'match': '', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_PERM00009', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'permissions', + 'parenttype': 'DocType', + 'permlevel': 0, + 'read': 1, + 'role': 'Administrator', + 'submit': 0, + 'write': 1 + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-06-30 16:22:31', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'module', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 1, + 'in_filter': None, + 'label': 'Module', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00293', + 'no_copy': None, + 'oldfieldname': 'module', + 'oldfieldtype': 'Select', + 'options': 'link:Module Def', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': None, + 'trigger': None, + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': '', + 'creation': '2009-05-12 11:19:12', + 'default': '', + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'html', + 'fieldtype': 'Text Editor', + 'hidden': 0, + 'icon': None, + 'idx': 2, + 'in_filter': None, + 'label': 'HTML', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00152', + 'no_copy': None, + 'oldfieldname': 'html', + 'oldfieldtype': 'Text Editor', + 'options': '', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 0, + 'search_index': 0, + 'trigger': '', + 'width': '' + }, + { + 'allow_on_submit': None, + 'colour': None, + 'creation': '2009-09-23 16:21:55', + 'default': None, + 'depends_on': None, + 'description': None, + 'docstatus': 0, + 'doctype': 'DocField', + 'fieldname': 'standard', + 'fieldtype': 'Select', + 'hidden': None, + 'icon': None, + 'idx': 3, + 'in_filter': None, + 'label': 'Standard', + 'modified': '2009-11-25 10:15:16', + 'modified_by': 'Administrator', + 'name': '_FL00318', + 'no_copy': None, + 'oldfieldname': 'standard', + 'oldfieldtype': 'Select', + 'options': '\nYes\nNo', + 'owner': 'Administrator', + 'parent': 'Print Format', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0, + 'print_hide': None, + 'report_hide': None, + 'reqd': 1, + 'search_index': 1, + 'trigger': None, + 'width': None + } +] \ No newline at end of file diff --git a/cgi-bin/core/doctype/profile/__init__.py b/cgi-bin/core/doctype/profile/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/core/doctype/profile/profile.js b/cgi-bin/core/doctype/profile/profile.js new file mode 100644 index 0000000000..b392a3a160 --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.js @@ -0,0 +1,26 @@ +cur_frm.cscript['Change Password']= function(doc, cdt, cdn) { + var error = false; + if ((!doc.new_password)||(!doc.retype_new_password)){ + alert("Both fields are required!"); + error = true; + } + if (doc.new_password.length<4) { + alert("Password must be atleast 4 characters long"); + error = true; + } + if(doc.new_password!=doc.retype_new_password) { + alert("Passwords must match"); + error = true; + } + if(!error) { + cur_frm.runscript('update_password', '', function(r,t) { + doc.new_password = ''; + doc.retype_new_password = ''; + }); + } +} + +cur_frm.cscript.validate = function(doc, cdt, cdn) { + doc.new_password = ''; + doc.retype_new_password = ''; +} \ No newline at end of file diff --git a/cgi-bin/core/doctype/profile/profile.py b/cgi-bin/core/doctype/profile/profile.py new file mode 100644 index 0000000000..60388f039f --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.py @@ -0,0 +1,48 @@ +# Please edit this list and import only required elements +import webnotes + +from webnotes import msgprint + +sql = webnotes.conn.sql + +# ----------------------------------------------------------------------------------------- + + +class DocType: + def __init__(self, doc, doclist): + self.doc = doc + self.doclist = doclist + + # Autoname is Email id + # -------------------- + + def autoname(self): + import re + from webnotes.utils import validate_email_add + + self.doc.email = self.doc.email.strip() + if self.doc.name not in ('Guest','Administrator'): + if not validate_email_add(self.doc.email): + msgprint("%s is not a valid email id" % self.doc.email) + raise Exception + self.doc.name = self.doc.email + + def on_update(self): + # owner is always name + if not self.doc.password: + webnotes.conn.set(self.doc, 'password' ,'password') + webnotes.conn.set(self.doc, 'owner' ,self.doc.name) + + + def update_password(self): + from webnotes.utils.email_lib import sendmail + s + sql("UPDATE `tabProfile` SET password=PASSWORD(%s) where name=%s", (self.doc.new_password, self.doc.name)) + email_text = '''%s, + +Your password has been changed. + +- Administrator +''' % self.doc.name + sendmail([self.doc.email], subject='Change of Password Notification', parts = [('text/plain', email_text)]) + msgprint("Your password has been changed") diff --git a/cgi-bin/core/doctype/profile/profile.txt b/cgi-bin/core/doctype/profile/profile.txt new file mode 100644 index 0000000000..7fe575fead --- /dev/null +++ b/cgi-bin/core/doctype/profile/profile.txt @@ -0,0 +1,2003 @@ +[ + { + '_last_update': None, + 'allow_attach': 1, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': None, + 'allow_trash': None, + 'autoname': None, + 'change_log': None, + 'client_script': 'cur_frm.cscript[\'Change Password\']= function(doc, cdt, cdn) {\n var error = false;\n if ((!doc.new_password)||(!doc.retype_new_password)){\n alert("Both fields are required!");\n error = true;\n }\n if (doc.new_password.length<4) {\n alert("Password must be atleast 4 characters long");\n error = true;\n }\n if(doc.new_password!=doc.retype_new_password) {\n alert("Passwords must match");\n error = true;\n }\n if(!/[A-Z]/.test(doc.new_password) || !/[0-9]/.test(doc.new_password) || !/[\\W_]/.test(doc.new_password)) {\n msgprint(\'New password must contain atleast 1 capital letter, 1 numeric and 1 special character.\');\n error = true;\n doc.new_password = \'\';\n refresh_field(\'new_password\');\n }\n if(!error) {\n cur_frm.runscript(\'update_password\', \'\', function(r,t) {\n\tdoc.new_password = \'\';\n\tdoc.retype_new_password = \'\';\n refresh_many([\'new_password\',\'retype_new_password\']);\n });\n }\n}\n\ncur_frm.cscript.validate = function(doc, cdt, cdn) {\n doc.new_password = \'\';\n doc.retype_new_password = \'\';\n}', + 'client_script_core': None, + 'client_string': None, + 'colour': 'White:FFF', + 'creation': '2009-05-12 11:19:11', + 'description': 'Defines the various users of the system.\n\nUse default values table to enable automatic form filling.', + 'docstatus': 0, + 'doctype': 'DocType', + 'document_type': None, + 'dt_template': None, + 'hide_heading': 0, + 'hide_toolbar': 0, + 'idx': 0, + 'in_create': None, + 'in_dialog': None, + 'is_transaction_doc': None, + 'issingle': 0, + 'istable': 0, + 'max_attachments': 1, + 'menu_index': None, + 'modified': '2011-04-21 14:09:06', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Profile', + 'name_case': None, + 'owner': 'Administrator', + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'print_outline': 'Yes', + 'read_only': 0, + 'read_only_onload': None, + 'search_fields': 'first_name, last_name', + 'section_style': 'Tray', + 'server_code': None, + 'server_code_compiled': None, + 'server_code_core': None, + 'server_code_error': '
',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 30
+	},
+	{
+		'amend': None,
+		'cancel': 0,
+		'create': 1,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': 0,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00010',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': 0,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2010-08-08 16:47:35',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00039',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'System Manager',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 3,
+		'match': None,
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00011',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 4,
+		'match': 'owner',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_PERM00013',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Details',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000444',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Picture',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000445',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Image',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Profile Picture',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00155',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Image',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Contact',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000446',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': '1',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'enabled',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Enabled',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00157',
+		'no_copy': None,
+		'oldfieldname': 'enabled',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'registered',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Registered',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000437',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': '1',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'send_email_invite',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Send Email Invite',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00158',
+		'no_copy': None,
+		'oldfieldname': 'send_email_invite',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': 'System Manager',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'escalates_to',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Escalates to',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00159',
+		'no_copy': None,
+		'oldfieldname': 'escalates_to',
+		'oldfieldtype': 'Link',
+		'options': 'Profile',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'unsubscribed',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 9,
+		'in_filter': None,
+		'label': 'Unsubscribed',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000438',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'invited',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Invited',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000439',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reg_id',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Reg ID',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000440',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'campaign',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 12,
+		'in_filter': None,
+		'label': 'Campaign',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000441',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'billing_currency',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 13,
+		'in_filter': None,
+		'label': 'Billing Currency',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000442',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'INR\nUSD',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'recent_documents',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 14,
+		'in_filter': None,
+		'label': 'Recent Documents',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00160',
+		'no_copy': None,
+		'oldfieldname': 'recent_documents',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'first_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 15,
+		'in_filter': None,
+		'label': 'First Name',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00161',
+		'no_copy': None,
+		'oldfieldname': 'first_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'gender',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 16,
+		'in_filter': None,
+		'label': 'Gender',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02339',
+		'no_copy': None,
+		'oldfieldname': 'gender',
+		'oldfieldtype': 'Select',
+		'options': '\nMale\nFemale',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'middle_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 17,
+		'in_filter': None,
+		'label': 'Middle Name (Optional)',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00162',
+		'no_copy': None,
+		'oldfieldname': 'middle_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 18,
+		'in_filter': None,
+		'label': 'Last Name',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00163',
+		'no_copy': None,
+		'oldfieldname': 'last_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'occupation',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 19,
+		'in_filter': None,
+		'label': 'Designation',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02340',
+		'no_copy': None,
+		'oldfieldname': 'occupation',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'bio',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 20,
+		'in_filter': None,
+		'label': 'Bio',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02341',
+		'no_copy': None,
+		'oldfieldname': 'bio',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'email',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 21,
+		'in_filter': None,
+		'label': 'Email',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00164',
+		'no_copy': None,
+		'oldfieldname': 'email',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-12-14 10:33:01',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'interests',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 22,
+		'in_filter': None,
+		'label': 'Interests',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL04167',
+		'no_copy': None,
+		'oldfieldname': 'interests',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-01 14:13:42',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'birth_date',
+		'fieldtype': 'Date',
+		'hidden': None,
+		'icon': None,
+		'idx': 23,
+		'in_filter': None,
+		'label': 'Birth Date',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00294',
+		'no_copy': None,
+		'oldfieldname': 'birth_date',
+		'oldfieldtype': 'Date',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'home_phone',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 24,
+		'in_filter': None,
+		'label': 'Home Phone',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00165',
+		'no_copy': None,
+		'oldfieldname': 'home_phone',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-12-14 10:33:01',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'activities',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 25,
+		'in_filter': None,
+		'label': 'Activities',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL04168',
+		'no_copy': None,
+		'oldfieldname': 'activities',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-08-08 17:09:14',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'messanger_status',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 26,
+		'in_filter': None,
+		'label': 'Messanger Status',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL02342',
+		'no_copy': None,
+		'oldfieldname': 'messanger_status',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'office_phone',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 27,
+		'in_filter': None,
+		'label': 'Office Phone',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00166',
+		'no_copy': None,
+		'oldfieldname': 'office_phone',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'extension',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 28,
+		'in_filter': None,
+		'label': 'Extension',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00167',
+		'no_copy': None,
+		'oldfieldname': 'extension',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'cell_no',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 29,
+		'in_filter': None,
+		'label': 'Cell No',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00168',
+		'no_copy': None,
+		'oldfieldname': 'cell_no',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:48',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'user_type',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 30,
+		'in_filter': None,
+		'label': 'User Type',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00313',
+		'no_copy': None,
+		'oldfieldname': 'user_type',
+		'oldfieldtype': 'Select',
+		'options': '\nSystem User\nPartner',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'default_app',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 31,
+		'in_filter': None,
+		'label': 'Default App',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000443',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'Application',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_login',
+		'fieldtype': 'Read Only',
+		'hidden': 0,
+		'icon': None,
+		'idx': 32,
+		'in_filter': None,
+		'label': 'Last Login',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00169',
+		'no_copy': None,
+		'oldfieldname': 'last_login',
+		'oldfieldtype': 'Read Only',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'last_ip',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 33,
+		'in_filter': None,
+		'label': 'Last IP',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00170',
+		'no_copy': None,
+		'oldfieldname': 'last_ip',
+		'oldfieldtype': 'Read Only',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 34,
+		'in_filter': None,
+		'label': 'Address',
+		'modified': '2011-04-21 14:09:06',
+		'modified_by': 'Administrator',
+		'name': '000000447',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'line_1',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 35,
+		'in_filter': None,
+		'label': 'Line 1',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00172',
+		'no_copy': None,
+		'oldfieldname': 'line_1',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'line_2',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 36,
+		'in_filter': None,
+		'label': 'Line 2',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00173',
+		'no_copy': None,
+		'oldfieldname': 'line_2',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'city',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 37,
+		'in_filter': None,
+		'label': 'City / Town',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00174',
+		'no_copy': None,
+		'oldfieldname': 'city',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'district',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 38,
+		'in_filter': None,
+		'label': 'District',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00175',
+		'no_copy': None,
+		'oldfieldname': 'district',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'state',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 39,
+		'in_filter': None,
+		'label': 'State',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00176',
+		'no_copy': None,
+		'oldfieldname': 'state',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'country',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 40,
+		'in_filter': None,
+		'label': 'Country',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00177',
+		'no_copy': None,
+		'oldfieldname': 'country',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'pin',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 41,
+		'in_filter': None,
+		'label': 'Pin',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00178',
+		'no_copy': None,
+		'oldfieldname': 'pin',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': 0,
+		'icon': None,
+		'idx': 42,
+		'in_filter': None,
+		'label': 'Roles',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000448',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:12',
+		'default': 'Simple',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'userroles',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 43,
+		'in_filter': None,
+		'label': 'User Roles',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00181',
+		'no_copy': None,
+		'oldfieldname': 'userroles',
+		'oldfieldtype': 'Table',
+		'options': 'UserRole',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 44,
+		'in_filter': None,
+		'label': 'System Defaults',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000449',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:12',
+		'default': 'Simple',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'defaults',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 45,
+		'in_filter': None,
+		'label': 'Defaults',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00183',
+		'no_copy': None,
+		'oldfieldname': 'defaults',
+		'oldfieldtype': 'Table',
+		'options': 'DefaultValue',
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 46,
+		'in_filter': None,
+		'label': 'Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000450',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'Pink:FEF2EA',
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'password',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 47,
+		'in_filter': None,
+		'label': 'Current Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00186',
+		'no_copy': None,
+		'oldfieldname': 'password',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'new_password',
+		'fieldtype': 'Password',
+		'hidden': None,
+		'icon': None,
+		'idx': 48,
+		'in_filter': None,
+		'label': 'New Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00187',
+		'no_copy': None,
+		'oldfieldname': 'new_password',
+		'oldfieldtype': 'Password',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'retype_new_password',
+		'fieldtype': 'Password',
+		'hidden': None,
+		'icon': None,
+		'idx': 49,
+		'in_filter': None,
+		'label': 'Retype New Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00188',
+		'no_copy': None,
+		'oldfieldname': 'retype_new_password',
+		'oldfieldtype': 'Password',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-28 17:24:55',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'password_last_updated',
+		'fieldtype': 'Date',
+		'hidden': 1,
+		'icon': None,
+		'idx': 50,
+		'in_filter': None,
+		'label': 'Password Last Updated',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00242',
+		'no_copy': None,
+		'oldfieldname': 'password_last_updated',
+		'oldfieldtype': 'Date',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': 1,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 51,
+		'in_filter': None,
+		'label': 'Change Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00189',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Button',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': '120px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:44',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 52,
+		'in_filter': None,
+		'label': 'Change Password',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '000000451',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Column Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '50%'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'file_list',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 53,
+		'in_filter': None,
+		'label': 'File List',
+		'modified': '2011-04-21 14:09:07',
+		'modified_by': 'Administrator',
+		'name': '_FL00192',
+		'no_copy': None,
+		'oldfieldname': 'file_list',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Profile',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/property_setter/__init__.py b/cgi-bin/core/doctype/property_setter/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/property_setter/property_setter.comp.js b/cgi-bin/core/doctype/property_setter/property_setter.comp.js
new file mode 100644
index 0000000000..51bd2d5c9c
--- /dev/null
+++ b/cgi-bin/core/doctype/property_setter/property_setter.comp.js
@@ -0,0 +1,8 @@
+
+$.extend(cur_frm.cscript,{onload:function(doc,dt,dn){cur_frm.cscript.do_setup(doc);},doctype_or_field:function(doc,dt,dn){doc.doc_type=doc.select_item=doc.doc_name=doc.select_doctype='';refresh_many(['doc_type','select_item','doc_name','select_doctype'])},do_setup:function(doc){$c_obj([doc],'get_setup_data','',function(r,rt){var r=r.message;cur_frm.cscript.set_doctypes(r.doctypes);cur_frm.dt_properties={};cur_frm.df_properties={};for(var i=0;i%(property)s property of %(doc_type)s %(doc_name)s',
+		'tag_fields': 'property',
+		'use_template': None,
+		'version': 33
+	},
+	{
+		'amend': None,
+		'cancel': 1,
+		'create': 1,
+		'creation': '2011-05-05 11:58:33',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000700',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': 1,
+		'create': 1,
+		'creation': '2011-05-05 11:58:33',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000701',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'System Manager',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-05 13:25:40',
+		'default': None,
+		'depends_on': 'eval:doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doctype_or_field',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'DocType or Field',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000704',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': '\nDocField\nDocType',
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 14:11:44',
+		'default': None,
+		'depends_on': 'eval:doc.doctype_or_field && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_doctype',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Select DocType',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000706',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 13:09:45',
+		'default': None,
+		'depends_on': "eval:doc.doctype_or_field=='DocField' && doc.__islocal",
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_item',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Select Field',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000703',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': 0,
+		'colour': None,
+		'creation': '2011-05-06 17:22:25',
+		'default': None,
+		'depends_on': 'eval:doc.doctype_or_field && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'select_property',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Select Property',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000708',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': 'New value to be set',
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'value',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Set Value',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000699',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-05 16:26:47',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Column Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': None,
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000707',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_type',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': 0,
+		'label': 'DocType',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000695',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': "eval:doc.doctype_or_field=='DocField'",
+		'description': 'ID (name) of the entity whose property is to be set',
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_name',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': 0,
+		'label': 'Field ID',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000696',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'eval:doc.doc_name && doc.__islocal',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'property',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 9,
+		'in_filter': 0,
+		'label': 'Property',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000697',
+		'no_column': None,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 12:38:01',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'property_type',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Property Type',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000702',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-05 11:54:08',
+		'default': None,
+		'depends_on': 'doc_name',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'default_value',
+		'fieldtype': 'Read Only',
+		'hidden': None,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Default Value',
+		'modified': '2011-05-18 15:36:45',
+		'modified_by': 'Administrator',
+		'name': '000000698',
+		'no_column': 0,
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Property Setter',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/role/__init__.py b/cgi-bin/core/doctype/role/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/role/role.txt b/cgi-bin/core/doctype/role/role.txt
new file mode 100644
index 0000000000..79a5d8ad59
--- /dev/null
+++ b/cgi-bin/core/doctype/role/role.txt
@@ -0,0 +1,183 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': 0,
+		'allow_email': 0,
+		'allow_print': 0,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'field:role_name',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': 0,
+		'hide_toolbar': 0,
+		'idx': 0,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 0,
+		'istable': 0,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Role',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 0,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 1
+	},
+	{
+		'amend': None,
+		'cancel': 0,
+		'create': 1,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': 0,
+		'idx': 1,
+		'match': '',
+		'modified': '2009-06-30 16:20:34',
+		'modified_by': 'Administrator',
+		'name': '_PERM00014',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': 0,
+		'write': 1
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-06-30 16:20:34',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00292',
+		'no_copy': None,
+		'oldfieldname': 'module',
+		'oldfieldtype': 'Select',
+		'options': 'link:Module Def',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'role_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Role Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00193',
+		'no_copy': None,
+		'oldfieldname': 'role_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'defaults',
+		'fieldtype': 'Table',
+		'hidden': 0,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Defaults',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00194',
+		'no_copy': None,
+		'oldfieldname': 'defaults',
+		'oldfieldtype': 'Table',
+		'options': 'DefaultValue',
+		'owner': 'Administrator',
+		'parent': 'Role',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/search_criteria/__init__.py b/cgi-bin/core/doctype/search_criteria/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/search_criteria/search_criteria.py b/cgi-bin/core/doctype/search_criteria/search_criteria.py
new file mode 100644
index 0000000000..2acbc16c3b
--- /dev/null
+++ b/cgi-bin/core/doctype/search_criteria/search_criteria.py
@@ -0,0 +1,71 @@
+# Please edit this list and import only required elements
+import webnotes
+from webnotes.utils import cint
+
+sql = webnotes.conn.sql
+
+	
+# -----------------------------------------------------------------------------------------
+
+class DocType:
+	def __init__(self,d,dl):
+		self.doc, self.doclist = d,dl
+
+	def autoname(self):
+		self.doc.name = self.doc.criteria_name.lower().replace('(','').replace(')', '')\
+			.replace('.','').replace(',','').replace('"', '').replace("'",'').replace(' ', '_')\
+			.replace('/', '-')
+		
+		# for duplicates
+		if sql("select name from `tabSearch Criteria` where name = %s", self.doc.name):
+			m = sql("select name from `tabSearch Criteria` where name like '%s%%' order by name desc limit 1" % self.doc.name)[0][0]
+			self.doc.name = self.doc.name + str(cint(m[-1]) + 1)
+
+	def set_module(self):
+		if not self.doc.module:
+			doctype_module = sql("select module from tabDocType where name = '%s'" % (self.doc.doc_type))
+			webnotes.conn.set(self.doc,'module',doctype_module and doctype_module[0][0] or 'NULL')
+
+	def on_update(self):
+		self.set_module()
+		self.export_doc()
+	
+	def export_doc(self):
+		# export
+		if self.doc.standard == 'Yes' and getattr(webnotes.defs, 'developer_mode', 0) == 1:
+			from webnotes.modules.export_module import export_to_files
+			export_to_files(record_list=[['Search Criteria', self.doc.name]])
+
+	# patch to rename search criteria from old style numerical to
+	# new style based on criteria name
+	def rename(self):
+		old_name = self.doc.name
+		
+		if not self.doc.module:
+			self.set_module()
+		
+		self.autoname()
+		sql("update `tabSearch Criteria` set name=%s where name=%s", (self.doc.name, old_name))
+		
+	def rename_export(self, old_name):
+				
+		# export the folders
+		self.export_doc()
+		import os, shutil
+		from webnotes.modules import get_module_path, scrub
+		
+		path = os.path.join(get_module_path(self.doc.module), 'search_criteria', scrub(old_name))
+		
+		# copy py/js files
+		self.copy_file(path, scrub(old_name), '.py')
+		self.copy_file(path, scrub(old_name), '.js')
+		self.copy_file(path, scrub(old_name), '.sql')
+				
+	def copy_file(self, path, old_name, extn):
+		import os
+		from webnotes.modules import get_module_path, scrub
+
+		if os.path.exists(os.path.join(path, old_name + extn)):
+			os.system('cp %s %s' % (os.path.join(path, old_name + extn), \
+			os.path.join(get_module_path(self.doc.module), 'search_criteria', scrub(self.doc.name), scrub(self.doc.name) + extn)))
+	
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/search_criteria/search_criteria.txt b/cgi-bin/core/doctype/search_criteria/search_criteria.txt
new file mode 100644
index 0000000000..70bae16a99
--- /dev/null
+++ b/cgi-bin/core/doctype/search_criteria/search_criteria.txt
@@ -0,0 +1,1092 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-02-11 15:44:30',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Search Criteria',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': 'criteria_name',
+		'section_style': 'Tabbed',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 4
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2010-12-23 11:48:49',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': None,
+		'match': None,
+		'modified': '2010-12-23 11:48:49',
+		'modified_by': 'Administrator',
+		'name': '_PERM00771',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2010-12-23 11:48:49',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': None,
+		'match': None,
+		'modified': '2010-12-23 11:48:49',
+		'modified_by': 'Administrator',
+		'name': '_PERM00772',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'All',
+		'submit': None,
+		'write': None
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2009-07-08 23:44:31',
+		'modified_by': 'Administrator',
+		'name': '_PERM00015',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2009-05-12 11:19:22',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2009-07-08 23:44:31',
+		'modified_by': 'Administrator',
+		'name': '_PERM00016',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Details',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000454',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'disabled',
+		'fieldtype': 'Check',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Disabled',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00196',
+		'no_copy': None,
+		'oldfieldname': 'disabled',
+		'oldfieldtype': 'Check',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00197',
+		'no_copy': None,
+		'oldfieldname': 'module',
+		'oldfieldtype': 'Link',
+		'options': 'Module Def',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:53',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'standard',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Standard',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00316',
+		'no_copy': None,
+		'oldfieldname': 'standard',
+		'oldfieldtype': 'Select',
+		'options': '\nYes\nNo',
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 1,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'criteria_name',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Criteria Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00198',
+		'no_copy': None,
+		'oldfieldname': 'criteria_name',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'description',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Description',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00199',
+		'no_copy': None,
+		'oldfieldname': 'description',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Query Details',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000455',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'doc_type',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Doc Type',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00201',
+		'no_copy': None,
+		'oldfieldname': 'doc_type',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'filters',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 9,
+		'in_filter': None,
+		'label': 'Filters',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00202',
+		'no_copy': None,
+		'oldfieldname': 'filters',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'columns',
+		'fieldtype': 'Text',
+		'hidden': 1,
+		'icon': None,
+		'idx': 10,
+		'in_filter': None,
+		'label': 'Columns',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00203',
+		'no_copy': None,
+		'oldfieldname': 'columns',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'parent_doc_type',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'icon': None,
+		'idx': 11,
+		'in_filter': None,
+		'label': 'Parent Doc Type',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00204',
+		'no_copy': None,
+		'oldfieldname': 'parent_doc_type',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_cond',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 12,
+		'in_filter': None,
+		'label': 'Additional Conditions',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00205',
+		'no_copy': None,
+		'oldfieldname': 'add_cond',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_col',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 13,
+		'in_filter': None,
+		'label': 'Additional Columns',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00206',
+		'no_copy': None,
+		'oldfieldname': 'add_col',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'add_tab',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 14,
+		'in_filter': None,
+		'label': 'Additional Tables',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00207',
+		'no_copy': None,
+		'oldfieldname': 'add_tab',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'dis_filters',
+		'fieldtype': 'Text',
+		'hidden': 0,
+		'icon': None,
+		'idx': 15,
+		'in_filter': None,
+		'label': 'Disabled Filters',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00208',
+		'no_copy': None,
+		'oldfieldname': 'dis_filters',
+		'oldfieldtype': 'Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'group_by',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 16,
+		'in_filter': None,
+		'label': 'Group By',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00209',
+		'no_copy': None,
+		'oldfieldname': 'group_by',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'graph_series',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 17,
+		'in_filter': None,
+		'label': 'Graph Series',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00210',
+		'no_copy': None,
+		'oldfieldname': 'graph_series',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'graph_values',
+		'fieldtype': 'Data',
+		'hidden': 0,
+		'icon': None,
+		'idx': 18,
+		'in_filter': None,
+		'label': 'Graph Values',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00211',
+		'no_copy': None,
+		'oldfieldname': 'graph_values',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:27:40',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'sort_by',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 19,
+		'in_filter': None,
+		'label': 'Sort By',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00300',
+		'no_copy': None,
+		'oldfieldname': 'sort_by',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:27:40',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'sort_order',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 20,
+		'in_filter': None,
+		'label': 'Sort Order',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00299',
+		'no_copy': None,
+		'oldfieldname': 'sort_order',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-09-23 16:21:53',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'page_len',
+		'fieldtype': 'Int',
+		'hidden': None,
+		'icon': None,
+		'idx': 21,
+		'in_filter': None,
+		'label': 'Page Len',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00317',
+		'no_copy': None,
+		'oldfieldname': 'page_len',
+		'oldfieldtype': 'Int',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 22,
+		'in_filter': None,
+		'label': 'Client Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000456',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'report_script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 23,
+		'in_filter': None,
+		'label': 'Report Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00213',
+		'no_copy': None,
+		'oldfieldname': 'report_script',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 24,
+		'in_filter': None,
+		'label': 'Server Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000457',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-05-12 11:19:12',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'server_script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 25,
+		'in_filter': None,
+		'label': 'Report Server Script',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00215',
+		'no_copy': None,
+		'oldfieldname': 'server_script',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Section Break',
+		'hidden': None,
+		'icon': None,
+		'idx': 26,
+		'in_filter': None,
+		'label': 'Overload Query',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000458',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': 'Section Break',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2009-07-08 23:44:31',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'custom_query',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 27,
+		'in_filter': None,
+		'label': 'Custom Query',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '_FL00302',
+		'no_copy': None,
+		'oldfieldname': 'custom_query',
+		'oldfieldtype': 'Code',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Search Criteria',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/stylesheet/__init__.py b/cgi-bin/core/doctype/stylesheet/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/stylesheet/stylesheet.py b/cgi-bin/core/doctype/stylesheet/stylesheet.py
new file mode 100644
index 0000000000..9a4c7f9f66
--- /dev/null
+++ b/cgi-bin/core/doctype/stylesheet/stylesheet.py
@@ -0,0 +1,18 @@
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d,dl
+
+	# export
+	def on_update(self):
+		import webnotes.defs
+		
+		if hasattr(webnotes.defs, 'developer_mode') and webnotes.defs.developer_mode:
+			from webnotes.modules.export_module import export_to_files	
+			from webnotes.modules import get_module_path, scurb
+			import os
+			
+			export_to_files(record_list=[['Stylesheet', self.doc.name]])
+
+			file = open(os.path.join(get_module_path(self.doc.module), 'Stylesheet', scrub(self.doc.name), scrub(self.doc.name) + '.html'), 'w')
+			file.write(self.doc.content)
+			file.close()	
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/stylesheet/stylesheet.txt b/cgi-bin/core/doctype/stylesheet/stylesheet.txt
new file mode 100644
index 0000000000..a067224731
--- /dev/null
+++ b/cgi-bin/core/doctype/stylesheet/stylesheet.txt
@@ -0,0 +1,160 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'field:stylesheet_name',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2011-04-05 10:01:46',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-02-21 17:10:05',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Stylesheet',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': None,
+		'show_in_menu': None,
+		'smallicon': None,
+		'use_template': None,
+		'version': 4
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'stylesheet_name',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Stylesheet Name',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000459',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'module',
+		'fieldtype': 'Link',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Module',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000460',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': 'Module Def',
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-05 10:01:46',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'stylesheet',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Stylesheet',
+		'modified': '2011-04-05 10:01:46',
+		'modified_by': 'Administrator',
+		'name': '000000461',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Stylesheet',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/__init__.py b/cgi-bin/core/doctype/system_console/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/system_console/system_console.comp.js b/cgi-bin/core/doctype/system_console/system_console.comp.js
new file mode 100644
index 0000000000..97e8afd0b0
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.comp.js
@@ -0,0 +1,8 @@
+
+cur_frm.cscript['Server (Python)']=function(doc,dt,dn){$c_obj([doc],'execute_server','',function(r,rt){doc=locals[doc.doctype][doc.name];if(r.exc){doc.response=r.exc;}else{doc.response='Worked!'}
+refresh_field('response');})}
+cur_frm.cscript['Client (JS)']=function(doc,dt,dn){try{doc.response=eval(doc.script);}catch(e){doc.response=e.toString()
++'\nMessage:'+e.message
++'\nLine Number:'+e.lineNumber
++'\nStack:'+e.stack;}
+refresh_field('response');}
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/system_console.js b/cgi-bin/core/doctype/system_console/system_console.js
new file mode 100644
index 0000000000..a16c39f6ac
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.js
@@ -0,0 +1,23 @@
+cur_frm.cscript['Server (Python)'] = function(doc, dt, dn) {
+	$c_obj([doc], 'execute_server', '', function(r, rt) {
+		doc = locals[doc.doctype][doc.name];
+		if(r.exc) {
+			doc.response = r.exc;
+		} else {
+			doc.response = 'Worked!'
+		}
+		refresh_field('response');
+	})
+}
+
+cur_frm.cscript['Client (JS)'] = function(doc, dt, dn) {
+	try {
+		doc.response = eval(doc.script);		
+	} catch(e) {
+		doc.response = e.toString() 
+			+ '\nMessage:' + e.message
+			+ '\nLine Number:' + e.lineNumber
+			+ '\nStack:' + e.stack;
+	}
+	refresh_field('response');
+}
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/system_console/system_console.py b/cgi-bin/core/doctype/system_console/system_console.py
new file mode 100644
index 0000000000..511cf518ab
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.py
@@ -0,0 +1,17 @@
+import webnotes
+
+from webnotes.utils import cint, flt
+from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
+from webnotes import session, msgprint, errprint
+
+sql = webnotes.conn.sql
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
+
+	def execute_server(self, arg=''):
+		if webnotes.user.name=='Guest':
+			raise Exception, 'Guest cannot call execute test!'
+		exec(self.doc.script)
diff --git a/cgi-bin/core/doctype/system_console/system_console.txt b/cgi-bin/core/doctype/system_console/system_console.txt
new file mode 100644
index 0000000000..cf5ff1434d
--- /dev/null
+++ b/cgi-bin/core/doctype/system_console/system_console.txt
@@ -0,0 +1,242 @@
+[
+	{
+		'_last_update': '1303450387',
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': 'System',
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 1,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-04-22 13:12:21',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'System Console',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': None,
+		'show_in_menu': 1,
+		'smallicon': None,
+		'use_template': None,
+		'version': 6
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': 1,
+		'creation': '2011-05-09 10:50:36',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 1,
+		'match': None,
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000145',
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': 1
+	},
+	{
+		'amend': None,
+		'cancel': None,
+		'create': None,
+		'creation': '2011-05-09 10:50:36',
+		'docstatus': 0,
+		'doctype': 'DocPerm',
+		'execute': None,
+		'idx': 2,
+		'match': None,
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000146',
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'read': 1,
+		'role': 'Administrator',
+		'submit': None,
+		'write': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'script',
+		'fieldtype': 'Code',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Script',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000147',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'Server (Python)',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000148',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': 'White:FFF',
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': None,
+		'fieldtype': 'Button',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'Client (JS)',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000149',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': 'Client',
+		'width': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-05-09 10:50:36',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'response',
+		'fieldtype': 'Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'Error',
+		'modified': '2011-05-09 10:50:36',
+		'modified_by': 'Administrator',
+		'name': '000000150',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'System Console',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 1,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/table_mapper_detail/__init__.py b/cgi-bin/core/doctype/table_mapper_detail/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt b/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt
new file mode 100644
index 0000000000..494fef1abf
--- /dev/null
+++ b/cgi-bin/core/doctype/table_mapper_detail/table_mapper_detail.txt
@@ -0,0 +1,335 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'TMD/.#######',
+		'change_log': None,
+		'client_script': '',
+		'client_script_core': '',
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2010-11-30 17:30:05',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': 1,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Table Mapper Detail',
+		'name_case': '',
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': '',
+		'read_only': None,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Tray',
+		'server_code': '',
+		'server_code_compiled': None,
+		'server_code_core': '',
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': '',
+		'use_template': None,
+		'version': 5
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'from_table',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'From Table',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00587',
+		'no_copy': None,
+		'oldfieldname': 'from_table',
+		'oldfieldtype': 'Select',
+		'options': 'link:DocType',
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'to_table',
+		'fieldtype': 'Select',
+		'hidden': None,
+		'icon': None,
+		'idx': 2,
+		'in_filter': None,
+		'label': 'To Table',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00588',
+		'no_copy': None,
+		'oldfieldname': 'to_table',
+		'oldfieldtype': 'Select',
+		'options': 'link:DocType',
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'from_field',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 3,
+		'in_filter': None,
+		'label': 'From Field',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00589',
+		'no_copy': None,
+		'oldfieldname': 'from_field',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'to_field',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 4,
+		'in_filter': None,
+		'label': 'To Field',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00590',
+		'no_copy': None,
+		'oldfieldname': 'to_field',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': '140px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'match_id',
+		'fieldtype': 'Int',
+		'hidden': None,
+		'icon': None,
+		'idx': 5,
+		'in_filter': None,
+		'label': 'Match Id',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00591',
+		'no_copy': None,
+		'oldfieldname': 'match_id',
+		'oldfieldtype': 'Int',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': None,
+		'trigger': None,
+		'width': '60px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:05',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'validation_logic',
+		'fieldtype': 'Small Text',
+		'hidden': None,
+		'icon': None,
+		'idx': 6,
+		'in_filter': None,
+		'label': 'Validation Logic',
+		'modified': '2010-11-30 17:30:05',
+		'modified_by': 'Administrator',
+		'name': '_FL00592',
+		'no_copy': None,
+		'oldfieldname': 'validation_logic',
+		'oldfieldtype': 'Small Text',
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 1,
+		'search_index': None,
+		'trigger': None,
+		'width': '150px'
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:06',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reference_doctype_key',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 7,
+		'in_filter': None,
+		'label': 'Reference DocType Key',
+		'modified': '2010-11-30 17:30:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00593',
+		'no_copy': None,
+		'oldfieldname': 'reference_doctype_key',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'nabin@webnotestech.com',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': ''
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2010-11-30 17:30:06',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'reference_key',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 8,
+		'in_filter': None,
+		'label': 'Reference Docname Key',
+		'modified': '2010-11-30 17:30:06',
+		'modified_by': 'Administrator',
+		'name': '_FL00594',
+		'no_copy': None,
+		'oldfieldname': 'reference_key',
+		'oldfieldtype': 'Data',
+		'options': None,
+		'owner': 'nabin@webnotestech.com',
+		'parent': 'Table Mapper Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/tag/__init__.py b/cgi-bin/core/doctype/tag/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/tag/tag.txt b/cgi-bin/core/doctype/tag/tag.txt
new file mode 100644
index 0000000000..9538f864a3
--- /dev/null
+++ b/cgi-bin/core/doctype/tag/tag.txt
@@ -0,0 +1,90 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': None,
+		'allow_email': None,
+		'allow_print': None,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': None,
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2010-08-08 17:09:26',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': None,
+		'hide_toolbar': None,
+		'idx': None,
+		'in_create': 1,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': None,
+		'istable': None,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2011-04-06 10:36:05',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'Tag',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 1,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': 7
+	},
+	{
+		'allow_on_submit': None,
+		'colour': None,
+		'creation': '2011-04-06 10:35:22',
+		'default': None,
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'tag_color',
+		'fieldtype': 'Data',
+		'hidden': None,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Tag Color',
+		'modified': '2011-04-06 10:36:05',
+		'modified_by': 'Administrator',
+		'name': '000000467',
+		'no_copy': None,
+		'oldfieldname': None,
+		'oldfieldtype': None,
+		'options': None,
+		'owner': 'Administrator',
+		'parent': 'Tag',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': None,
+		'search_index': None,
+		'trigger': None,
+		'width': None
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/doctype/userrole/__init__.py b/cgi-bin/core/doctype/userrole/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/doctype/userrole/userrole.txt b/cgi-bin/core/doctype/userrole/userrole.txt
new file mode 100644
index 0000000000..9e99c293e7
--- /dev/null
+++ b/cgi-bin/core/doctype/userrole/userrole.txt
@@ -0,0 +1,90 @@
+[
+	{
+		'allow_attach': None,
+		'allow_copy': 0,
+		'allow_email': 0,
+		'allow_print': 0,
+		'allow_rename': None,
+		'allow_trash': None,
+		'autoname': 'UR.#####',
+		'change_log': None,
+		'client_script': None,
+		'client_script_core': None,
+		'client_string': None,
+		'colour': 'White:FFF',
+		'creation': '2009-05-12 11:19:11',
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocType',
+		'document_type': None,
+		'dt_template': None,
+		'hide_heading': 0,
+		'hide_toolbar': 0,
+		'idx': 0,
+		'in_create': None,
+		'in_dialog': None,
+		'is_transaction_doc': None,
+		'issingle': 0,
+		'istable': 1,
+		'max_attachments': None,
+		'menu_index': None,
+		'modified': '2010-09-20 14:06:57',
+		'modified_by': 'Administrator',
+		'module': 'Core',
+		'name': 'UserRole',
+		'name_case': None,
+		'owner': 'Administrator',
+		'parent': None,
+		'parent_node': None,
+		'parentfield': None,
+		'parenttype': None,
+		'print_outline': None,
+		'read_only': 0,
+		'read_only_onload': None,
+		'search_fields': None,
+		'section_style': 'Simple',
+		'server_code': None,
+		'server_code_compiled': None,
+		'server_code_core': None,
+		'server_code_error': ' ',
+		'show_in_menu': 0,
+		'smallicon': None,
+		'use_template': None,
+		'version': None
+	},
+	{
+		'allow_on_submit': None,
+		'colour': '',
+		'creation': '2009-05-12 11:19:12',
+		'default': '',
+		'depends_on': None,
+		'description': None,
+		'docstatus': 0,
+		'doctype': 'DocField',
+		'fieldname': 'role',
+		'fieldtype': 'Link',
+		'hidden': 0,
+		'icon': None,
+		'idx': 1,
+		'in_filter': None,
+		'label': 'Role',
+		'modified': '2009-05-12 11:19:12',
+		'modified_by': 'Administrator',
+		'name': '_FL00236',
+		'no_copy': None,
+		'oldfieldname': 'role',
+		'oldfieldtype': 'Link',
+		'options': 'Role',
+		'owner': 'Administrator',
+		'parent': 'UserRole',
+		'parentfield': 'fields',
+		'parenttype': 'DocType',
+		'permlevel': 0,
+		'print_hide': None,
+		'report_hide': None,
+		'reqd': 0,
+		'search_index': 0,
+		'trigger': '',
+		'width': '200px'
+	}
+]
\ No newline at end of file
diff --git a/cgi-bin/core/module.info b/cgi-bin/core/module.info
new file mode 100644
index 0000000000..f51efd8b20
--- /dev/null
+++ b/cgi-bin/core/module.info
@@ -0,0 +1 @@
+{'update_date': '2011-03-18 18:12:06'}
\ No newline at end of file
diff --git a/cgi-bin/core/page/__init__.py b/cgi-bin/core/page/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/page/login_page/__init__.py b/cgi-bin/core/page/login_page/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cgi-bin/core/page/login_page/login_page.html b/cgi-bin/core/page/login_page/login_page.html
new file mode 100644
index 0000000000..3242669c6b
--- /dev/null
+++ b/cgi-bin/core/page/login_page/login_page.html
@@ -0,0 +1,29 @@
+
+

Login

+ + + + + + + + + + + + + + + + + + + + + + + +
Login Id
Password
Remember Me
  
 
+

Forgot Password

+

Debug

+
\ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page.js b/cgi-bin/core/page/login_page/login_page.js new file mode 100644 index 0000000000..6f73ae14db --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page.js @@ -0,0 +1,56 @@ +pscript['onload_Login Page'] = function(){ + var lw = $i('login_wrapper') + $bs(lw, '1px 1px 3px #888'); + $bg(document.getElementsByTagName('body')[0], '#DDD'); + + pscript.login_btn = $btn('login_btn', 'Login', pscript.doLogin) + + keypress_observers.push(new function() { + this.notify_keypress = function(kc) { if(kc==13 && $i("password").value) pscript.doLogin(); } + } + ); +} + + +// Login Callback +pscript.onLoginReply = function(r, rtext) { + pscript.login_btn.done_working(); + if(r.message=="Logged In"){ + window.location.href='index.cgi' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : ''); + } else { + $i('login_message').innerHTML = ''+eval(r.message)+''; + //if(r.exc)alert(r.exc); + } +} + + +// Login +pscript.doLogin = function(){ + + var args = {}; + args['usr']=$i("login_id").value; + args['pwd']=$i("password").value; + if($i('remember_me').checked) + args['remember_me'] = 1; + + pscript.login_btn.set_working(); + + $c("login", args, pscript.onLoginReply); +} + + +pscript.show_forgot_password = function(){ + // create dialog + var d = new Dialog(400, 400, 'Reset Password') + d.make_body([['HTML','Title','Enter your email id to reset the password'], ['Data','Email Id'], ['Button','Reset']]); + + var callback = function(r,rt) { + if(!r.exc) pscript.forgot_dialog.hide(); + } + + d.widgets['Reset'].onclick = function() { + $c('reset_password', {user: pscript.forgot_dialog.widgets['Email Id'].value}, callback) + } + d.show(); + pscript.forgot_dialog = d; +} \ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page.txt b/cgi-bin/core/page/login_page/login_page.txt new file mode 100644 index 0000000000..0764e237f3 --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page.txt @@ -0,0 +1,33 @@ +[ + { + 'content': None, + 'creation': '2010-01-20 11:10:18', + 'docstatus': 0, + 'doctype': 'Page', + 'icon': None, + 'idx': None, + 'keywords': None, + 'menu_index': None, + 'modified': '2011-02-17 13:01:57', + 'modified_by': 'Administrator', + 'module': 'Core', + 'name': 'Login Page', + 'owner': 'Administrator', + 'page_name': 'Login Page', + 'page_title': None, + 'parent': None, + 'parent_node': None, + 'parentfield': None, + 'parenttype': None, + 'publish': None, + 'script': None, + 'show_in_menu': None, + 'site_description': None, + 'standard': 'Yes', + 'static_content': None, + 'style': None, + 'stylesheet': None, + 'template': None, + 'write_content': 1 + } +] \ No newline at end of file diff --git a/cgi-bin/core/page/login_page/login_page_static.html b/cgi-bin/core/page/login_page/login_page_static.html new file mode 100644 index 0000000000..00a339f2d2 --- /dev/null +++ b/cgi-bin/core/page/login_page/login_page_static.html @@ -0,0 +1,3 @@ +

Login Page

+ +

Powered by Web Notes Framework

\ No newline at end of file diff --git a/cgi-bin/getfile.cgi b/cgi-bin/getfile.cgi new file mode 100755 index 0000000000..cd652c0b6d --- /dev/null +++ b/cgi-bin/getfile.cgi @@ -0,0 +1,82 @@ +#!/usr/bin/python + +try: + + import sys, os + + sys.path.append(os.getcwd()+'/cgi-bin') + + def getTraceback(): + import sys, traceback, string + type, value, tb = sys.exc_info() + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) \ + + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + return body + + import cgi + import webnotes + import webnotes.auth + import webnotes.utils + import webnotes.utils.file_manager + import webnotes.db + import webnotes.defs + + sys.path.append(webnotes.defs.modules_path) + + form = cgi.FieldStorage() + webnotes.form_dict = {} + + for each in form.keys(): + webnotes.form_dict[each] = form.getvalue(each) + + n = form.getvalue('name') + + # authenticate + webnotes.auth.HTTPRequest() + + # get file + res = webnotes.utils.file_manager.get_file(n) + + fname = res[0] + if hasattr(res[1], 'tostring'): + fcontent = res[1].tostring() + else: + fcontent = res[1] + + if form.getvalue('thumbnail'): + tn = webnotes.utils.cint(form.getvalue('thumbnail')) + try: + from PIL import Image + import cStringIO + + fobj = cStringIO.StringIO(fcontent) + image = Image.open(fobj) + image.thumbnail((tn,tn*2), Image.ANTIALIAS) + outfile = cStringIO.StringIO() + + if image.mode != "RGB": + image = image.convert("RGB") + + image.save(outfile, 'JPEG') + outfile.seek(0) + fcontent = outfile.read() + except: + pass + + import mimetypes + print "Content-Type: %s" % (mimetypes.guess_type(fname)[0] or 'application/unknown') + print "Content-Disposition: filename="+fname.replace(' ', '_') + print "Cache-Control: max-age=3600" + print + print fcontent + +except Exception, e: + print "Content-Type: text/html" + try: + out = {'message':'', 'exc':getTraceback().replace('\n','
')} + except: + out = {'exc': e} + print + print str(out) diff --git a/cgi-bin/getjsfile.cgi b/cgi-bin/getjsfile.cgi new file mode 100755 index 0000000000..18a876cead --- /dev/null +++ b/cgi-bin/getjsfile.cgi @@ -0,0 +1,73 @@ +#!/usr/bin/python + +import cgi +import datetime +import os + +try: + + form = cgi.FieldStorage() + out = '' + out_buf, str_out = '', '' + + # Traceback + # --------- + def getTraceback(): + import sys, traceback, string + type, value, tb = sys.exc_info() + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) \ + + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + return body + + def load_js_file(): + global out + filename = form.getvalue('filename') + import os + try: + f = open(os.path.join('../js/', filename)) + try: + out = f.read() + finally: + f.close() + except IOError,e: + out = "Not Found: %s" % filename + + def compress_string(buf): + import gzip, cStringIO + zbuf = cStringIO.StringIO() + zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) + zfile.write(buf) + zfile.close() + return zbuf.getvalue() + + compress = 0 + try: + if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: + compress = 1 + except: + pass + + load_js_file() + + if compress and len(out)>512: + out_buf = compress_string(str_out) + print "Content-Encoding: gzip" + print "Content-Length: %d" % (len(out_buf)) + + print "Content-Type: text/javascript" + + # Headers end + print + + if out_buf: + sys.stdout.write(out_buf) + elif out: + print out + +except Exception, e: + print "Content-Type: text/javascript" + print + print getTraceback().replace('\n','
') + \ No newline at end of file diff --git a/cgi-bin/pypi-setup.py b/cgi-bin/pypi-setup.py new file mode 100755 index 0000000000..07c6bb952d --- /dev/null +++ b/cgi-bin/pypi-setup.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Script for creating the pypi packages +# Works only for python 2.6+ + + +import os + +try: + from setuptools import setup, find_packages +except ImportError: + import ez_setup + ez_setup.use_setuptools() + from setuptools import setup, find_packages + +# Startup +appname = "webnotes-core" +appversion = "v170" + +setup( + name = appname, + version = appversion, + author = "Rushabh Mehta", + namespace_packages = ["webnotes"], + packages = ["webnotes"] + [ os.path.join("webnotes", a) for a in find_packages("webnotes") ], + author_email = "rmehta@gmail.com", + description = "A meta-data based library for creating web apps in python and javascript", + license = "MIT", + keywords = "Meta-data web app framework python", + url = "http://code.google.com/p/webnotes/", + classifiers = ["License :: OSI Approved :: MIT License","Topic :: Software Development :: Libraries :: Python Modules"], + long_description = "Webnotes is a meta-data based framework for web applications in python", +) + diff --git a/cgi-bin/webnotes/__init__.py b/cgi-bin/webnotes/__init__.py new file mode 100644 index 0000000000..8607425ffb --- /dev/null +++ b/cgi-bin/webnotes/__init__.py @@ -0,0 +1,228 @@ +# +# import modules path +# +import os, sys + +try: + import webnotes.defs + m = getattr(webnotes.defs,'modules_path',None) + m and sys.path.append(m) +except Exception,e: + raise e + +# +# map for identifying which field values come from files +# +code_fields_dict = { + 'Page':[('script', 'js'), ('content', 'html'), ('style', 'css'), ('static_content', 'html'), ('server_code', 'py')], + 'DocType':[('server_code_core', 'py'), ('client_script_core', 'js')], + 'Search Criteria':[('report_script', 'js'), ('server_script', 'py'), ('custom_query', 'sql')], + 'Patch':[('patch_code', 'py')], + 'Stylesheet':['stylesheet', 'css'], + 'Page Template':['template', 'html'], + 'Control Panel':[('startup_code', 'js'), ('startup_css', 'css')] +} + +# +# globals +# +#: "v170" +version = 'v170' +form_dict = {} +auth_obj = None + +#: The database connection :class:`webnotes.db.Database` setup by :mod:`auth` +conn = None + +#: The cgi.FieldStorage() object (Dictionary representing the formdata from the URL) +form = None + +session = None +""" + Global session dictionary. + + * session['user'] - Current user + * session['data'] - Returns a dictionary of the session cache +""" + +user = None +is_testing = None +""" Flag to identify if system is in :term:`Testing Mode` """ + +incoming_cookies = {} +add_cookies = {} +""" Dictionary of additional cookies appended by custom code """ + +cookies = {} +auto_masters = {} +tenant_id = None + +# +# Custom Class (no traceback) +# +class ValidationError(Exception): + pass + +# +# HTTP standard response +# +response = {'message':'', 'exc':''} +""" + The JSON response object. Default is:: + + {'message':'', 'exc':''} +""" + +# +# the logs +# +debug_log = [] +""" List of exceptions to be shown in the :term:`Error Console` """ + +message_log = [] +""" List of messages to be shown to the user in a popup box at the end of the request """ + +def getTraceback(): + import webnotes.utils + return webnotes.utils.getTraceback() + +def errprint(msg): + """ + Append to the :data:`debug log` + """ + debug_log.append(str(msg or '')) + +def msgprint(msg, small=0, raise_exception=0): + """ + Append to the :data:`message_log` + """ + message_log.append((small and '__small:' or '')+str(msg or '')) + if raise_exception: + raise ValidationError + +def is_apache_user(): + import os + if os.environ.get('USER') == 'apache': + return True + else: + return (not os.environ.get('USER')) + # os.environ does not have user, so allows a security vulnerability,fixed now. + +def get_index_path(): + import os + return os.sep.join(os.path.dirname(os.path.abspath(__file__)).split(os.sep)[:-2]) + +def get_files_path(): + global conn + import defs, os + + if not conn: + raise Exception, 'You must login first' + + if defs.files_path: + return os.path.join(defs.files_path, conn.cur_db_name) + else: + return os.path.join(get_index_path(), 'user_files', conn.cur_db_name) + +def create_folder(path): + import os + + try: + os.makedirs(path) + except Exception, e: + if e.args[0]==17: + pass + else: + raise e + + +############################################################################### +# BEGIN: TENTATIVE CODE FEELS LIKE A CLASS/TEMPLATE IS A BETTER IDEA FOR THESE VARIABLES. +# Bad idea combining/using one function to set conn,user,session variables. +# Need to split up. +############################################################################### + +def set_as_account_master(): + import webnotes.db + global conn + conn = webnotes.db.Database(use_default = 1) + +def set_as_administrator(): + + global user + + if is_apache_user(): + raise Exception, 'Not for web users!' + + import webnotes.profile + user = webnotes.profile.Profile('Administrator') + +def set_as_admin_session(): + global session + session = {'user':'Administrator'} + +############################################################################### +#END +############################################################################### + + +def set_as_admin(db_name=None, ac_name=None): + + import os + if is_apache_user(): + raise Exception, 'Not for web users!' + + global conn + global session + global user + + import webnotes.db + if ac_name: + conn = webnotes.db.Database(ac_name = ac_name) + else: + set_as_account_master() + if db_name: + conn.use(db_name) + + session = {'user':'Administrator'} + import webnotes.profile + user = webnotes.profile.Profile('Administrator') + + +# Environment Variables +#----------------------------------------------------------- +def get_env_vars(env_var): + return os.environ.get(env_var,'None') + +remote_ip = get_env_vars('REMOTE_ADDR') #Required for login from python shell + +# Logging +# ----------------------------------------------------------- + +logger = None + + +def setup_logging(): + import logging + import logging.handlers + # Also please set umask for apache to 002. + global logger + + try: + logger = logging.getLogger('WNLogger') + logger.setLevel(eval(defs.log_level)) + + log_handler = logging.handlers.RotatingFileHandler(defs.log_file_name, maxBytes = defs.log_file_size, backupCount = defs.log_file_backup_count) + formatter = logging.Formatter('%(name)s - %(asctime)s - %(levelname)s\n%(message)s\n-------------------') + + log_handler.setFormatter(formatter) + logger.addHandler(log_handler) + + except IOError,e: + if e.args == 13: + open(defs.log_file_name).close() + + +if getattr(defs, 'log_file_name', None): + setup_logging() + diff --git a/cgi-bin/webnotes/auth.py b/cgi-bin/webnotes/auth.py new file mode 100644 index 0000000000..c83118ce80 --- /dev/null +++ b/cgi-bin/webnotes/auth.py @@ -0,0 +1,424 @@ +import webnotes +import webnotes.db +import webnotes.utils +import webnotes.profile +import webnotes.defs + +# ================================================================================= +# HTTPRequest +# ================================================================================= + +class HTTPRequest: + def __init__(self): + + # Get Environment variables + self.domain = webnotes.get_env_vars('HTTP_HOST') + if self.domain and self.domain.startswith('www.'): + self.domain = self.domain[4:] + + webnotes.remote_ip = webnotes.get_env_vars('REMOTE_ADDR') + + # load cookies + webnotes.cookie_manager = CookieManager() + + # set db + self.set_db() + + # check status + if webnotes.conn.get_global("__session_status")=='stop': + webnotes.msgprint(webnotes.conn.get_global("__session_status_message")) + raise Exception + + # ----------------------------- + # start transaction + webnotes.conn.begin() + + # login + webnotes.login_manager = LoginManager() + + # start session + webnotes.session_obj = Session() + webnotes.session = webnotes.session_obj.data + webnotes.tenant_id = webnotes.session.get('tenant_id', 0) + + # write out cookies if sid is supplied (this is a pre-logged in redirect) + if webnotes.form_dict.get('sid'): + webnotes.cookie_manager.set_cookies() + + # run login triggers + if webnotes.form_dict.get('cmd')=='login': + webnotes.login_manager.run_trigger('on_login_post_session') + + # load profile + self.setup_profile() + + webnotes.conn.commit() + # end transaction + # ----------------------------- + + # setup profile + # ------------- + + def setup_profile(self): + webnotes.user = webnotes.profile.Profile() + # load the profile data + if webnotes.session['data'].get('profile'): + webnotes.user.load_from_session(webnotes.session['data']['profile']) + else: + webnotes.user.load_profile() + + + # get account name + # ------------------ + + def get_ac_name(self): + # login + if webnotes.form_dict.get('acx'): + return webnotes.form_dict.get('acx') + + # in form + elif webnotes.form_dict.get('ac_name'): + return webnotes.form_dict.get('ac_name') + + # in cookie + elif webnotes.incoming_cookies.get('ac_name'): + return webnotes.incoming_cookies.get('ac_name') + + + # set database login + # ------------------ + + def set_db(self, ac_name = None): + + + # select based on subdomain + if getattr(webnotes.defs,'domain_name_map', {}).get(self.domain): + db_name = webnotes.defs.domain_name_map[self.domain] + + # select based on ac_name + else: + ac_name = self.get_ac_name() + if ac_name: + db_name = getattr(webnotes.defs,'db_name_map',{}).\ + get(ac_name, ac_name) + else: + db_name = getattr(webnotes.defs,'default_db_name','') + + webnotes.conn = webnotes.db.Database(user = db_name,password = getattr(webnotes.defs,'db_password','')) + webnotes.ac_name = ac_name + +# ================================================================================= +# Login Manager +# ================================================================================= + +class LoginManager: + def __init__(self): + self.cp = None + if webnotes.form_dict.get('cmd')=='login': + # clear cache + from webnotes.session_cache import clear_cache + clear_cache(webnotes.form_dict.get('usr')) + + self.authenticate() + self.post_login() + webnotes.response['message'] = 'Logged In' + + # run triggers, write cookies + # --------------------------- + + def post_login(self): + self.validate_ip_address() + self.run_trigger() + + # check password + # -------------- + + def authenticate(self, user=None, pwd=None): + if not (user and pwd): + user, pwd = webnotes.form_dict.get('usr'), webnotes.form_dict.get('pwd') + + if not (user and pwd): + webnotes.msgprint('Incomplete Login Details', raise_exception=1) + + # custom authentication (for single-sign on) + self.load_control_panel() + if hasattr(self.cp, 'authenticate'): + self.user = self.cp.authenticate() + + # check the password + if user=='Administrator': + p = webnotes.conn.sql("select name from tabProfile where name=%s and (`password`=%s OR `password`=PASSWORD(%s))", (user, pwd, pwd)) + else: + p = webnotes.conn.sql("select name from tabProfile where name=%s and (`password`=%s OR `password`=PASSWORD(%s)) and IFNULL(enabled,0)=1", (user, pwd, pwd)) + + if not p: + webnotes.msgprint('Authentication Failed', raise_exception=1) + + self.user = p[0][0] + + # triggers + # -------- + + def load_control_panel(self): + import webnotes.model.code + try: + if not self.cp: + self.cp = webnotes.model.code.get_obj('Control Panel') + except Exception, e: + webnotes.response['Control Panel Exception'] = webnotes.utils.getTraceback() + + # -------- + def run_trigger(self, method='on_login'): + try: + import event_handlers + if hasattr(event_handlers, method): + getattr(event_handlers, method)(self) + return + except ImportError, e: + pass + + # deprecated + self.load_control_panel() + if self.cp and hasattr(self.cp, method): + getattr(self.cp, method)(self) + + # ip validation + # ------------- + + def validate_ip_address(self): + try: + ip = webnotes.conn.sql("select ip_address from tabProfile where name = '%s'" % self.user)[0][0] or '' + except: return + + ip = ip.replace(",", "\n").split('\n') + ip = [i.strip() for i in ip] + + if ret and ip: + if not (webnotes.remote_ip.startswith(ip[0]) or (webnotes.remote_ip in ip)): + raise Exception, 'Not allowed from this IP Address' + + # login as guest + # -------------- + + def login_as_guest(self): + res = webnotes.conn.sql("select name from tabProfile where name='Guest' and ifnull(enabled,0)=1") + if not res: + raise Exception, "No Guest Access" + self.user = 'Guest' + self.post_login() + + # Logout + # ------ + + def call_on_logout_event(self): + import webnotes.model.code + cp = webnotes.model.code.get_obj('Control Panel', 'Control Panel') + if hasattr(cp, 'on_logout'): + cp.on_logout(self) + + def logout(self, arg=''): + self.run_trigger('on_logout') + webnotes.conn.sql('update tabSessions set status="Logged Out" where sid="%s"' % webnotes.session['sid']) + +# ================================================================================= +# Cookie Manager +# ================================================================================= + +class CookieManager: + def __init__(self): + import Cookie + webnotes.cookies = Cookie.SimpleCookie() + self.get_incoming_cookies() + + # get incoming cookies + # -------------------- + def get_incoming_cookies(self): + import os + cookies = {} + if 'HTTP_COOKIE' in os.environ: + c = os.environ['HTTP_COOKIE'] + webnotes.cookies.load(c) + for c in webnotes.cookies.values(): + cookies[c.key] = c.value + + webnotes.incoming_cookies = cookies + + # Set cookies + # ----------- + + def set_cookies(self): + if webnotes.conn.cur_db_name: + webnotes.cookies['account_id'] = webnotes.conn.cur_db_name + + # ac_name + webnotes.cookies['ac_name'] = webnotes.ac_name or '' + + if webnotes.session.get('sid'): + webnotes.cookies['sid'] = webnotes.session['sid'] + + # sid expires in 3 days + import datetime + expires = datetime.datetime.now() + datetime.timedelta(days=3) + + webnotes.cookies['sid']['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S') + + # Set Remember Me + # --------------- + + def set_remember_me(self): + if webnotes.utils.cint(webnotes.form_dict.get('remember_me')): + remember_days = webnotes.conn.get_value('Control Panel',None,'remember_for_days') or 7 + webnotes.cookies['remember_me'] = 1 + + import datetime + expires = datetime.datetime.now() + datetime.timedelta(days=remember_days) + + for k in webnotes.cookies.keys(): + webnotes.cookies[k]['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S') + +# ================================================================================= +# Session +# ================================================================================= + +class Session: + def __init__(self, user=None): + self.user = user + self.sid = webnotes.form_dict.get('sid') or webnotes.incoming_cookies.get('sid') + self.data = {'user':user,'data':{}} + + if webnotes.form_dict.get('cmd')=='login': + self.start() + return + + self.load() + + # start a session + # --------------- + def load(self): + import webnotes + + r=None + try: + r = webnotes.conn.sql("select user, sessiondata, status from tabSessions where sid='%s'" % self.sid) + except Exception, e: + if e.args[0]==1054: + self.add_status_column() + else: + raise e + + if r: + r=r[0] + + # ExipredSession + if r[2]=='Expired' and (webnotes.form_dict.get('cmd')!='resume_session'): + if r[0]=='Guest' or (not webnotes.form_dict.get('cmd')) or webnotes.form_dict.get('cmd')=='logout': + webnotes.login_manager.login_as_guest() + self.start() + else: + webnotes.response['session_status'] = 'Session Expired' + raise Exception, 'Session Expired' + elif r[2]=='Logged Out': + webnotes.login_manager.login_as_guest() + self.start() + # allow refresh or logout + if webnotes.form_dict.get('cmd') and webnotes.form_dict.get('cmd')!='logout': + webnotes.response['session_status'] = 'Logged Out' + raise Exception, 'Logged Out' + else: + self.data = {'data':eval(r[1]), 'user':r[0], 'sid': self.sid} + else: + webnotes.login_manager.login_as_guest() + self.start() + + + # start a session + # --------------- + def start(self): + import os + import webnotes + import webnotes.utils + + # generate sid + self.data['user'] = webnotes.login_manager.user + self.data['sid'] = webnotes.utils.generate_hash() + self.data['data']['session_ip'] = os.environ.get('REMOTE_ADDR'); + self.data['data']['tenant_id'] = webnotes.form_dict.get('tenant_id', 0) + + # get ipinfo + if webnotes.conn.get_global('get_ip_info'): + self.get_ipinfo() + + # insert session + try: + self.insert_session_record() + except Exception, e: + if e.args[0]==1054: + self.add_status_column() + self.insert_session_record() + else: + raise e + + # update profile + webnotes.conn.sql("UPDATE tabProfile SET last_login = '%s', last_ip = '%s' where name='%s'" % (webnotes.utils.now(), webnotes.remote_ip, self.data['user'])) + + # set cookies to write + webnotes.session = self.data + webnotes.cookie_manager.set_cookies() + + + # resume session + # -------------- + def resume(self): + pwd = webnotes.form_dict.get('pwd') + webnotes.login_manager.authenticate(self.data['user'], pwd) + webnotes.conn.sql("update tabSessions set status='Active' where sid=%s", self.data['sid']) + return 'Logged In' + + # update session + # -------------- + def update(self): + # update session + webnotes.conn.sql("update tabSessions set sessiondata=%s, user=%s, lastupdate=NOW() where sid=%s" , (str(self.data['data']), self.data['user'], self.data['sid'])) + + self.check_expired() + + # check expired + # ------------- + def check_expired(self): + # in control panel? + exp_sec = webnotes.conn.get_value('Control Panel', None, 'session_expiry') or '6:00:00' + + # set sessions as expired + try: + webnotes.conn.sql("update from tabSessions where TIMEDIFF(NOW(), lastupdate) > %s SET `status`='Expired'", exp_sec) + except Exception, e: + if e.args[0]==1054: + self.add_status_column() + + # clear out old sessions + webnotes.conn.sql("delete from tabSessions where TIMEDIFF(NOW(), lastupdate) > '72:00:00'") + + # ----------------------------- + def add_status_column(self): + webnotes.conn.commit() + webnotes.conn.sql("alter table tabSessions add column `status` varchar(20)") + webnotes.conn.begin() + + + # Get IP Info from ipinfodb.com + # ----------------------------- + def get_ipinfo(self): + import os + + try: + import pygeoip + except: + return + + gi = pygeoip.GeoIP('data/GeoIP.dat') + self.data['data']['ipinfo'] = {'countryName': gi.country_name_by_addr(os.environ.get('REMOTE_ADDR'))} + + # ----------------------------- + def insert_session_record(self): + webnotes.conn.sql("insert into tabSessions (sessiondata, user, lastupdate, sid, status) values (%s , %s, NOW(), %s, 'Active')", (str(self.data['data']), self.data['user'], self.data['sid'])) + diff --git a/cgi-bin/webnotes/db.py b/cgi-bin/webnotes/db.py new file mode 100644 index 0000000000..912d70437c --- /dev/null +++ b/cgi-bin/webnotes/db.py @@ -0,0 +1,310 @@ +# Database Module +# -------------------- + +import MySQLdb +from webnotes import defs +import webnotes + +class Database: + """ + Open a database connection with the given parmeters, if use_default is True, use the + login details from `defs.py`. This is called by the request handler and is accessible using + the `conn` global variable. the `sql` method is also global to run queries + """ + def __init__(self, host='', user='', password='', ac_name = '', use_default = 0): + self.host = host or 'localhost' + self.user = user or getattr(defs, 'default_db_name', '') + self.password = password or getattr(defs, 'db_password', '') + + if ac_name: + self.user = self.get_db_login(ac_name) or defs.default_db_name + + if use_default: + self.user = defs.default_db_name + + self.is_testing = 0 + self.in_transaction = 0 + self.transaction_writes = 0 + self.testing_tables = [] + + self.connect() + if self.user != 'root': + self.use(self.user) + + if webnotes.logger: + webnotes.logger.debug('Database object initialized for:%s',self.user) + + def get_db_login(self, ac_name): + return getattr(defs,'db_name_map').get(ac_name, getattr(defs,'default_db_name')) + + def connect(self): + """ + Connect to a database + """ + self._conn = MySQLdb.connect(user=self.user, host=self.host, passwd=self.password) + try: + self._conn.set_character_set('utf8') + except: + pass + + self._cursor = self._conn.cursor() + + return self._cursor + + def use(self, db_name): + """ + `USE` db_name + """ + self._conn.select_db(db_name) + self.cur_db_name = db_name + + def check_transaction_status(self, query): + """ + Update *in_transaction* and check if "START TRANSACTION" is not called twice + """ + if self.in_transaction and query and query.strip().split()[0].lower() in ['start', 'alter', 'drop', 'create']: + raise Exception, 'This statement can cause implicit commit' + + if query and query.strip().lower()=='start transaction': + self.in_transaction = 1 + self.transaction_writes = 0 + + if query and query.strip().split()[0].lower() in ['commit', 'rollback']: + self.in_transaction = 0 + + if self.in_transaction and query[:6].lower() in ['update', 'insert']: + self.transaction_writes += 1 + if self.transaction_writes > 5000: + webnotes.msgprint('A very long query was encountered. If you are trying to import data, please do so using smaller files') + raise Exception, 'Bad Query!!! Too many writes' + + def fetch_as_dict(self, formatted=0): + """ + Internal - get results as dictionary + """ + result = self._cursor.fetchall() + ret = [] + for r in result: + dict = {} + for i in range(len(r)): + dict[self._cursor.description[i][0]] = self.convert_to_simple_type(r[i], formatted) + ret.append(dict) + return ret + + def validate_query(self, q): + cmd = q.strip().lower().split()[0] + if cmd in ['alter', 'drop', 'truncate'] and webnotes.user.name != 'Administrator': + webnotes.msgprint('Not allowed to execute query') + raise Execption + + # ====================================================================================== + + def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0, ignore_no_table = 1, debug=0): + """ + * Execute a `query`, with given `values` + * returns as a dictionary if as_dict = 1 + * returns as a list of lists (with cleaned up dates and decimals) if as_list = 1 + """ + # in transaction validations + self.check_transaction_status(query) + + if getattr(defs,'multi_tenant',None): + query = self.add_multi_tenant_condition(query) + + # execute + if values!=(): + self._cursor.execute(query, values) + if debug: webnotes.msgprint(query % values) + + else: + self._cursor.execute(query) + if debug: webnotes.msgprint(query) + + # scrub output if required + if as_dict: + return self.fetch_as_dict(formatted) + elif as_list: + return self.convert_to_lists(self._cursor.fetchall(), formatted) + else: + return self._cursor.fetchall() + + # add condition for tenant id + # ====================================================================================== + def add_multi_tenant_condition(query): + import webnotes.multi_tenant + return webnotes.multi_tenant.query_parser.add_condition(query) + + # ====================================================================================== + + def get_description(self): + """ + Get metadata of the last query + """ + return self._cursor.description + + # ====================================================================================== + + def convert_to_simple_type(self, v, formatted=0): + try: import decimal # for decimal Python 2.5 onwards + except: pass + import datetime + from webnotes.utils import formatdate, fmt_money + + # date + if type(v)==datetime.date: + v = str(v) + if formatted: + v = formatdate(v) + + # time + elif type(v)==datetime.timedelta: + h = int(v.seconds/60/60) + v = str(h) + ':' + str(v.seconds/60 - h*60) + if v[1]==':': + v='0'+v + + # datetime + elif type(v)==datetime.datetime: + v = str(v) + + # long + elif type(v)==long: + v=int(v) + + # decimal + try: + if type(v)==decimal.Decimal: + v=float(v) + except: pass + + # convert to strings... (if formatted) + if formatted: + if type(v)==float: + v=fmt_money(v) + if type(v)==int: + v=str(v) + + return v + + # ====================================================================================== + + def convert_to_lists(self, res, formatted=0): + """ + Convert the given result set to a list of lists (with cleaned up dates and decimals) + """ + nres = [] + for r in res: + nr = [] + for c in r: + nr.append(self.convert_to_simple_type(c, formatted)) + nres.append(nr) + return nres + + # ====================================================================================== + + def replace_tab_by_test(self, query): + """ + Relace all ``tab`` + doctype to ``test`` + doctype + """ + if self.is_testing: + tl = self.get_testing_tables() + for t in tl: + query = query.replace(t, 'test' + t[3:]) + return query + + def get_testing_tables(self): + """ + Get list of all tables for which `tab` is to be replaced by `test` before a query is executed + """ + if not self.testing_tables: + testing_tables = ['tab'+r[0] for r in self.sql('SELECT name from tabDocType where docstatus<2 and (issingle=0 or issingle is null)', allow_testing = 0)] + testing_tables+=['tabSeries','tabSingles'] # tabSessions is not included here + return self.testing_tables + + # ====================================================================================== + # get a single value from a record + + def get_value(self, doctype, docname, fieldname): + """ + Get a single / multiple value from a record. + + For Single DocType, let docname be = None + """ + + fl = fieldname + if docname and (docname!=doctype or docname=='DocType'): + if type(fieldname) in (list, tuple): + fl = '`, `'.join(fieldname) + + r = self.sql("select `%s` from `tab%s` where name='%s'" % (fl, doctype, docname)) + return r and (len(r[0]) > 1 and r[0] or r[0][0]) or None + else: + if type(fieldname) in (list, tuple): + fl = "', '".join(fieldname) + + r = self.sql("select value from tabSingles where field in ('%s') and doctype='%s'" % (fieldname, doctype)) + return r and (len(r) > 1 and (i[0] for i in r) or r[0][0]) or None + + def set_value(self, dt, dn, field, val): + if dn and dt!=dn: + self.sql("update `tab"+dt+"` set `"+field+"`=%s where name=%s", (val, dn)) + else: + if self.sql("select value from tabSingles where field=%s and doctype=%s", (field, dt)): + self.sql("update tabSingles set value=%s where field=%s and doctype=%s", (val, field, dt)) + else: + self.sql("insert into tabSingles(doctype, field, value) values (%s, %s, %s)", (dt, field, val)) + + def set(self, doc, field, val): + self.set_value(doc.doctype, doc.name, field, val) + doc.fields[field] = val + + # ====================================================================================== + + def set_global(self, key, val, user='__global'): + res = self.sql('select defkey from `tabDefaultValue` where defkey=%s and parent=%s', (key, user)) + if res: + self.sql('update `tabDefaultValue` set defvalue=%s where parent=%s and defkey=%s', (str(val), user, key)) + else: + self.sql('insert into `tabDefaultValue` (name, defkey, defvalue, parent) values (%s,%s,%s,%s)', (user+'_'+key, key, str(val), user)) + + def get_global(self, key, user='__global'): + g = self.sql("select defvalue from tabDefaultValue where defkey=%s and parent=%s", (key, user)) + return g and g[0][0] or None + + # ====================================================================================== + + def begin(self): + if not self.in_transaction: + self.sql("start transaction") + + def commit(self): + self.sql("commit") + + + def rollback(self): + self.sql("ROLLBACK") + + # ====================================================================================== + + def field_exists(self, dt, fn): + """ + Returns True if `fn` exists in `DocType` `dt` + """ + return self.sql("select name from tabDocField where fieldname=%s and parent=%s", (dt, fn)) + + def exists(self, dt, dn): + """ + Returns true if the record exists + """ + try: + return self.sql('select name from `tab%s` where name=%s' % (dt, '%s'), dn) + except: + return None + + # ====================================================================================== + def close(self): + """ + Close my connection + """ + if self._conn: + self._conn.close() diff --git a/cgi-bin/webnotes/defs_template.py b/cgi-bin/webnotes/defs_template.py new file mode 100644 index 0000000000..9bfa2c7234 --- /dev/null +++ b/cgi-bin/webnotes/defs_template.py @@ -0,0 +1,86 @@ +# This file contains all the major settings regarding +# You must setup this file before running the application +# There are also settings for multiple files +# You must save this file as "defs.py" to make it live +# ================================================================================= + +# +# [IMPORTANT] - Please set your default db_name +# +default_db_name = '' +db_password = 'some_password' + +# +# map of database names to account names +# if you are running multiple database instances, then you can set "account names" to each database +# account names can be same as db_names - it is only to mask database names for security reasons +# un-comment this if you want to use db_names +# +#db_name_map = {'accountname':'dbname'} + +# +# if you are running multiple applications on one server, then you can use this to map a domain name to an +# database name. comment this if you do not want to map domain names +# +#domain_name_map = {'example.com':'dbname'} + + +# +# Path to your MySQL command account, if not directly "mysql" +# +mysql_path = '' + +# +# Attachment Files Path: This is where attachments are stored. Attachments are not stored in the database +# as they can incease backup sizes. +# It is best to keep this folder outside your www folder so that it is not accessible directly +# +files_path = 'user_files' + +# +# Modules path: This is where the module files are stored +# If this is blank, your modules files will be saved in the 'cgi-bin' forder +# +modules_path = '' + +# +# Developer Mode: If the developer_mode is set, all updates to DocTypes, Pages and Search Criteria will be +# saved to the modules folder +# +developer_mode = 0 + +# +# Time Zone: Useful if your users are across timezones +# +user_timezone = 'Asia/Calcutta' + +# +# Default Mail Server Settings +# If mail server settings are not set in the Control Panel, they are picked from here +# +mail_server = None +mail_login = None +mail_password = None +mail_port = None +use_ssl = None + +# +# Email Batching Settings +# Batching of emails is a good idea because sending an email takes a longer time in the middle of a transaction +# and locks the table. If emails are batched, you need to setup cron to call +# webnotes.utils.email_lib.EmailQueue().flush() +# +batch_emails = 0 +# email_queue = 'email_queue.py' + +# +# Logging Settings: Log using the python logger +# Error levels (in string): 'login.DEBUG', 'login.INFO', 'login.WARNING', 'logging.ERROR', 'login.CRITICAL' +# +log_file_name = 'logs/error_log.txt' +debug_log_dbs = [] +log_level = 'logging.INFO' +log_file_size = 5000 +log_file_backup_count = 5 + + diff --git a/cgi-bin/webnotes/handler.py b/cgi-bin/webnotes/handler.py new file mode 100755 index 0000000000..933784ebad --- /dev/null +++ b/cgi-bin/webnotes/handler.py @@ -0,0 +1,437 @@ +import sys, os +import webnotes +import webnotes.defs +import webnotes.utils + +form = webnotes.form +form_dict = webnotes.form_dict + +sql = None +session = None +errdoc = '' +errdoctype = '' +errmethod = '' +fw_folder = '/Users/rushabh/workbench/www/' + + +# Logs + +# refresh / start page +# ------------------------------------------------------------------------------------ + +def startup(): + import webnotes + import webnotes.session_cache + + webnotes.response.update(webnotes.session_cache.get()) + +def cleanup_docs(): + import webnotes.model.doclist + if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict: + webnotes.response['docs'] = webnotes.model.doclist.compress(webnotes.response['docs']) + +# server calls +# ------------------------------------------------------------------------------------ + +def runserverobj(arg=None): + import webnotes.widgets.form + webnotes.widgets.form.runserverobj() + +def logout(): + webnotes.login_manager.logout() + +# DocType Mapper +# ------------------------------------------------------------------------------------ + +def dt_map(): + import webnotes + import webnotes.model.doclist + from webnotes.model.code import get_obj + from webnotes.model.doc import Document + + form_dict = webnotes.form_dict + + dt_list = webnotes.model.doclist.expand(form_dict.get('docs')) + from_doctype = form_dict.get('from_doctype') + to_doctype = form_dict.get('to_doctype') + from_docname = form_dict.get('from_docname') + from_to_list = form_dict.get('from_to_list') + + dm = get_obj('DocType Mapper', from_doctype +'-' + to_doctype) + doclist = dm.dt_map(from_doctype, to_doctype, from_docname, Document(fielddata = dt_list[0]), [], from_to_list) + + webnotes.response['docs'] = doclist + +# Load Month Events +# ------------------------------------------------------------------------------------ + +def load_month_events(): + import webnotes + form = webnotes.form + + mm = form.getvalue('month') + yy = form.getvalue('year') + m_st = str(yy) + '-' + str(mm) + '-01' + m_end = str(yy) + '-' + str(mm) + '-31' + + import webnotes.widgets.event + webnotes.response['docs'] = webnotes.widgets.event.get_cal_events(m_st, m_end) + +# Data import +# ------------------------------------------------------------------------------------ + +def import_csv(): + import webnotes.model.import_docs + form = webnotes.form + from webnotes.utils import cint + + i = webnotes.model.import_docs.CSVImport() + r = i.import_csv(form.getvalue('csv_file'), form.getvalue('dateformat'), form_dict.get('overwrite', 0) and 1) + + webnotes.response['type']='iframe' + rhead = '''''' + webnotes.response['result']= rhead + r + +def get_template(): + import webnotes.model.import_docs + webnotes.model.import_docs.get_template() + + +# File Upload +# ------------------------------------------------------------------------------------ + +def uploadfile(): + import webnotes.utils.file_manager + if webnotes.form_dict.get('from_form'): + webnotes.utils.file_manager.upload() + else: + # save the file + fid, fname = webnotes.utils.file_manager.save_uploaded() + + # do something with the uploaded file + if fid and webnotes.form_dict.get('server_obj'): + from webnotes.model.code import get_obj + getattr(get_obj(webnotes.form_dict.get('server_obj')), webnotes.form_dict.get('method'))(fid, fname) + + # return the upload + if fid: + webnotes.response['result'] = '' + +# File upload (from scripts) +# ------------------------------------------------------------------------------------ + +def upload_many(): + from webnotes.model.code import get_obj + + # pass it on to upload_many method in Control Panel + cp = get_obj('Control Panel') + cp.upload_many(webnotes.form) + + webnotes.response['result'] = """ + +%s +%s""" % (cp.upload_callback(webnotes.form), '\n----\n'.join(webnotes.message_log).replace("'", "\'"), '\n----\n'.join(webnotes.debug_log).replace("'", "\'").replace("\n","
")) + webnotes.response['type'] = 'iframe' + + +# File download +# ------------------------------------------------------------------------------------ +def get_file(): + import webnotes.utils.file_manager + + res = webnotes.utils.file_manager.get_file(form.getvalue('fname')) + if res: + webnotes.response['type'] = 'download' + webnotes.response['filename'] = res[0] + + if hasattr(res[1], 'tostring'): + webnotes.response['filecontent'] = res[1].tostring() + else: + webnotes.response['filecontent'] = res[1] + else: + webnotes.msgprint('[get_file] Unknown file name') + +# Get Graph +# ------------------------------------------------------------------------------------ +def get_graph(): + form = webnotes.form + + import StringIO + f = StringIO.StringIO() + + # call the object + obj = server.get_obj(form_dict.get('dt')) + plt = server.run_server_obj(obj, form_dict.get('method'), form_dict.get('arg')) + plt.savefig(f) + + # stream out + webnotes.response['type'] = 'download' + webnotes.response['filename'] = webnotes.user.get_random_password() + '.png' + webnotes.response['filecontent'] = f.getvalue() + +# Reset Password +# ------------------------------------------------------------------------------------ + +def reset_password(): + form_dict = webnotes.form_dict + + act = form_dict.get('account', '') + user = form_dict.get('user', '') + if act: + webnotes.conn.set_db(act) + + try: + p = webnotes.profile.Profile(user) + p.reset_password() + webnotes.msgprint("Password has been reset and sent to your email id.") + except Exception, e: + webnotes.msgprint(str(e)) + +# Resume session +# ------------------------------------------------------------------------------------ + +def resume_session(): + webnotes.response['message'] = webnotes.session_obj.resume() + +# ------------- +# Create Backup +# ------------- + +def backupdb(form_dict, session): + db_name = server.decrypt(form_dict.get('db_name')) + + server.backup_db(db_name) + + webnotes.response['type'] = 'download' + webnotes.response['filename'] = db_name+'.tar.gz' + webnotes.response['filecontent'] = open('../backups/' + db_name+'.tar.gz','rb').read() + +# --------------------------------------------------------------------- + +def validate_cmd(cmd): + # check if there is no direct possibility of malicious script injection + if cmd.startswith('webnotes.model.code'): + raise Exception, 'Cannot call any methods from webnotes.model.code directly from the handler' + + if cmd.startswith('webnotes.model.db_schema'): + raise Exception, 'Cannot call any methods from webnotes.model.db_schema directly from the handler' + + if cmd.startswith('webnotes.conn'): + raise Exception, 'Cannot call database connection method directly from the handler' + +# Execution Starts Here +# --------------------------------------------------------------------- + +import webnotes.auth +import webnotes.db + +# reset password +# --------------------------------------------------------------------- + +if form_dict.has_key('cmd') and (form_dict.get('cmd')=='reset_password'): + webnotes.conn = webnotes.db.Database(use_default = 1) + sql = webnotes.conn.sql + sql("START TRANSACTION") + try: + reset_password() + sql("COMMIT") + except Exception, e: + webnotes.errprint(str(e)) + sql("ROLLBACK") + +# pre-login access - for registration etc. +# --------------------------------------------------------------------- + +elif form_dict.has_key('cmd') and (form_dict.get('cmd')=='prelogin'): + webnotes.conn = webnotes.db.Database(use_default = 1) + sql = webnotes.conn.sql + webnotes.session = {'user':'Administrator'} + + import webnotes.model.code + + sql("START TRANSACTION") + try: + webnotes.response['message'] = webnotes.model.code.get_obj('Profile Control').prelogin(form_dict) or '' + sql("COMMIT") + except: + webnotes.errprint(webnotes.utils.getTraceback()) + sql("ROLLBACK") + +# main stuff +# --------------------------------------------------------------------- + +else: + + try: + webnotes.request = webnotes.auth.HTTPRequest() + + if form_dict.get('cmd') != 'login' and webnotes.conn: + sql = webnotes.conn.sql + + # NOTE: + # guest should only be allowed: + # getdoc (if Guest access) + # runserverobj (if Guest access) + + # get command cmd + cmd = form_dict.has_key('cmd') and form_dict.get('cmd') or '' + read_only = form_dict.has_key('_read_only') and form_dict.get('_read_only') or None + + validate_cmd(cmd) + + module = '' + if '.' in cmd: + module = '.'.join(cmd.split('.')[:-1]) + cmd = cmd.split('.')[-1] + + exec 'from %s import %s' % (module, cmd) in locals() + + + # execute + if locals().has_key(cmd): + if (not webnotes.conn.in_transaction) and (not read_only): + webnotes.conn.begin() + + if webnotes.form_dict.get('arg'): + # direct method call + ret = locals()[cmd](webnotes.form_dict.get('arg')) + else: + ret = locals()[cmd]() + + # returns with a message + if ret: + webnotes.response['message'] = ret + + # update session + webnotes.session_obj.update() + + if webnotes.conn.in_transaction: + webnotes.conn.commit() + else: + if cmd!='login': + webnotes.msgprint('No Method: %s' % cmd) + + except webnotes.ValidationError: + webnotes.conn.rollback() + except: + webnotes.errprint(webnotes.utils.getTraceback()) + webnotes.conn and webnotes.conn.rollback() + + +#### cleanup +#----------- + +if webnotes.conn: + webnotes.conn.close() + +#### go + +import string +import os + +acceptsGzip, out_buf, str_out = 0, None, None +try: + if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: + acceptsGzip = 1 # problem in win ? +except: + pass + +def compressBuf(buf): + import gzip, cStringIO + zbuf = cStringIO.StringIO() + zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) + zfile.write(buf) + zfile.close() + return zbuf.getvalue() + +# CSV +# ------------------------------------------------------------------- + +if webnotes.response.get('type')=='csv': + print "Content-Type: text/csv" + print "Content-Disposition: attachment; filename="+webnotes.response['doctype'].replace(' ', '_')+".csv" + print + print webnotes.response['result'] + +# IFRAME +# ------------------------------------------------------------------- + +elif webnotes.response.get('type')=='iframe': + print "Content-Type: text/html" + print + if webnotes.response.get('result'): + print webnotes.response['result'] + if webnotes.debug_log: + print '''''' % ('-------'.join(webnotes.debug_log).replace('"', '').replace('\n','')) + +# file +# ------------------------------------------------------------------- + +elif webnotes.response.get('type')=='download': + import mimetypes + print "Content-Type: %s" % (mimetypes.guess_type(webnotes.response['filename'])[0] or 'application/unknown') + print "Content-Disposition: filename="+webnotes.response['filename'].replace(' ', '_') + print + print webnotes.response['filecontent'] + +# JSON +# ------------------------------------------------------------------- + +else: + if webnotes.debug_log: + save_log = 1 + if webnotes.debug_log[0].startswith('[Validation Error]'): + save_log = 0 + + t = '\n----------------\n'.join(webnotes.debug_log) + if errdoctype: + t = t + '\nDocType: ' + errdoctype + if errdoc: + t = t + '\nName: ' + errdoc + if errmethod: + t = t + '\nMethod: ' + errmethod + webnotes.response['exc'] = '
'+t.replace('\n','
')+'
' + + if save_log: # don't save validation errors + try: save_log(t, 'Server') + except: pass + + if webnotes.message_log: + webnotes.response['server_messages'] = '\n----------------\n'.join(webnotes.message_log) + + cleanup_docs() + + # Convert to JSON + # --------------- + try: + import json + except: # python 2.4 + import simplejson as json + + try: + str_out = json.dumps(webnotes.response) + except: + str_out = str(webnotes.response).replace(', None', ', ""') + + if acceptsGzip and len(str_out)>512: + out_buf = compressBuf(str_out) + print "Content-Encoding: gzip" + print "Content-Length: %d" % (len(out_buf)) + + print "Content-Type: text/html; Charset: ISO-8859-1" + + # if there ar additional cookies defined during the request, add them here + if webnotes.cookies or webnotes.add_cookies: + for c in webnotes.add_cookies.keys(): + webnotes.cookies[c] = webnotes.add_cookies[c] + + print webnotes.cookies + + print # Headers end + +if out_buf: + sys.stdout.write(out_buf) +elif str_out: + print str_out diff --git a/cgi-bin/webnotes/install_lib/__init__.py b/cgi-bin/webnotes/install_lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/install_lib/db_init.py b/cgi-bin/webnotes/install_lib/db_init.py new file mode 100644 index 0000000000..ae76889c2f --- /dev/null +++ b/cgi-bin/webnotes/install_lib/db_init.py @@ -0,0 +1,284 @@ +""" + Create a database from scratch (wip) +""" + +class DatabaseInstance: + + def __init__(self, conn = None,db_name = None): + self.conn = conn + self.db_name = db_name + + +# def setup(self): +# self.create_db_and_user() +# self.create_base_tables() +# self.import_system_module() +# self.setup_users() + + def create_db_and_user(self): + import webnotes.defs + + # create user and db + self.conn.sql("CREATE USER '%s'@'localhost' IDENTIFIED BY '%s'" % (self.db_name, webnotes.defs.db_password)) + self.conn.sql("CREATE DATABASE IF NOT EXISTS `%s` ;" % self.db_name) + self.conn.sql("GRANT ALL PRIVILEGES ON `%s` . * TO '%s'@'localhost';" % (self.db_name, self.db_name)) + self.conn.sql("FLUSH PRIVILEGES") + self.conn.sql("SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;") + self.conn.sql("USE %s"%self.db_name) + + + + + + def create_base_tables(self): + self.create_singles() + self.create_sessions() + self.create_doctypecache() + self.create_role() + self.create_docfield() + self.create_docperm() + self.create_docformat() + self.create_doctype() + + def import_system_module(self): + docs = [ + ['DocType','Role'] + ,['Role','Administrator'] + ,['Role','Guest'] + ,['Role','All'] + ,['DocType','DocPerm'] + ,['DocType','DocFormat'] + ,['DocType','DocField'] + ,['DocType','DocType'] + ,['DocType','DefaultValue'] + ,['DocType','Profile'] + ,['DocType','UserRole'] + ] + + # import in sequence + for d in docs: + import_module.import_from_files(record_list=[['System',d[0],d[1]]]) + + # import all + import_module.import_from_files([['System']]) + + + # singles + # ------------------------------------------------------ + + def create_singles(self): + self.conn.sql("DROP TABLE IF EXISTS `tabSingles`") + self.conn.sql("""CREATE TABLE `tabSingles` ( + `doctype` varchar(40) default NULL, + `field` varchar(40) default NULL, + `value` text, + KEY `doctype` (`doctype`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # sessions + # ------------------------------------------------------ + + def create_sessions(self): + self.conn.sql("DROP TABLE IF EXISTS `tabSessions`;") + self.conn.sql("""CREATE TABLE `tabSessions` ( + `user` varchar(40) default NULL, + `sid` varchar(120) default NULL, + `sessiondata` longtext, + `ipaddress` varchar(16) default NULL, + `lastupdate` datetime default NULL + ) ENGINE=MyISAM DEFAULT CHARSET=latin1;""") + + # doc type cache + # ------------------------------------------------------ + + def create_doctypecache(self): + self.conn.sql("DROP TABLE IF EXISTS `__DocTypeCache`") + self.conn.sql("create table `__DocTypeCache` (name VARCHAR(120), modified DATETIME, content TEXT, server_code_compiled TEXT)") + + + + + # Role + # ------------------------------------------------------ + + def create_role(self): + self.conn.sql("DROP TABLE IF EXISTS `tabRole`") + self.conn.sql("""CREATE TABLE `tabRole` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `role_name` varchar(180) default NULL, + `module` varchar(180) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocField + # ------------------------------------------------------ + + def create_docfield(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocField`") + self.conn.sql("""CREATE TABLE `tabDocField` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `fieldname` varchar(180) default NULL, + `label` varchar(180) default NULL, + `oldfieldname` varchar(180) default NULL, + `fieldtype` varchar(180) default NULL, + `oldfieldtype` varchar(180) default NULL, + `options` text, + `search_index` int(3) default NULL, + `hidden` int(3) default NULL, + `print_hide` int(3) default NULL, + `report_hide` int(3) default NULL, + `reqd` int(3) default NULL, + `no_copy` int(3) default NULL, + `allow_on_submit` int(3) default NULL, + `trigger` varchar(180) default NULL, + `depends_on` varchar(180) default NULL, + `permlevel` int(3) default NULL, + `width` varchar(180) default NULL, + `default` text, + `description` text, + `colour` varchar(180) default NULL, + `icon` varchar(180) default NULL, + `in_filter` int(3) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`), + KEY `label` (`label`), + KEY `fieldtype` (`fieldtype`), + KEY `fieldname` (`fieldname`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocPerm + # ------------------------------------------------------ + + def create_docperm(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocPerm`") + self.conn.sql("""CREATE TABLE `tabDocPerm` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `permlevel` int(11) default NULL, + `role` varchar(180) default NULL, + `match` varchar(180) default NULL, + `read` int(3) default NULL, + `write` int(3) default NULL, + `create` int(3) default NULL, + `submit` int(3) default NULL, + `cancel` int(3) default NULL, + `amend` int(3) default NULL, + `execute` int(3) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocFormat + # ------------------------------------------------------ + + def create_docformat(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocFormat`") + self.conn.sql("""CREATE TABLE `tabDocFormat` ( + `name` varchar(120) NOT NULL, + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(40) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `format` varchar(180) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + # DocType + # ------------------------------------------------------ + + def create_doctype(self): + self.conn.sql("DROP TABLE IF EXISTS `tabDocType`") + self.conn.sql("""CREATE TABLE `tabDocType` ( + `name` varchar(180) NOT NULL default '', + `creation` datetime default NULL, + `modified` datetime default NULL, + `modified_by` varchar(40) default NULL, + `owner` varchar(180) default NULL, + `docstatus` int(1) default '0', + `parent` varchar(120) default NULL, + `parentfield` varchar(120) default NULL, + `parenttype` varchar(120) default NULL, + `idx` int(8) default NULL, + `search_fields` varchar(180) default NULL, + `issingle` int(1) default NULL, + `istable` int(1) default NULL, + `version` int(11) default NULL, + `module` varchar(180) default NULL, + `autoname` varchar(180) default NULL, + `name_case` varchar(180) default NULL, + `description` text, + `colour` varchar(180) default NULL, + `read_only` int(1) default NULL, + `in_create` int(1) default NULL, + `show_in_menu` int(3) default NULL, + `menu_index` int(11) default NULL, + `parent_node` varchar(180) default NULL, + `smallicon` varchar(180) default NULL, + `allow_print` int(1) default NULL, + `allow_email` int(1) default NULL, + `allow_copy` int(1) default NULL, + `allow_rename` int(1) default NULL, + `hide_toolbar` int(1) default NULL, + `hide_heading` int(1) default NULL, + `allow_attach` int(1) default NULL, + `use_template` int(1) default NULL, + `max_attachments` int(11) default NULL, + `section_style` varchar(180) default NULL, + `client_script` text, + `client_script_core` text, + `server_code` text, + `server_code_core` text, + `server_code_compiled` text, + `client_string` text, + `server_code_error` varchar(180) default NULL, + `print_outline` varchar(180) default NULL, + `dt_template` text, + `is_transaction_doc` int(1) default NULL, + `change_log` text, + `read_only_onload` int(1) default NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""") + + def create_module_def(self): + self.conn.sql("DROP TABLE IF EXISTS `tabModule Def`") + self.conn.sql("CREATE TABLE `tabModule Def` (`name` varchar(120) NOT NULL, `creation` datetime default NULL, `modified` datetime default NULL,`modified_by` varchar(40) default NULL,`owner` varchar(40) default NULL,`docstatus` int(1) default '0', `parent` varchar(120) default NULL,`parentfield` varchar(120) default NULL, `parenttype` varchar(120) default NULL, `idx` int(8) default NULL,`module_name` varchar(180) default NULL,`doctype_list` text, PRIMARY KEY (`name`), KEY `parent` (`parent`)) ENGINE=InnoDB") + + + def post_cleanup(self): + self.conn.sql("use %s;" % self.db_name) + self.conn.sql("update tabProfile set password = password('admin') where name='Administrator'") + self.conn.sql("update tabDocType set server_code_compiled = NULL") diff --git a/cgi-bin/webnotes/install_lib/install.py b/cgi-bin/webnotes/install_lib/install.py new file mode 100755 index 0000000000..5612f36ce2 --- /dev/null +++ b/cgi-bin/webnotes/install_lib/install.py @@ -0,0 +1,232 @@ +import os,sys + +cgi_bin_path = os.path.sep.join(__file__.split(os.path.sep)[:-3]) + +sys.path.append(cgi_bin_path) + + + +# +# make a copy of defs.py (if not exists) +# +def copy_defs(): + global cgi_bin_path + if not os.path.exists(os.path.join(cgi_bin_path, 'webnotes', 'defs.py')): + ret = os.system('cp '+ os.path.join(cgi_bin_path, 'webnotes', 'defs_template.py')+\ + ' '+os.path.join(cgi_bin_path, 'webnotes', 'defs.py')) + print 'Made copy of defs.py' + +# +# Main Installer Class +# +class Installer: + def __init__(self, root_login, root_password): + + self.root_password = root_password + from webnotes.model.db_schema import DbManager + + self.conn = webnotes.db.Database(user=root_login, password=root_password) + webnotes.conn=self.conn + webnotes.session= {'user':'Administrator'} + self.dbman = DbManager(self.conn) + self.mysql_path = hasattr(defs, 'mysql_path') and webnotes.defs.mysql_path or '' + + # + # run framework related cleanups + # + def framework_cleanups(self, target): + self.dbman.drop_table('__DocTypeCache') + webnotes.conn.sql("create table `__DocTypeCache` (name VARCHAR(120), modified DATETIME, content TEXT, server_code_compiled TEXT)") + + # set the basic passwords + webnotes.conn.begin() + webnotes.conn.sql("update tabProfile set password = password('admin') where name='Administrator'") + webnotes.conn.commit() + + def import_core_module(self): + """ + Imports the "Core" module from .txt file and creates + Creates profile Administrator + """ + from webnotes.modules.import_module import import_module + from webnotes.modules.module_manager import reload_doc + + reload_doc('core','doctype','doctype') + reload_doc('core','doctype','docfield') + reload_doc('core','doctype','docperm') + + import_module('core') + + webnotes.conn.begin() + + from webnotes.model.doc import Document + p = Document('Profile') + p.name = p.first_name = 'Administrator' + p.email = 'admin@localhost' + p.save(new = 1) + + ur = Document('UserRole') + ur.parent = 'Administrator' + ur.role = 'Administrator' + ur.parenttype = 'Profile' + ur.parentfield = 'userroles' + p.enabled = 1 + ur.save(1) + + p = Document('Profile') + p.name = p.first_name = 'Guest' + p.email = 'guest@localhost' + p.enabled = 1 + p.save(new = 1) + + ur = Document('UserRole') + ur.parent = 'Guest' + ur.role = 'Guest' + ur.parenttype = 'Profile' + ur.parentfield = 'userroles' + ur.save(1) + + webnotes.conn.commit() + + # + # main script to create a database from + # + def import_from_db(self, target, source_path='', password = 'admin', verbose=0): + """ + a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes. + """ + + # get the path of the sql file to import + if not source_path: + source_path = os.path.join(os.path.sep.join(os.path.abspath(webnotes.__file__).split(os.path.sep)[:-3]), 'data', 'Framework.sql') + + # delete user (if exists) + self.dbman.delete_user(target) + + # create user and db + self.dbman.create_user(target,getattr(defs,'db_password',None)) + if verbose: print "Created user %s" % target + + # create a database + self.dbman.create_database(target) + if verbose: print "Created database %s" % target + + # grant privileges to user + self.dbman.grant_all_privileges(target,target) + if verbose: print "Granted privileges to user %s and database %s" % (target, target) + + # flush user privileges + self.dbman.flush_privileges() + + self.conn.use(target) + + # import in target + if verbose: print "Starting database import..." + self.dbman.restore_database(target, source_path, self.root_password) + if verbose: print "Imported from database %s" % source_path + + self.import_core_module() + + # framework cleanups + self.framework_cleanups(target) + if verbose: print "Ran framework startups on %s" % target + + return target + +def make_scheduler(root_login, root_password, verbose): + """ + Make the database where all scheduler events will be stored from multiple datbases + See webnotes.utils.scheduler for more information + """ + conn = webnotes.db.Database(user=root_login, password=root_password) + + from webnotes.model.db_schema import DbManager + + dbman = DbManager(conn) + + # delete user (if exists) + dbman.delete_user('master_scheduler') + + # create user and db + dbman.create_user('master_scheduler', getattr(defs,'db_password',None)) + if verbose: print "Created user master_scheduler" + + # create a database + dbman.create_database('master_scheduler') + if verbose: print "Created database master_scheduler" + + # grant privileges to user + dbman.grant_all_privileges('master_scheduler','master_scheduler') + + # flush user privileges + dbman.flush_privileges() + + conn.use('master_scheduler') + + # create events table + conn.sql("""create table Event( + `db_name` varchar(60), + `event` varchar(180), + `interval` int(20), + `next_execution` timestamp, + `recurring` int(1), + primary key (`db_name`, `event`), + index next_execution(next_execution) + )""") + + conn.sql("""create table EventLog( + `db_name` varchar(180), + `event` varchar(180), + `executed_on` timestamp, + `log` text, + index executed_on(executed_on)) + """) +# +# load the options +# +def get_parser(): + from optparse import OptionParser + + parser = OptionParser(usage="usage: %prog [options] ROOT_LOGIN ROOT_PASSWORD DBNAME") + parser.add_option("-x", "--database-password", dest="password", default="admin", help="Optional: New password for the Framework Administrator, default 'admin'") + parser.add_option("-s", "--source", dest="source_path", default=None, help="Optional: Path of the sql file from which you want to import the instance, default 'data/Framework.sql'") + + return parser + + +# +# execution here +# +if __name__=='__main__': + + parser = get_parser() + (options, args) = parser.parse_args() + + try: + + from webnotes import defs + import webnotes + import webnotes.db + except ImportError: + copy_defs() + from webnotes import defs + import webnotes + import webnotes.db + + if len(args)==3: + + root_login, root_password, db_name = args[0], args[1], args[2] + + if db_name=='master_scheduler': + make_scheduler(root_login, root_password, 1) + else: + inst = Installer(root_login, root_password) + + inst.import_from_db(db_name, source_path=options.source_path, \ + password = options.password, verbose = 1) + + + print "Database created, please edit defs.py to get started" + else: + parser.print_help() + diff --git a/cgi-bin/webnotes/model/__init__.py b/cgi-bin/webnotes/model/__init__.py new file mode 100644 index 0000000000..8a95daf0e9 --- /dev/null +++ b/cgi-bin/webnotes/model/__init__.py @@ -0,0 +1,205 @@ +# model __init__.py +import webnotes + +no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image', 'Graph'] +default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus'] + +#================================================================================= + +def check_if_doc_is_linked(dt, dn): + """ + Raises excption if the given doc(dt, dn) is linked in another record. + """ + sql = webnotes.conn.sql + + ll = get_link_fields(dt) + for l in ll: + link_dt, link_field = l + issingle = sql("select issingle from tabDocType where name = '%s'" % link_dt) + + # no such doctype (?) + if not issingle: continue + + if issingle[0][0]: + item = sql("select doctype from `tabSingles` where field='%s' and value = '%s' and doctype = '%s' " % (link_field, dn, l[0])) + if item: + webnotes.msgprint("Cannot delete %s %s because it is linked in %s" % (dt, dn, item[0][0]), raise_exception=1) + + else: + item = sql("select name from `tab%s` where `%s`='%s' and docstatus!=2 limit 1" % (link_dt, link_field, dn)) + if item: + webnotes.msgprint("Cannot delete %s %s because it is linked in %s %s" % (dt, dn, link_dt, item[0][0]), raise_exception=1) + + +def delete_doc(doctype=None, name=None, doclist = None): + """ + Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record + """ + import webnotes.model.meta + sql = webnotes.conn.sql + + if not doctype: + doctype = webnotes.form_dict.get('dt') + name = webnotes.form_dict.get('dn') + if not doctype: + webnotes.msgprint('Nothing to delete!', raise_exception =1) + + tablefields = webnotes.model.meta.get_table_fields(doctype) + + # check if submitted + d = webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doctype, '%s'), name) + if d and int(d[0][0]) == 1: + webnotes.msgprint("Submitted Record '%s' '%s' cannot be deleted" % (doctype, name)) + raise Exception + + # call on_trash if required + from webnotes.model.code import get_obj + if doclist: + obj = get_obj(doclist=doclist) + else: + obj = get_obj(doctype, name) + + if hasattr(obj,'on_trash'): + obj.on_trash() + + # check if links exist + check_if_doc_is_linked(doctype, name) + + try: + webnotes.conn.sql("delete from `tab%s` where name='%s' limit 1" % (doctype, name)) + for t in tablefields: + webnotes.conn.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), name) + except Exception, e: + if e.args[0]==1451: + webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) + + raise e + + return 'okay' + +#================================================================================= +# new feature added 9-Jun-10 to allow doctypes to have labels +def get_dt_labels(): + d = {} + try: + res = webnotes.conn.sql("select name, dt_label from `tabDocType Label`") + except: + return {} + + for r in res: + d[r[0]] = r[1] + + return d +#================================================================================= + +def get_search_criteria(dt): + import webnotes.model.doc + # load search criteria for reports (all) + dl = [] + try: # bc + sc_list = webnotes.conn.sql("select name from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s' and (disabled!=1 OR disabled IS NULL)" % (dt, dt)) + for sc in sc_list: + dl += webnotes.model.doc.get('Search Criteria', sc[0]) + except Exception, e: + pass # no search criteria + return dl + + +# Rename Doc +#================================================================================= + +def get_link_fields(dt): + """ + Returns linked fields for dt as a tuple of (linked_doctype, linked_field) + """ + return webnotes.conn.sql("select parent, fieldname from tabDocField where parent not like 'old%%' and ((options = '%s' and fieldtype='Link') or (options = 'link:%s' and fieldtype='Select'))" % (dt, dt)) + +def rename(dt, old, new, is_doctype = 0): + """ + Renames a doc(dt, old) to doc(dt, new) and updates all linked fields of type "Link" or "Select" with "link:" + """ + sql = webnotes.conn.sql + + # rename doc + sql("update `tab%s` set name='%s' where name='%s'" % (dt, new, old)) + + # get child docs + ct = sql("select options from tabDocField where parent = '%s' and fieldtype='Table'" % dt) + for c in ct: + sql("update `tab%s` set parent='%s' where parent='%s'" % (c[0], new, old)) + + # get links (link / select) + ll = get_link_fields(dt) + for l in ll: + is_single = sql("select issingle from tabDocType where name = '%s'" % l[0]) + is_single = is_single and webnotes.utils.cint(is_single[0][0]) or 0 + if is_single: + sql("update `tabSingles` set value='%s' where field='%s' and value = '%s' and doctype = '%s' " % (new, l[1], old, l[0])) + else: + sql("update `tab%s` set `%s`='%s' where `%s`='%s'" % (l[0], l[1], new, l[1], old)) + + # doctype + if is_doctype: + sql("RENAME TABLE `tab%s` TO `tab%s`" % (old, new)) + + # get child docs (update parenttype) + ct = sql("select options from tabDocField where parent = '%s' and fieldtype='Table'" % new) + for c in ct: + sql("update `tab%s` set parenttype='%s' where parenttype='%s'" % (c[0], new, old)) + +#================================================================================= + +def clear_recycle_bin(): + """ + Clears temporary records that have been deleted + """ + sql = webnotes.conn.sql + + tl = sql('show tables') + total_deleted = 0 + for t in tl: + fl = [i[0] for i in sql('desc `%s`' % t[0])] + + if 'name' in fl: + total_deleted += sql("select count(*) from `%s` where name like '__overwritten:%%'" % t[0])[0][0] + sql("delete from `%s` where name like '__overwritten:%%'" % t[0]) + + if 'parent' in fl: + total_deleted += sql("select count(*) from `%s` where parent like '__oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like '__oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'old_parent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'old_parent:%%'" % t[0]) + + webnotes.msgprint("%s records deleted" % str(int(total_deleted))) + + +# Make Table Copy +#================================================================================= + +def copytables(srctype, src, srcfield, tartype, tar, tarfield, srcfields, tarfields=[]): + import webnotes.model.doc + + if not tarfields: + tarfields = srcfields + l = [] + data = webnotes.model.doc.getchildren(src.name, srctype, srcfield) + for d in data: + newrow = webnotes.model.doc.addchild(tar, tarfield, tartype, local = 1) + newrow.idx = d.idx + + for i in range(len(srcfields)): + newrow.fields[tarfields[i]] = d.fields[srcfields[i]] + + l.append(newrow) + return l + +# DB Exists +#================================================================================= + +def db_exists(dt, dn): + import webnotes + return webnotes.conn.exists(dt, dn) diff --git a/cgi-bin/webnotes/model/code.py b/cgi-bin/webnotes/model/code.py new file mode 100644 index 0000000000..dcebc823b9 --- /dev/null +++ b/cgi-bin/webnotes/model/code.py @@ -0,0 +1,223 @@ +""" +This is where all the plug-in code is executed. The standard method for DocTypes is declaration of a +standardized `DocType` class that has the methods of any DocType. When an object is instantiated using the +`get_obj` method, it creates an instance of the `DocType` class of that particular DocType and sets the +`doc` and `doclist` attributes that represent the fields (properties) of that record. + +methods in following modules are imported for backward compatibility + + * webnotes.* + * webnotes.utils.* + * webnotes.model.doc.* + * webnotes.model.doclist.* +""" +custom_class = ''' +# Please edit this list and import only required elements +import webnotes + +from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add +from webnotes.model import db_exists +from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType +from webnotes.model.doclist import getlist, copy_doclist +from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax +from webnotes import session, form, is_testing, msgprint, errprint + +set = webnotes.conn.set +sql = webnotes.conn.sql +get_value = webnotes.conn.get_value +in_transaction = webnotes.conn.in_transaction +convert_to_lists = webnotes.conn.convert_to_lists + +# ----------------------------------------------------------------------------------------- + +class CustomDocType(DocType): + def __init__(self, doc, doclist): + DocType.__init__(self, doc, doclist) +''' + + +#================================================================================= +# execute a script with a lot of globals - deprecated +#================================================================================= + +def execute(code, doc=None, doclist=[]): + """ + Execute the code, if doc is given, then return the instance of the `DocType` class created + """ + # functions used in server script of DocTypes + # -------------------------------------------------- + from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add + from webnotes.model import db_exists + from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType + from webnotes.model.doclist import getlist, copy_doclist + from webnotes import session, form, is_testing, msgprint, errprint + + import webnotes + + set = webnotes.conn.set + sql = webnotes.conn.sql + get_value = webnotes.conn.get_value + in_transaction = webnotes.conn.in_transaction + convert_to_lists = webnotes.conn.convert_to_lists + if webnotes.user: + get_roles = webnotes.user.get_roles + locals().update({'get_obj':get_obj, 'get_server_obj':get_server_obj, 'run_server_obj':run_server_obj, 'updatedb':updatedb, 'check_syntax':check_syntax}) + version = 'v170' + NEWLINE = '\n' + BACKSLASH = '\\' + + # execute it + # ----------------- + exec code in locals() + + # if doc + # ----------------- + if doc: + d = DocType(doc, doclist) + return d + + if locals().get('page_html'): + return page_html + + if locals().get('out'): + return out + +#================================================================================= +# load the DocType class from module & return an instance +#================================================================================= + +def get_custom_script(doctype, script_type): + """ + Returns custom script if set in doctype `Custom Script` + """ + import webnotes + try: + custom_script = webnotes.conn.sql("select script from `tabCustom Script` where dt=%s and script_type=%s", (doctype, script_type)) + except Exception, e: + if e.args[0]==1146: + return None + else: raise e + + if custom_script and custom_script[0][0]: + return custom_script[0][0] + +def get_server_obj(doc, doclist = [], basedoctype = ''): + """ + Returns the instantiated `DocType` object. Will also manage caching & compiling + """ + # for test + import webnotes + + + # get doctype details + module = webnotes.conn.get_value('DocType', doc.doctype, 'module') + + # no module specified (must be really old), can't get code so quit + if not module: + return + + module = module.replace(' ','_').lower() + dt = doc.doctype.replace(' ','_').lower() + + # import + try: + exec 'from %s.doctype.%s.%s import DocType' % (module, dt, dt) + except ImportError, e: + # declare it here + class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + + # custom? + custom_script = get_custom_script(doc.doctype, 'Server') + if custom_script: + global custom_class + + exec custom_class + custom_script.replace('\t',' ') in locals() + + return CustomDocType(doc, doclist) + else: + return DocType(doc, doclist) + +#================================================================================= +# get object (from dt and/or dn or doclist) +#================================================================================= + +def get_obj(dt = None, dn = None, doc=None, doclist=[], with_children = 0): + """ + Returns the instantiated `DocType` object. Here you can pass the DocType and name (ID) to get the object. + If with_children is true, then all child records will be laoded and added in the doclist. + """ + if dt: + import webnotes.model.doc + + if not dn: + dn = dt + if with_children: + doclist = webnotes.model.doc.get(dt, dn, from_get_obj=1) + else: + doclist = webnotes.model.doc.get(dt, dn, with_children = 0, from_get_obj=1) + return get_server_obj(doclist[0], doclist) + else: + return get_server_obj(doc, doclist) + +#================================================================================= +# get object and run method +#================================================================================= + +def run_server_obj(server_obj, method_name, arg=None): + """ + Executes a method (`method_name`) from the given object (`server_obj`) + """ + if server_obj and hasattr(server_obj, method_name): + if arg: + return getattr(server_obj, method_name)(arg) + else: + return getattr(server_obj, method_name)() + else: + raise Exception, 'No method %s' % method_name + +#================================================================================= +# deprecated methods to keep v160 apps happy +#================================================================================= + +def updatedb(doctype, userfields = [], args = {}): + pass + +def check_syntax(code): + return '' + +#=================================================================================== +def get_code(module, dt, dn, extn, is_static=None, fieldname=None): + from webnotes.modules import scrub, get_module_path + import os, webnotes + + # get module (if required) + if not module: + module = webnotes.conn.sql("select module from `tab%s` where name=%s" % (dt,'%s'),dn)[0][0] + + # no module, quit + if not module: + return '' + + # file names + if scrub(dt) in ('page','doctype','search_criteria'): + dt, dn = scrub(dt), scrub(dn) + + # get file name + fname = dn + '.' + extn + if is_static: + fname = dn + '_static.' + extn + + # code + code = '' + try: + file = open(os.path.join(get_module_path(scrub(module)), dt, dn, fname), 'r') + code = file.read() + file.close() + except IOError, e: + # no file, try from db + if fieldname: + code = webnotes.conn.get_value(dt, dn, fieldname) + + return code diff --git a/cgi-bin/webnotes/model/db_schema.py b/cgi-bin/webnotes/model/db_schema.py new file mode 100644 index 0000000000..7b97a0cab2 --- /dev/null +++ b/cgi-bin/webnotes/model/db_schema.py @@ -0,0 +1,430 @@ +""" +Syncs a database table to the `DocType` (metadata) + +.. note:: This module is only used internally + +""" +import os +import webnotes + +type_map = { + 'currency': ('decimal', '14,2') + ,'int': ('int', '11') + ,'float': ('decimal', '14,6') + ,'check': ('int', '1') + ,'small text': ('text', '') + ,'long text': ('text', '') + ,'code': ('text', '') + ,'text editor': ('text', '') + ,'date': ('date', '') + ,'time': ('time', '') + ,'text': ('text', '') + ,'data': ('varchar', '180') + ,'link': ('varchar', '180') + ,'password': ('varchar', '180') + ,'select': ('varchar', '180') + ,'read only': ('varchar', '180') + ,'blob': ('longblob', '') +} + +default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner', 'docstatus', 'parent',\ + 'parentfield', 'parenttype', 'idx'] + +default_shortcuts = ['_Login', '__user', '_Full Name', 'Today', '__today'] + + +from webnotes.utils import cint + +# ------------------------------------------------- +# Class database table +# ------------------------------------------------- + +class DbTable: + def __init__(self, doctype, prefix = 'tab'): + self.doctype = doctype + self.name = prefix + doctype + self.columns = {} + self.current_columns = {} + + # lists for change + self.add_column = [] + self.change_type = [] + self.add_index = [] + self.drop_index = [] + self.set_default = [] + + # load + self.get_columns_from_docfields() + + def create(self): + add_text = '' + + # columns + t = self.get_column_definitions() + if t: add_text += ',\n'.join(self.get_column_definitions()) + ',\n' + + # index + t = self.get_index_definitions() + if t: add_text += ',\n'.join(self.get_index_definitions()) + ',\n' + + # create table + webnotes.conn.sql("""create table `%s` ( + name varchar(120) not null primary key, + creation datetime, + modified datetime, + modified_by varchar(40), + owner varchar(40), + docstatus int(1) default '0', + parent varchar(120), + parentfield varchar(120), + parenttype varchar(120), + idx int(8), + %sindex parent(parent)) ENGINE=InnoDB""" % (self.name, add_text)) + + def get_columns_from_docfields(self): + fl = webnotes.conn.sql("SELECT * FROM tabDocField WHERE parent = '%s'" % self.doctype, as_dict = 1) + + for f in fl: + if not f.get('no_column'): + self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], f['fieldtype'], f.get('length'), f['default'], f['search_index'], f['options']) + + def get_columns_from_db(self): + self.show_columns = webnotes.conn.sql("desc `%s`" % self.name) + for c in self.show_columns: + self.current_columns[c[0]] = {'name': c[0], 'type':c[1], 'index':c[3], 'default':c[4]} + + def get_column_definitions(self): + column_list = [] + default_columns + ret = [] + for k in self.columns.keys(): + if k not in column_list: + d = self.columns[k].get_definition() + if d: + ret.append('`'+ k+ '` ' + d) + column_list.append(k) + return ret + + def get_index_definitions(self): + ret = [] + for k in self.columns.keys(): + if type_map.get(self.columns[k].fieldtype) and type_map.get(self.columns[k].fieldtype.lower())[0] not in ('text', 'blob'): + ret.append('index `' + k + '`(`' + k + '`)') + return ret + + + # GET foreign keys + def get_foreign_keys(self): + fk_list = [] + txt = webnotes.conn.sql("show create table `%s`" % self.name)[0][1] + for line in txt.split('\n'): + if line.strip().startswith('CONSTRAINT') and line.find('FOREIGN')!=-1: + try: + fk_list.append((line.split('`')[3], line.split('`')[1])) + except IndexError, e: + pass + + return fk_list + + # Drop foreign keys + def drop_foreign_keys(self): + if not self.drop_foreign_key: + return + + fk_list = self.get_foreign_keys() + + # make dictionary of constraint names + fk_dict = {} + for f in fk_list: + fk_dict[f[0]] = f[1] + + # drop + for col in self.drop_foreign_key: + webnotes.conn.sql("set foreign_key_checks=0") + webnotes.conn.sql("alter table `%s` drop foreign key `%s`" % (self.name, fk_dict[col.fieldname])) + webnotes.conn.sql("set foreign_key_checks=1") + + def sync(self): + if not self.name in DbManager(webnotes.conn).get_tables_list(webnotes.conn.cur_db_name): + self.create() + else: + self.alter() + + def alter(self): + self.get_columns_from_db() + for col in self.columns.values(): + col.check(self.current_columns.get(col.fieldname, None)) + + for col in self.add_column: + webnotes.conn.sql("alter table `%s` add column `%s` %s" % (self.name, col.fieldname, col.get_definition())) + + for col in self.change_type: + webnotes.conn.sql("alter table `%s` change `%s` `%s` %s" % (self.name, col.fieldname, col.fieldname, col.get_definition())) + + for col in self.add_index: + webnotes.conn.sql("alter table `%s` add index `%s`(`%s`)" % (self.name, col.fieldname, col.fieldname)) + + for col in self.drop_index: + if col.fieldname != 'name': # primary key + webnotes.conn.sql("alter table `%s` drop index `%s`" % (self.name, col.fieldname)) + + + for col in self.set_default: + webnotes.conn.sql("alter table `%s` alter column `%s` set default %s" % (self.name, col.fieldname, '%s'), col.default) + + +# ------------------------------------------------- +# Class database column +# ------------------------------------------------- + +class DbColumn: + def __init__(self, table, fieldname, fieldtype, length, default, set_index, options): + self.table = table + self.fieldname = fieldname + self.fieldtype = fieldtype + self.length = length + self.set_index = set_index + self.default = default + self.options = options + + def get_definition(self, with_default=1): + d = type_map.get(self.fieldtype.lower()) + + if not d: + return + + ret = d[0] + if d[1]: + ret += '(' + d[1] + ')' + if with_default and self.default and (self.default not in default_shortcuts): + ret += ' default "' + self.default.replace('"', '\"') + '"' + return ret + + def check(self, current_def): + column_def = self.get_definition(0) + + # no columns + if not column_def: + return + + # to add? + if not current_def: + self.fieldname = validate_column_name(self.fieldname) + self.table.add_column.append(self) + return + + # type + if current_def['type'] != column_def: + self.table.change_type.append(self) + + # index + else: + if (current_def['index'] and not self.set_index): + self.table.drop_index.append(self) + + if (not current_def['index'] and self.set_index and not (column_def in ['text','blob'])): + self.table.add_index.append(self) + + # default + if (self.default and (current_def['default'] != self.default) and (self.default not in default_shortcuts) and not (column_def in ['text','blob'])): + self.table.set_default.append(self) + + +class DbManager: + """ + Basically, a wrapper for oft-used mysql commands. like show tables,databases, variables etc... + + #TODO: + 0. Simplify / create settings for the restore database source folder + 0a. Merge restore database and extract_sql(from webnotes_server_tools). + 1. Setter and getter for different mysql variables. + 2. Setter and getter for mysql variables at global level?? + """ + def __init__(self,conn): + """ + Pass root_conn here for access to all databases. + """ + if conn: + self.conn = conn + + + def get_variables(self,regex): + """ + Get variables that match the passed pattern regex + """ + return list(self.conn.sql("SHOW VARIABLES LIKE '%s'"%regex)) + + + def drop_all_databases(self): + """ + Danger: will delete all databases except test,mysql. + """ + db_list = self.get_database_list() + for db in db_list: + self.drop_database(db) + + def get_table_schema(self,table): + """ + Just returns the output of Desc tables. + """ + return list(self.conn.sql("DESC %s"%table)) + + + def get_tables_list(self,target): + """ + + """ + try: + self.conn.use(target) + res = self.conn.sql("SHOW TABLES;") + table_list = [] + for table in res: + table_list.append(table[0]) + return table_list + + except Exception,e: + raise e + + def create_user(self,user,password): + #Create user if it doesn't exist. + try: + if password: + self.conn.sql("CREATE USER '%s'@'localhost' IDENTIFIED BY '%s';" % (user[:16], password)) + else: + self.conn.sql("CREATE USER '%s'@'localhost';"%user[:16]) + except Exception, e: + raise e + + + def delete_user(self,target): + # delete user if exists + try: + self.conn.sql("DROP USER '%s'@'localhost';" % target) + except Exception, e: + if e.args[0]==1396: + pass + else: + raise e + + def create_database(self,target): + + try: + self.conn.sql("CREATE DATABASE IF NOT EXISTS `%s` ;" % target) + except Exception,e: + raise e + + + def drop_database(self,target): + try: + self.conn.sql("DROP DATABASE IF EXISTS `%s`;"%target) + except Exception,e: + raise e + + def grant_all_privileges(self,target,user): + try: + self.conn.sql("GRANT ALL PRIVILEGES ON `%s` . * TO '%s'@'localhost';" % (target, user)) + except Exception,e: + raise e + + def grant_select_privilges(self,db,table,user): + try: + if table: + self.conn.sql("GRANT SELECT ON %s.%s to '%s'@'localhost';" % (db,table,user)) + else: + self.conn.sql("GRANT SELECT ON %s.* to '%s'@'localhost';" % (db,user)) + except Exception,e: + raise e + + def flush_privileges(self): + try: + self.conn.sql("FLUSH PRIVILEGES") + except Exception,e: + raise e + + + def get_database_list(self): + try: + db_list = [] + ret_db_list = self.conn.sql("SHOW DATABASES") + for db in ret_db_list: + if db[0] not in ['information_schema', 'mysql', 'test', 'accounts']: + db_list.append(db[0]) + return db_list + except Exception,e: + raise e + + def restore_database(self,target,source,root_password): + import webnotes.defs + mysql_path = getattr(webnotes.defs, 'mysql_path', None) + mysql = mysql_path and os.path.join(mysql_path, 'mysql') or 'mysql' + + try: + ret = os.system("%s -u root -p%s %s < %s"%(mysql, root_password, target, source)) + except Exception,e: + raise e + + def drop_table(self,table_name): + try: + self.conn.sql("DROP TABLE IF EXISTS %s "%(table_name)) + except Exception,e: + raise e + + def set_transaction_isolation_level(self,scope='SESSION',level='READ COMMITTED'): + #Sets the transaction isolation level. scope = global/session + try: + self.conn.sql("SET %s TRANSACTION ISOLATION LEVEL %s"%(scope,level)) + except Exception,e: + raise e + + + +# ------------------------------------------------- +# validate column name to be code-friendly +# ------------------------------------------------- + +def validate_column_name(n): + n = n.replace(' ','_').strip().lower() + import re + if not re.match("[a-zA-Z_][a-zA-Z0-9_]*$", n): + webnotes.msgprint('err:%s is not a valid fieldname.
A valid name must contain letters / numbers / spaces.
Tip: You can change the Label after the fieldname has been set' % n) + raise Exception + return n + +# ------------------------------------------------- +# sync table - called from form.py +# ------------------------------------------------- + +def updatedb(dt, archive=0): + """ + Syncs a `DocType` to the table + * creates if required + * updates columns + * updates indices + """ + res = webnotes.conn.sql("select ifnull(issingle, 0) from tabDocType where name=%s", dt) + if not res: + raise Exception, 'Wrong doctype "%s" in updatedb' % dt + + if not res[0][0]: + webnotes.conn.commit() + tab = DbTable(dt, archive and 'arc' or 'tab') + tab.sync() + webnotes.conn.begin() + +# patch to remove foreign keys +# ---------------------------- + +def remove_all_foreign_keys(): + webnotes.conn.sql("set foreign_key_checks = 0") + webnotes.conn.commit() + for t in webnotes.conn.sql("select name from tabDocType where ifnull(issingle,0)=0"): + dbtab = webnotes.model.db_schema.DbTable(t[0]) + try: + fklist = dbtab.get_foreign_keys() + except Exception, e: + if e.args[0]==1146: + fklist = [] + else: + raise e + + for f in fklist: + webnotes.conn.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) diff --git a/cgi-bin/webnotes/model/doc.py b/cgi-bin/webnotes/model/doc.py new file mode 100644 index 0000000000..f6dc31bbca --- /dev/null +++ b/cgi-bin/webnotes/model/doc.py @@ -0,0 +1,671 @@ +""" +Contains the Document class representing an object / record +""" + +import webnotes +import webnotes.model.meta + +from webnotes.utils import * + +# actually should be "BaseDocType" - deprecated. Only for v160 +class SuperDocType: + def __init__(self): + pass + + def __getattr__(self, name): + if self.__dict__.has_key(name): + return self.__dict__[name] + elif self.super and hasattr(self.super, name): + return getattr(self.super, name) + else: + raise AttributeError, 'BaseDocType Attribute Error' + +class Document: + """ + The wn(meta-data)framework equivalent of a Database Record. + Stores,Retrieves,Updates the record in the corresponding table. + Runs the triggers required. + + The `Document` class represents the basic Object-Relational Mapper (ORM). The object type is defined by + `DocType` and the object ID is represented by `name`:: + + Please note the anamoly in the Web Notes Framework that `ID` is always called as `name` + + If both `doctype` and `name` are specified in the constructor, then the object is loaded from the database. + If only `doctype` is given, then the object is not loaded + If `fielddata` is specfied, then the object is created from the given dictionary. + + **Note 1:** + + The getter and setter of the object are overloaded to map to the fields of the object that + are loaded when it is instantiated. + + For example: doc.name will be the `name` field and doc.owner will be the `owner` field + + **Note 2 - Standard Fields:** + + * `name`: ID / primary key + * `owner`: creator of the record + * `creation`: datetime of creation + * `modified`: datetime of last modification + * `modified_by` : last updating user + * `docstatus` : Status 0 - Saved, 1 - Submitted, 2- Cancelled + * `parent` : if child (table) record, this represents the parent record + * `parenttype` : type of parent record (if any) + * `parentfield` : table fieldname of parent record (if any) + * `idx` : Index (sequence) of the child record + """ + + def __init__(self, doctype = '', name = '', fielddata = {}, prefix='tab'): + self._roles = [] + self._perms = [] + self._user_defaults = {} + self._prefix = prefix + + if fielddata: + self.fields = fielddata + else: + self.fields = {} + + if not self.fields.has_key('name'): + self.fields['name']='' # required on save + if not self.fields.has_key('doctype'): + self.fields['doctype']='' # required on save + if not self.fields.has_key('owner'): + self.fields['owner']='' # required on save + + if doctype: + self.fields['doctype'] = doctype + if name: + self.fields['name'] = name + self.__initialized = 1 + + if (doctype and name): + self._loadfromdb(doctype, name) + + def __nonzero__(self): + return True + + def __str__(self): + return str(self.fields) + + # Load Document + # --------------------------------------------------------------------------- + + def _loadfromdb(self, doctype = None, name = None): + if name: self.name = name + if doctype: self.doctype = doctype + + if webnotes.model.meta.is_single(self.doctype): + self._loadsingle() + else: + dataset = webnotes.conn.sql('select * from `%s%s` where name="%s"' % (self._prefix, self.doctype, self.name.replace('"', '\"'))) + if not dataset: + webnotes.msgprint('%s %s does not exist' % (self.doctype, self.name), 1) + raise Exception, '[WNF] %s %s does not exist' % (self.doctype, self.name) + self._load_values(dataset[0], webnotes.conn.get_description()) + + # Load Fields from dataset + # --------------------------------------------------------------------------- + + def _load_values(self, data, description): + for i in range(len(description)): + v = data[i] + self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v) + + def _merge_values(self, data, description): + for i in range(len(description)): + v = data[i] + if v: # only if value, over-write + self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v) + + # Load Single Type + # --------------------------------------------------------------------------- + + def _loadsingle(self): + self.name = self.doctype + dataset = webnotes.conn.sql("select field, value from tabSingles where doctype='%s'" % self.doctype) + for d in dataset: self.fields[d[0]] = d[1] + + # Setter + # --------------------------------------------------------------------------- + + def __setattr__(self, name, value): + # normal attribute + if not self.__dict__.has_key('_Document__initialized'): + self.__dict__[name] = value + elif self.__dict__.has_key(name): + self.__dict__[name] = value + else: + # field attribute + f = self.__dict__['fields'] + f[name] = value + + # Getter + # --------------------------------------------------------------------------- + + def __getattr__(self, name): + if self.__dict__.has_key(name): + return self.__dict__[name] + elif self.fields.has_key(name): + return self.fields[name] + else: + return '' + + # Get Amendement number + # --------------------------------------------------------------------------- + + def _get_amended_name(self): + am_id = 1 + am_prefix = self.amended_from + if webnotes.conn.sql('select amended_from from `tab%s` where name = "%s"' % (self.doctype, self.amended_from))[0][0] or '': + am_id = cint(self.amended_from.split('-')[-1]) + 1 + am_prefix = '-'.join(self.amended_from.split('-')[:-1]) # except the last hyphen + + self.name = am_prefix + '-' + str(am_id) + + # Set Name + # --------------------------------------------------------------------------- + + def _set_name(self, autoname, istable): + self.localname = self.name + + # get my object + import webnotes.model.code + so = webnotes.model.code.get_server_obj(self, []) + + # amendments + if self.amended_from: + self._get_amended_name() + + # by method + elif so and hasattr(so, 'autoname'): + r = webnotes.model.code.run_server_obj(so, 'autoname') + if r: return r + + # based on a field + elif autoname and autoname.startswith('field:'): + n = self.fields[autoname[6:]] + if not n: + raise Exception, 'Name is required' + self.name = n.strip() + + # based on expression + elif autoname and autoname.startswith('eval:'): + doc = self # for setting + self.name = eval(autoname[5:]) + + # call the method! + elif autoname and autoname!='Prompt': + self.name = make_autoname(autoname, self.doctype) + + # given + elif self.fields.get('__newname',''): + self.name = self.fields['__newname'] + + # default name for table + elif istable: + self.name = make_autoname('#########', self.doctype) + + # Validate Name + # --------------------------------------------------------------------------- + + def _validate_name(self, case): + + if webnotes.conn.sql('select name from `tab%s` where name=%s' % (self.doctype,'%s'), self.name): + raise NameError, 'Name %s already exists' % self.name + + # no name + if not self.name: return 'No Name Specified for %s' % self.doctype + + # new.. + if self.name.startswith('New '+self.doctype): + return 'There were some errors setting the name, please contact the administrator' + + if case=='Title Case': self.name = self.name.title() + if case=='UPPER CASE': self.name = self.name.upper() + + self.name = self.name.strip() # no leading and trailing blanks + + forbidden = ['%', "'", '"', ',', '#', '*', '?', '&', '`'] + for f in forbidden: + if f in self.name: + webnotes.msgprint('%s not allowed in ID (name)' % f, raise_exception =1) + + # Insert + # --------------------------------------------------------------------------- + + def _makenew(self, autoname, istable, case='', make_autoname=1): + # set owner + if not self.owner: self.owner = webnotes.session['user'] + + # set name + if make_autoname: + self._set_name(autoname, istable) + + # validate name + self._validate_name(case) + + # insert! + webnotes.conn.sql("""insert into `tab%s` (name, owner, creation, modified, modified_by) values ('%s', '%s', '%s', '%s', '%s')""" % (self.doctype, self.name, webnotes.session['user'], now(), now(), webnotes.session['user'])) + + + # Update Values + # --------------------------------------------------------------------------- + + def _update_single(self, link_list): + update_str = ["(%s, 'modified', %s)",] + values = [self.doctype, now()] + + webnotes.conn.sql("delete from tabSingles where doctype='%s'" % self.doctype) + for f in self.fields.keys(): + if not (f in ('modified', 'doctype', 'name', 'perm', 'localname', 'creation'))\ + and (not f.startswith('__')): # fields not saved + + # validate links + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if self.fields[f]==None: + update_str.append("(%s,%s,NULL)") + values.append(self.doctype) + values.append(f) + else: + update_str.append("(%s,%s,%s)") + values.append(self.doctype) + values.append(f) + values.append(self.fields[f]) + webnotes.conn.sql("insert into tabSingles(doctype, field, value) values %s" % (', '.join(update_str)), values) + + # Validate Links + # --------------------------------------------------------------------------- + + def validate_links(self, link_list): + err_list = [] + for f in self.fields.keys(): + # validate links + old_val = self.fields[f] + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if old_val and not self.fields[f]: + s = link_list[f][1] + ': ' + old_val + err_list.append(s) + + return err_list + + def make_link_list(self): + res = webnotes.model.meta.get_link_fields(self.doctype) + + link_list = {} + for i in res: link_list[i[0]] = (i[1], i[2]) # options, label + return link_list + + def _validate_link(self, dt, dn): + if not dt: return dn + if not dn: return None + if dt.lower().startswith('link:'): + dt = dt[5:] + if '\n' in dt: + dt = dt.split('\n')[0] + tmp = webnotes.conn.sql("""SELECT name FROM `tab%s` WHERE name = %s""" % (dt, '%s'), dn) + return tmp and tmp[0][0] or ''# match case + + # Update query + # --------------------------------------------------------------------------- + + def _update_values(self, issingle, link_list, ignore_fields=0): + if issingle: + self._update_single(link_list) + else: + update_str, values = [], [] + # set modified timestamp + self.modified = now() + self.modified_by = webnotes.session['user'] + for f in self.fields.keys(): + if (not (f in ('doctype', 'name', 'perm', 'localname', 'creation','_user_tags'))) \ + and (not f.startswith('__')): # fields not saved + + # validate links + if link_list and link_list.get(f): + self.fields[f] = self._validate_link(link_list[f][0], self.fields[f]) + + if self.fields[f]==None or self.fields[f]=='': + update_str.append("`%s`=NULL" % f) + if ignore_fields: + try: r = webnotes.conn.sql("update `tab%s` set `%s`=NULL where name=%s" % (self.doctype, f, '%s'), self.name) + except: pass + else: + values.append(self.fields[f]) + update_str.append("`%s`=%s" % (f, '%s')) + if ignore_fields: + try: r = webnotes.conn.sql("update `tab%s` set `%s`=%s where name=%s" % (self.doctype, f, '%s', '%s'), (self.fields[f], self.name)) + except: pass + if values: + if not ignore_fields: + # update all in one query + r = webnotes.conn.sql("update `tab%s` set %s where name='%s'" % (self.doctype, ', '.join(update_str), self.name), values) + + # Save values + # --------------------------------------------------------------------------- + + def save(self, new=0, check_links=1, ignore_fields=0, make_autoname = 1): + """ + Saves the current record in the database. If new = 1, creates a new instance of the record. + Also clears temperory fields starting with `__` + + * if check_links is set, it validates all `Link` fields + * if ignore_fields is sets, it does not throw an exception for any field that does not exist in the + database table + """ + res = webnotes.model.meta.get_dt_values(self.doctype, 'autoname, issingle, istable, name_case', as_dict=1) + res = res and res[0] or {} + + # if required, make new + if new or (not new and self.fields.get('__islocal')) and (not res.get('issingle')): + r = self._makenew(res.get('autoname'), res.get('istable'), res.get('name_case'), make_autoname) + if r: + return r + + # save the values + self._update_values(res.get('issingle'), check_links and self.make_link_list() or {}, ignore_fields) + self._clear_temp_fields() + + # check permissions + # --------------------------------------------------------------------------- + + def _get_perms(self): + if not self._perms: + self._perms = webnotes.conn.sql("select role, `match` from tabDocPerm where parent=%s and ifnull(`read`,0) = 1 and ifnull(permlevel,0)=0", self.doctype) + + def _get_roles(self): + # check if roles match/ + if not self._roles: + if webnotes.user: + self._roles = webnotes.user.get_roles() + else: + self._roles = ['Guest'] + + def _get_user_defaults(self): + if not self._user_defaults: + self._user_defaults = webnotes.user.get_defaults() + + def check_perm(self, verbose=0): + import webnotes + + # find roles with read access for this record at 0 + self._get_perms() + self._get_roles() + self._get_user_defaults() + + has_perm, match = 0, [] + + # loop through everything to find if there is a match + for r in self._perms: + if r[0] in self._roles: + has_perm = 1 + if r[1] and match != -1: + match.append(r[1]) # add to match check + else: + match = -1 # has permission and no match, so match not required! + + if has_perm and match and match != -1: + for m in match: + if self.fields.get(m, 'no value') in self._user_defaults.get(m, 'no default'): + has_perm = 1 + break # permission found! break + else: + has_perm = 0 + if verbose: + webnotes.msgprint("Value not allowed: '%s' for '%s'" % (self.fields.get(m, 'no value'), m)) + + + # check for access key + if webnotes.form and webnotes.form.has_key('akey'): + import webnotes.utils.encrypt + if webnotes.utils.encrypt.decrypt(webnotes.form.getvalue('akey')) == self.name: + has_perm = 1 + webnotes.response['print_access'] = 1 + + return has_perm + + # Cleanup + # --------------------------------------------------------------------------- + + def _clear_temp_fields(self): + # clear temp stuff + keys = self.fields.keys() + for f in keys: + if f.startswith('__'): + del self.fields[f] + + # Table methods + # --------------------------------------------------------------------------- + + def clear_table(self, doclist, tablefield, save=0): + """ + Clears the child records from the given `doclist` for a particular `tablefield` + """ + import webnotes.model.doclist + + for d in webnotes.model.doclist.getlist(doclist, tablefield): + d.fields['__oldparent'] = d.parent + d.parent = 'old_parent:' + d.parent # for client to send it back while saving + d.docstatus = 2 + if save and not d.fields.get('__islocal'): + d.save() + self.fields['__unsaved'] = 1 + + def addchild(self, fieldname, childtype = '', local=0, doclist=None): + """ + Returns a child record of the give `childtype`. + + * if local is set, it does not save the record + * if doclist is passed, it append the record to the doclist + """ + if not childtype: + childtype = db_getchildtype(self.doctype, fieldname) + + d = Document() + d.parent = self.name + d.parenttype = self.doctype + d.parentfield = fieldname + d.doctype = childtype + d.docstatus = 0; + d.name = '' + d.owner = webnotes.session['user'] + + if local: + d.fields['__islocal'] = '1' # for Client to identify unsaved doc + else: + d.save(new=1) + + if doclist != None: + doclist.append(d) + + return d + +def addchild(parent, fieldname, childtype = '', local=0, doclist=None): + """ + + Create a child record to the parent doc. + + Example:: + + c = Document('Contact','ABC') + d = addchild(c, 'contact_updates', 'Contact Update', local = 1) + d.last_updated = 'Phone call' + d.save(1) + """ + return parent.addchild(fieldname, childtype, local, doclist) + +# Remove Child +# ------------ + +def removechild(d, is_local = 0): + """ + Sets the docstatus of the object d to 2 (deleted) and appends an 'old_parent:' to the parent name + """ + if not is_local: + set(d, 'docstatus', 2) + set(d, 'parent', 'old_parent:' + d.parent) + else: + d.parent = 'old_parent:' + d.parent + d.docstatus = 2 + +# Naming +# ------ +def make_autoname(key, doctype=''): + """ + Creates an autoname from the given key: + + **Autoname rules:** + + * The key is separated by '.' + * '####' represents a series. The string before this part becomes the prefix: + Example: ABC.#### creates a series ABC0001, ABC0002 etc + * 'MM' represents the current month + * 'YY' and 'YYYY' represent the current year + + + *Example:* + + * DE/./.YY./.MM./.##### will create a series like + DE/09/01/0001 where 09 is the year, 01 is the month and 0001 is the series + """ + n = '' + l = key.split('.') + for e in l: + en = '' + if e.startswith('#'): + digits = len(e) + en = getseries(n, digits, doctype) + elif e=='YY': + import time + en = time.strftime('%y') + elif e=='MM': + import time + en = time.strftime('%m') + elif e=='YYYY': + import time + en = time.strftime('%Y') + else: en = e + n+=en + return n + +# Get Series for Autoname +# ----------------------- +def getseries(key, digits, doctype=''): + # series created ? + if webnotes.conn.sql("select name from tabSeries where name='%s'" % key): + + # yes, update it + webnotes.conn.sql("update tabSeries set current = current+1 where name='%s'" % key) + + # find the series counter + r = webnotes.conn.sql("select current from tabSeries where name='%s'" % key) + n = r[0][0] + else: + + # no, create it + webnotes.conn.sql("insert into tabSeries (name, current) values ('%s', 1)" % key) + n = 1 + return ('%0'+str(digits)+'d') % n + + +# Get Children +# ------------ + +def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix='tab'): + import webnotes + + tmp = '' + + if field: + tmp = ' and parentfield="%s" ' % field + if parenttype: + tmp = ' and parenttype="%s" ' % parenttype + + try: + dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" % (prefix, childtype, name, tmp)) + desc = webnotes.conn.get_description() + except Exception, e: + if prefix=='arc' and e.args[0]==1146: + return [] + else: + raise e + + l = [] + + for i in dataset: + d = Document() + d.doctype = childtype + d._load_values(i, desc) + l.append(d) + + return l + +# Check if "Guest" is allowed to view this page +# --------------------------------------------- + +def check_page_perm(doc): + if doc.name=='Login Page': + return + if doc.publish: + return + + if not webnotes.conn.sql("select name from `tabPage Role` where parent=%s and role='Guest'", doc.name): + webnotes.response['exc_type'] = 'PermissionError' + raise Exception, '[WNF] No read permission for %s %s' % ('Page', doc.name) + +def get_report_builder_code(doc): + if doc.doctype=='Search Criteria': + from webnotes.model.code import get_code + + if doc.standard != 'No': + doc.report_script = get_code(doc.module, 'Search Criteria', doc.name, 'js') + doc.custom_query = get_code(doc.module, 'Search Criteria', doc.name, 'sql') + + +# called from everywhere +# load a record and its child records and bundle it in a list - doclist +# --------------------------------------------------------------------- + +def get(dt, dn='', with_children = 1, from_get_obj = 0, prefix = 'tab'): + """ + Returns a doclist containing the main record and all child records + """ + import webnotes + import webnotes.model + import webnotes.defs + + dn = dn or dt + + # load the main doc + doc = Document(dt, dn, prefix=prefix) + + # check permission - for doctypes, pages + if (dt in ('DocType', 'Page', 'Control Panel', 'Search Criteria')) or (from_get_obj and webnotes.session.get('user') != 'Guest'): + if dt=='Page' and webnotes.session['user'] == 'Guest': + check_page_perm(doc) + else: + if not doc.check_perm(): + webnotes.response['exc_type'] = 'PermissionError' + raise webnotes.ValidationError, '[WNF] No read permission for %s %s' % (dt, dn) + + # import report_builder code + get_report_builder_code(doc) + + if not with_children: + # done + return [doc,] + + # get all children types + tablefields = webnotes.model.meta.get_table_fields(dt) + + # load chilren + doclist = [doc,] + for t in tablefields: + doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix) + + return doclist diff --git a/cgi-bin/webnotes/model/doclist.py b/cgi-bin/webnotes/model/doclist.py new file mode 100644 index 0000000000..aff1ebbc6c --- /dev/null +++ b/cgi-bin/webnotes/model/doclist.py @@ -0,0 +1,191 @@ +import webnotes +import webnotes.model +import webnotes.model.doc + +def xzip(a,b): + d = {} + for i in range(len(a)): + d[a[i]] = b[i] + return d + +def expand(docs): + """ + Expand a doclist sent from the client side. (Internally used by the request handler) + """ + from webnotes.utils import load_json + + docs = load_json(docs) + clist = [] + for d in docs['_vl']: + doc = xzip(docs['_kl'][d[0]], d); + clist.append(doc) + return clist + +def compress(doclist): + """ + Compress a doclist before sending it to the client side. (Internally used by the request handler) + + """ + if doclist and hasattr(doclist[0],'fields'): + docs = [d.fields for d in doclist] + else: + docs = doclist + + kl, vl = {}, [] + for d in docs: + dt = d['doctype'] + if not (dt in kl.keys()): + fl = d.keys() + forbidden = ['server_code_compiled'] + nl = ['doctype','localname','__oldparent','__unsaved'] + + # add client script for doctype, doctype due to ambiguity + if dt=='DocType': nl.append('__client_script') + + for f in fl: + if not (f in nl) and not (f in forbidden): + nl.append(f) + kl[dt] = nl + + ## values + fl = kl[dt] + nl = [] + for f in fl: + v = d.get(f) + + if type(v)==long: + v=int(v) + nl.append(v) + vl.append(nl) + #errprint(str({'_vl':vl,'_kl':kl})) + return {'_vl':vl,'_kl':kl} + +# Get Children List (for scripts utility) +# --------------------------------------- + +def getlist(doclist, field): + """ + Filter a list of records for a specific field from the full doclist + + Example:: + + # find all phone call details + dl = getlist(self.doclist, 'contact_updates') + pl = [] + for d in dl: + if d.type=='Phone': + pl.append(d) + """ + + l = [] + for d in doclist: + if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: + l.append(d) + return l + +# Copy doclist +# ------------ + +def copy_doclist(doclist, no_copy = []): + """ + Save & return a copy of the given doclist + Pass fields that are not to be copied in `no_copy` + """ + from webnotes.model.doc import Document + + cl = [] + + # main doc + c = Document(fielddata = doclist[0].fields.copy()) + + # clear no_copy fields + for f in no_copy: + if c.fields.has_key(f): + c.fields[f] = None + + c.name = None + c.save(1) + cl.append(c) + + # new parent name + parent = c.name + + # children + for d in doclist[1:]: + c = Document(fielddata = d.fields.copy()) + c.name = None + + # clear no_copy fields + for f in no_copy: + if c.fields.has_key(f): + c.fields[f] = None + + c.parent = parent + c.save(1) + cl.append(c) + + return cl + +# Validate Multiple Links +# ----------------------- + +def validate_links_doclist(doclist): + """ + Validate link fields and return link fields that are not correct. + Calls the `validate_links` function on the Document object + """ + ref, err_list = {}, [] + for d in doclist: + if not ref.get(d.doctype): + ref[d.doctype] = d.make_link_list() + + err_list += d.validate_links(ref[d.doctype]) + return ', '.join(err_list) + +# Get list of field values +# ------------------------ + +def getvaluelist(doclist, fieldname): + """ + Returns a list of values of a particualr fieldname from all Document object in a doclist + """ + l = [] + for d in doclist: + l.append(d.fields[fieldname]) + return l + +def _make_html(doc, link_list): + + from webnotes.utils import cstr + out = '' + for k in doc.fields.keys(): + if k!='server_code_compiled': + v = cstr(doc.fields[k]) + + # link field + if v and (k in link_list.keys()): + dt = link_list[k] + if type(dt)==str and dt.startswith('link:'): + dt = dt[5:] + v = '%s' % (dt, v, v) + + out += '\t\n' % (cstr(k), v) + + out += '
%s%s
' + return out + +def to_html(doclist): + """ +Return a simple HTML format of the doclist + """ + out = '' + link_lists = {} + + for d in doclist: + if not link_lists.get(d.doctype): + link_lists[d.doctype] = d.make_link_list() + + out += _make_html(d, link_lists[d.doctype]) + + return out + diff --git a/cgi-bin/webnotes/model/doctype.py b/cgi-bin/webnotes/model/doctype.py new file mode 100644 index 0000000000..ce61b3c8fd --- /dev/null +++ b/cgi-bin/webnotes/model/doctype.py @@ -0,0 +1,282 @@ +""" + DocType module + ============== + + This module has the DocType class that represents a "DocType" as metadata. + This is usually called by the form builder or report builder. + + Key functions: + * manage cache - read / write + * merge client-side scripts + * update properties from the modules .txt files + + Cache management: + * Cache is stored in __DocTypeCache +""" + +import webnotes +import webnotes.model +import webnotes.model.doclist +import webnotes.model.doc + +from webnotes.utils import cstr + +class _DocType: + """ + The _DocType object is created internally using the module's `get` method. + """ + def __init__(self, name): + self.name = name + + # is cache modified ? + # ================================================================= + + def is_modified(self): + """ + Returns true if modified + """ + try: + # doctype modified + modified = webnotes.conn.sql("select modified from tabDocType where name=%s", self.name)[0][0] + + # cache modified + cache_modified = webnotes.conn.sql("SELECT modified from `__DocTypeCache` where name='%s'" % self.name)[0][0] + + except IndexError, e: + return 1 + + return cache_modified != modified + + # write to cache + # ================================================================= + + def _update_cache(self, doclist): + import zlib + + if webnotes.conn.sql("SELECT name FROM __DocTypeCache WHERE name=%s", self.name): + webnotes.conn.sql("UPDATE `__DocTypeCache` SET `modified`=%s, `content`=%s WHERE name=%s", (doclist[0].modified, zlib.compress(str([d.fields for d in doclist]),2), self.name)) + else: + webnotes.conn.sql("INSERT INTO `__DocTypeCache` (`name`, `modified`, `content`) VALUES (%s, %s, %s)" , (self.name, doclist[0].modified, zlib.compress(str([d.fields for d in doclist])))) + + # read from cache + # ================================================================= + + def _load_from_cache(self): + import zlib + + doclist = eval(zlib.decompress(webnotes.conn.sql("SELECT content from `__DocTypeCache` where name=%s", self.name)[0][0])) + return [webnotes.model.doc.Document(fielddata = d) for d in doclist] + + + # load options for "link:" type 'Select' fields + # ================================================================= + + def _load_select_options(self, doclist): + for d in doclist: + if d.doctype=='DocField' and d.fieldtype=='Select' and d.options and d.options[:5].lower()=='link:': + op = d.options.split('\n') + if len(op)>1 and op[1][:4].lower() == 'sql:': + ol = webnotes.conn.sql(op[1][4:].replace('__user', webnotes.session['user'])) + else: + t = op[0][5:].strip() + op = op[1:] + op = [oc.replace('__user', webnotes.session['user']) for oc in op] + + try: + # select options will always come from the user db + ol = webnotes.conn.sql("select name from `tab%s` where %s docstatus!=2 order by name asc" % (t, op and (' AND '.join(op) + ' AND ') or '')) + except: + ol = [] + ol = [''] + [o[0] or '' for o in ol] + d.options = '\n'.join(ol) + + # clear un-necessary code from going to the client side + # ================================================================= + + def _clear_code(self, doclist): + if self.name != 'DocType': + if doclist[0].server_code: doclist[0].server_code = None + if doclist[0].server_code_core: doclist[0].server_code_core = None + if doclist[0].client_script: doclist[0].client_script = None + if doclist[0].client_script_core: doclist[0].client_script_core = None + doclist[0].server_code_compiled = None + + # build a list of all the records required for the DocType + # ================================================================= + + def _get_last_update(self, dt): + """ + Returns last update timestamp + """ + try: + last_update = webnotes.conn.sql("select _last_update from tabDocType where name=%s", dt)[0][0] + except Exception, e: + if e.args[0]==1054: + self._setup_last_update(dt) + last_update = None + + return last_update + + def _setup_last_update(self, doctype): + """ + Adds _last_update column to tabDocType + + """ + webnotes.conn.commit() + webnotes.conn.sql("alter table `tabDocType` add column _last_update varchar(32)") + webnotes.conn.begin() + + def _get_fields(self, file_name): + """ + Returns a dictionary of DocFields by fieldname or label + """ + try: + doclist = open(file_name, 'r').read() + except: + return + doclist = eval(doclist) + fields = {} + for d in doclist: + if d['doctype']=='DocField': + if d['fieldname'] or d['label']: + fields[d['fieldname'] or d['label']] = d + return fields + + def _update_field_properties(self, doclist): + """ + Updates properties like description, depends on from the database based on the timestamp + of the .txt file. Adds a column _last_updated if not exists in the database and uses + it to update the file.. + + This feature is built because description is changed / updated quite often and is tedious to + write a patch every time. Can be extended to cover more updates + """ + + update_fields = ('description', 'depends_on') + + from webnotes.modules import get_file_timestamp, get_item_file + + doc = doclist[0] # main doc + file_name = get_item_file(doc.module, 'DocType', doc.name) + time_stamp = get_file_timestamp(file_name) + last_update = self._get_last_update(doc.name) + + # this is confusing because we are updating the fields of fields + + if last_update != time_stamp: + + # there are updates! + fields = self._get_fields(file_name) + if fields: + for d in doclist: + + # for each field in teh outgoing doclist + if d.doctype=='DocField': + key = d.fieldname or d.label + + # if it has a fieldname or label + if key and key in fields: + + # update the values + for field_to_update in update_fields: + new_value = fields[key][field_to_update] + + # in doclist + d.fields[field_to_update] = new_value + + # in database + webnotes.conn.sql("update tabDocField set `%s` = %s where parent=%s and `%s`=%s" % \ + (field_to_update, '%s', '%s', (d.fieldname and 'fieldname' or 'label'), '%s'), \ + (new_value, doc.name, key)) + + webnotes.conn.sql("update tabDocType set _last_update=%s where name=%s", (time_stamp, doc.name)) + + def _override_field_properties(self, doclist): + """ + Override field properties that are updated by "Property Setter" + The term "property" is used to define a fieldname of a field to avoid confusing + terminology + """ + # load field properties and add them to a dictionary + property_dict = {} + dt = doclist[0].name + try: + for f in webnotes.conn.sql("select doc_name, property, property_type, value from `tabProperty Setter` where doc_type=%s", dt, as_dict=1): + if not f['doc_name'] in property_dict: + property_dict[f['doc_name']] = [] + property_dict[f['doc_name']].append(f) + except Exception, e: + if e.args[0]==1146: + # no override table + pass + else: + raise e + + # loop over fields and override property + for d in doclist: + if d.doctype=='DocField' and d.name in property_dict: + for p in property_dict[d.name]: + if p['property_type']=='Check': + d.fields[p['property']] = int(p['value']) + else: + d.fields[p['property']] = p['value'] + + # override properties in the main doctype + if dt in property_dict: + for p in property_dict[self.name]: + doclist[0].fields[p['property']] = p['value'] + + + def make_doclist(self): + """ + returns the :term:`doclist` for consumption by the client + + * it cleans up the server code + * executes all `$import` tags in client code + * replaces `link:` in the `Select` fields + * loads all related `Search Criteria` + * updates the cache + """ + from webnotes.modules import compress + + tablefields = webnotes.model.meta.get_table_fields(self.name) + + if self.is_modified(): + # yes + doclist = webnotes.model.doc.get('DocType', self.name, 1) + + self._update_field_properties(doclist) + self._override_field_properties(doclist) + + # table doctypes + for t in tablefields: + table_doclist = webnotes.model.doc.get('DocType', t[0], 1) + + self._override_field_properties(table_doclist) + doclist += table_doclist + + # don't save compiled server code + + else: + doclist = self._load_from_cache() + + doclist[0].fields['__client_script'] = compress.get_doctype_js(self.name) + self._load_select_options(doclist) + self._clear_code(doclist) + + return doclist + +def clear_cache(): + webnotes.conn.sql("delete from __DocTypeCache") + +# Load "DocType" - called by form builder, report buider and from code.py (when there is no cache) +#================================================================================================= + +def get(dt): + """ + Load "DocType" - called by form builder, report buider and from code.py (when there is no cache) + """ + doclist = _DocType(dt).make_doclist() + + return doclist + diff --git a/cgi-bin/webnotes/model/import_docs.py b/cgi-bin/webnotes/model/import_docs.py new file mode 100644 index 0000000000..44c872c920 --- /dev/null +++ b/cgi-bin/webnotes/model/import_docs.py @@ -0,0 +1,415 @@ +import webnotes + +def import_docs(docs = []): + from webnotes.model.doc import Document + import webnotes.model.code + + doc_list = {} + created_docs = [] + already_exists = [] + + out, tmp ="", "" + + for d in docs: + cur_doc = Document(fielddata = d) + if not cur_doc.parent in already_exists: # parent should not exist + try: + cur_doc.save(1) + out += "Created: " + cur_doc.name + "\n" + created_docs.append(cur_doc) + + # make in groups + if cur_doc.parent: + if not doc_list.has_key(cur_doc.parent): + doc_list[cur_doc.parent] = [] + doc_list[cur_doc.parent].append(cur_doc) + + except Exception, e: + out += "Creation Warning/Error: " + cur_doc.name + " :"+ str(e) + "\n" + already_exists.append(cur_doc.name) + + # Run scripts for main docs + for m in created_docs: + if doc_list.has_key(m.name): + tmp = webnotes.model.code.run_server_obj(webnotes.model.code.get_server_obj(m, doc_list.get(m.name, [])),'on_update') + + # update database (in case of DocType) + if m.doctype=='DocType': + import webnotes.model.doctype + try: webnotes.model.doctype.update_doctype(doc_list.get(m.name, [])) + except: pass + out += 'Executed: '+ str(m.name) + ', Err:' + str(tmp) + "\n" + + return out + +#====================================================================================================================================== + +import webnotes +import webnotes.utils +sql = webnotes.conn.sql +flt = webnotes.utils.flt +cint = webnotes.utils.cint +cstr = webnotes.utils.cstr + +class CSVImport: + def __init__(self): + self.msg = [] + self.csv_data = None + self.import_date_format = None + + def validate_doctype(self, dt_list): + cl, tables, self.dt_list, self.prompt_autoname_flag = 0, [t[0] for t in sql("show tables")], [], 0 + self.msg.append('

Identifying Documents

') + dtd = sql("select name, istable, autoname from `tabDocType` where name = '%s' " % dt_list[0]) + if dtd and dtd[0][0]: + self.msg.append('
Identified Document: ' + dt_list[0] + '
') + self.dt_list.append(dt_list[0]) + if dtd[0][2] and 'Prompt' in dtd[0][2]: self.prompt_autoname_flag = 1 + if flt(dtd[0][1]): + res1 = sql("select parent, fieldname from tabDocField where options='%s' and fieldtype='Table' and docstatus!=2" % self.dt_list[0]) + if res1 and res1[0][0] == dt_list[1]: + self.msg.append('
Identified Document: ' + dt_list[1] + '
') + self.dt_list.append(dt_list[1]) + else : + self.msg.append('
Error: At Row 1, Column 2 => %s is not a valid Document
' % dt_list[1]) + self.validate_success = 0 + + if res1 and res1[0][1] == dt_list[2]: + self.msg.append('
Identified Document Fieldname: ' + dt_list[2] + '
') + self.dt_list.append(dt_list[2]) + else : + self.msg.append('
Error: At Row 1, Column 3 => %s is not a valid Fieldname
' % dt_list[2]) + self.validate_success = 0 + elif dt_list[1]: + self.msg.append('
Error: At Row 1, Column 1 => %s is not a Table.
' % dt_list[0]) + self.validate_success = 0 + else: + self.msg.append('
Error: At Row 1, Column 1 => %s is not a valid Document
' % dt_list[0]) + self.validate_success = 0 + + + def validate_fields(self, lb_list): + self.msg.append('

Checking fieldnames for %s

' % self.dt_list[0]) + if len(self.dt_list) > 1 and self.overwrite: + self.msg.append('
Error: Overwrite is not possible for Document %s
' % self.dt_list[0]) + self.validate_success = 0 + return + + elif self.overwrite and 'Name' != lb_list[0]: + self.msg.append('
Error : At Row 4 and Column 1: To Overwrite fieldname should be Name
') + self.validate_success = 0 + return + # labelnames + res = self.validate_success and [d[0] for d in sql("select label from tabDocField where parent='%s' and docstatus!=2 and ifnull(hidden,'') in ('',0)" % self.dt_list[0])] or [] + + if len(self.dt_list) > 1 and self.dt_list[1]: + self.fields.append('parent') + lb_list.pop(lb_list.index(self.dt_list[1])) + + dtd = sql("select autoname from `tabDocType` where name = '%s' " % self.dt_list[0])[0][0] + if self.prompt_autoname_flag or self.overwrite: + self.fields.append('name') + res.append('Name') + lb_list.pop(lb_list.index('Name')) + + cl = 1 + for l in lb_list: + try: + if l: + if not (l in res): + self.msg.append('
Error : At Row 4 and Column %s Field %s is not present in %s
' % (cl, l, self.dt_list[0])) + self.validate_success = 0 + # this condition is for child doctype + + else: self.fields.append(sql("select fieldname from tabDocField where parent ='%s' and label = '%s' and ifnull(fieldname,'') !='' " % (self.dt_list[0], l))[0][0] or '') + except Exception, e: + self.msg.append('
At Row 4 and Column %s : =>ERROR: %s
' % ( cl, e)) + self.validate_success = 0 + cl = cl + 1 + + if not self.overwrite: + # get_reqd_fields + reqd_list = [d[0] for d in sql("select label from `tabDocField` where parent = '%s' and ifnull(reqd,'') not in ('', 0) and docstatus !=2" % self.dt_list[0]) if d[0] not in lb_list] or [] + + # Check if Reqd field not present in self.fields + if reqd_list: + self.msg.append('
Error : At Row 4 Mandatory Fields %s of Document %s are Required.
' %(reqd_list , self.dt_list[0])) + self.validate_success = 0 + if self.validate_success: + self.msg.append('
Fields OK for %s
' % self.dt_list[0]) + + def validate_headers(self): + self.validate_doctype(self.doctype_data) + if self.validate_success: + self.validate_fields(self.labels) + + # Date parsing + # -------------------------------------------------------------------- + def parse_date(self, r, c, d): + out = '' + try: + if self.import_date_format=='yyyy-mm-dd': + tmpd = d.split('-') + + if len(tmpd)==3: + out = tmpd[0] + '-'+tmpd[1] + '-' + tmpd[2] + + elif d and self.import_date_format=='dd-mm-yyyy': + tmpd = d.split('-') + + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + elif d and self.import_date_format=='mm/dd/yyyy': + tmpd = d.split('/') + + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[0]+'-'+tmpd[1] + + elif d and self.import_date_format=='mm/dd/yy': + tmpd = d.split('/') + + if len(tmpd)==3: + out = '20'+tmpd[2]+'-'+tmpd[0]+'-'+tmpd[1] + + elif d and self.import_date_format=='dd/mm/yyyy': + tmpd = d.split('/') + if len(tmpd)==3: + out = tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + elif d and self.import_date_format=='dd/mm/yy': + tmpd = d.split('/') + if len(tmpd)==3: + out = '20'+tmpd[2]+'-'+tmpd[1]+'-'+tmpd[0] + + if len(tmpd) != 3: + self.msg.append('
At Row %s and Column %s : => Date Format selected as %s does not match with Date Format in File
' % (r, c, str(self.import_date_format))) + self.validate_success = 0 + else: + + import datetime + dt = out.split('-') + datetime.date(int(dt[0]),int(dt[1]), int(dt[2])) + except Exception, e: + self.msg.append('
At Row %s and Column %s : =>ERROR: %s
' % (r, c, e)) + self.validate_success = 0 + self.msg.append(out) + return out + + def check_select_link_data(self, r, c, f, d, s = '', l = ''): + options = '' + try: + if d and f: + dt = sql("select options, label from `tabDocField` where fieldname ='%s' and parent = '%s' " % (f, self.dt_list[0])) + dt, lbl = (dt and dt[0][0] and dt[0][0].strip() or None), dt and dt[0][1].strip() + if dt: + options = l and dt and [n[0] for n in sql("select name from `tab%s` " % (('link:' in dt and dt[5:]) or dt))] or s and dt.split('\n') or '' + if options and d not in options : + msg = '
At Row ' + str(r) + ' and Column ' + str(c)+ ' : => Data "' + str(d) + '" in field ['+ str(lbl) +'] Not Found in ' + msg = msg.__add__( s and str( 'Select Options [' +str(dt.replace('\n', ',')) +']' ) or str('Master ' + str('link:' in dt and dt[5:] or dt))) + msg = msg.__add__('
\n') + self.msg.append(msg) + + self.validate_success = 0 + except Exception, e: + self.msg.append('
ERROR: %s
' % (str(webnotes.utils.getTraceback()))) + self.validate_success = 0 + return d + + + def get_field_type_list(self): + # get_date_fields + date_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and fieldtype='Date' and docstatus !=2" % self.dt_list[0])] + + # get_link_fields + link_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and ((fieldtype='Link' and ifnull(options,'') != '') or (fieldtype='Select' and ifnull(options,'') like '%%link:%%')) and docstatus !=2 " % self.dt_list[0])] + + # get_select_fileds + select_list = [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and fieldtype='Select' and ifnull(options,'') not like '%%link:%%' and docstatus !=2" % self.dt_list[0])] + + # get_reqd_fields + reqd_list = self.overwrite and ['name'] or [d[0] for d in sql("select fieldname from `tabDocField` where parent = '%s' and ifnull(reqd,'') not in ('', 0) and docstatus !=2" % self.dt_list[0])] + + if len(self.dt_list)> 1 and 'parent' not in reqd_list: reqd_list.append('parent') + + if self.prompt_autoname_flag and 'name' not in reqd_list: reqd_list.append('name') + + return date_list, link_list, select_list, reqd_list + + + def validate_data(self): + self.msg.append('

Checking Data for %s

' % self.dt_list[0]) + date_list, link_list, select_list, reqd_list = self.get_field_type_list() + + + # load data + row = 5 + for d in self.data: + self.validate_success, fd, col = 1, {}, 1 + self.msg.append('

Checking Row %s

' % (row)) + for i in range(len(d)): + if i < len(self.fields): + f = self.fields[i] + try: + # Check Reqd Fields + if (f in reqd_list) and not d[i]: + self.msg.append('
Error: At Row %s and Column %s, Field %s is Mandatory.
' % (row, col, f)) + self.validate_success = 0 + + # Check Date Fields + if d[i] and f and f in date_list : fd[f] = self.parse_date(row, col, d[i]) + + # Check Link Fields + elif d[i] and f in link_list: + fd[f] = self.check_select_link_data(row, col, f, d[i], l='Link') + + # Check Select Fields + elif d[i] and f in select_list: + fd[f] = self.check_select_link_data(row, col, f, d[i], s= 'Select') + + # Need To Perform Check For Other Data Type Too + else: fd[f] = d[i] + + except Exception: + self.msg.append('
ERROR: %sData:%s and %s and %s and %s
' % (str(webnotes.utils.getTraceback()) + '\n', str(d), str(f), str(date_list), str(link_list))) + self.validate_success = 0 + elif d[i]: + self.validate_success = 0 + self.msg.append('
At Row %s and Column %s
' % (row,col)) + self.msg.append('
Ignored
') + col = col + 1 + if self.validate_success: + self.msg.append('
At Row %s and Column %s, Data Verification Completed
' % (row,col)) + self.update_data(fd,row) + row = row + 1 + + def update_data(self, fd, row): + # load metadata + from webnotes.model.doc import Document + cur_doc = Document(fielddata = fd) + cur_doc.doctype, cur_doc.parenttype, cur_doc.parentfield = self.dt_list[0], len(self.dt_list) > 1 and self.dt_list[1] or '', len(self.dt_list) > 1 and self.dt_list[2] or '' + obj = '' + # save the document + try: + if webnotes.conn.in_transaction: + sql("COMMIT") + sql("START TRANSACTION") + if cur_doc.name and webnotes.conn.exists(self.dt_list[0], cur_doc.name): + if self.overwrite: + cur_doc.save() + obj = webnotes.model.code.get_obj(cur_doc.parent and cur_doc.parent_type or cur_doc.doctype, cur_doc.parent or cur_doc.name, with_children = 1) + self.msg.append('
Row %s => Over-written: %s
' % (row, cur_doc.name)) + else: + self.msg.append('
Row %s => Ignored: %s
' % (row, cur_doc.name)) + else: + if cur_doc.parent and webnotes.conn.exists(cur_doc.parenttype, cur_doc.parent) or not cur_doc.parent: + cur_doc.save(1) + obj = webnotes.model.code.get_obj(cur_doc.parent and cur_doc.parenttype or cur_doc.doctype, cur_doc.parent or cur_doc.name, with_children = 1) + self.msg.append('
Row %s => Created: %s
' % (row, cur_doc.name)) + else: + self.msg.append('
Row %s => Invalid %s : %s
' % (row, cur_doc.parenttype, cur_doc.parent)) + except Exception: + self.msg.append('
Validation: %s
' % str(webnotes.utils.getTraceback())) + try: + if obj: + if hasattr(obj, 'validate') : obj.validate() + if hasattr(obj, 'on_update') : obj.on_update() + if hasattr(obj, 'on_submit') : obj.on_submit() + sql("COMMIT") + + except Exception: + sql("ROLLBACK") + self.msg.append('
Validation: %s
' % str(webnotes.message_log[-1:])) + + # do import + # -------------------------------------------------------------------- + def import_csv(self, csv_data, import_date_format = 'yyyy-mm-dd', overwrite = 0): + import csv + self.validate_success, self.csv_data = 1, self.convert_csv_data_into_list(csv.reader(csv_data.splitlines())) + self.import_date_format, self.overwrite = import_date_format, overwrite + if len(self.csv_data) > 4: + + self.doctype_data, self.labels, self.data = self.csv_data[0][:4], self.csv_data[3], self.csv_data[4:] + self.fields = [] + + import webnotes.model.code + from webnotes.model.doc import Document + sql = webnotes.conn.sql + + self.validate_headers() + if self.validate_success: + self.validate_data() + else: + self.msg.append('

No data entered in file.

') + return '\n'.join(self.msg) + + def convert_csv_data_into_list(self,csv_data): + st_list = [] + for s in csv_data: + st_list.append([d.strip() for d in s]) + return st_list + +# Get Template method +# ----------------------------------------------------------------- + +def get_template(): + import webnotes.model + + from webnotes.utils import getCSVelement + + form = webnotes.form + sql = webnotes.conn.sql + # get form values + dt = form.getvalue('dt') + overwrite = cint(form.getvalue('overwrite')) or 0 + + pt, pf = '', '' + tmp_lbl, tmp_ml = [],[] + + # is table? + dtd = sql("select istable, autoname from tabDocType where name='%s'" % dt) + if dtd and dtd[0][0]: + res1 = sql("select parent, fieldname from tabDocField where options='%s' and fieldtype='Table' and docstatus!=2" % dt) + if res1: + pt, pf = res1[0][0], res1[0][1] + + # line 1 + dset = [] + if pt and pf: + lbl, ml = [pt], ['[Mandatory]'] + line1 = '%s,%s,%s' % (getCSVelement(dt), getCSVelement(pt), getCSVelement(pf)) + line2 = ',,,,,,Please fill valid %(p)s No in %(p)s column.' % {'p':getCSVelement(pt)} + else: + if dtd[0][1]=='Prompt' or overwrite: + lbl, ml= ['Name'], ['[Mandatory][Special Characters are not allowed]'] + else: + lbl, ml= [], [] + line1 = '%s' % getCSVelement(dt) + line2 = (overwrite and ',,,,,,Please fill valid %(d)s No in %(n)s' % {'d':dt,'n': 'Name'}) or ',,' + + # Help on Line + line1 = line1 + ',,,Please fill columns which are Mandatory., Please do not modify the structure' + + # fieldnames + res = sql("select fieldname, fieldtype, label, reqd, hidden from tabDocField where parent='%s' and docstatus!=2" % dt) + + for r in res: + # restrict trash_reason field, hidden and required fields + if not r[1] in webnotes.model.no_value_fields and r[0] != 'trash_reason' and not r[4] and not r[3]: + tmp_lbl.append(getCSVelement(r[2])) + tmp_ml.append('') + # restrict trash_reason field and hidden fields and add Mandatory indicator for required fields + elif not r[1] in webnotes.model.no_value_fields and r[0] != 'trash_reason' and not r[4] and r[3]: + lbl.append(getCSVelement(r[2])) + ml.append(getCSVelement('[Mandatory]')) + + dset.append(line1) + dset.append(line2) + dset.append(','.join(ml + tmp_ml)) + dset.append(','.join(lbl + tmp_lbl)) + + txt = '\n'.join(dset) + webnotes.response['result'] = txt + webnotes.response['type'] = 'csv' + webnotes.response['doctype'] = dt + diff --git a/cgi-bin/webnotes/model/meta.py b/cgi-bin/webnotes/model/meta.py new file mode 100644 index 0000000000..f9fa156e33 --- /dev/null +++ b/cgi-bin/webnotes/model/meta.py @@ -0,0 +1,57 @@ +# metadata + +import webnotes + +#================================================================================= + +def get_dt_values(doctype, fields, as_dict = 0): + return webnotes.conn.sql('SELECT %s FROM tabDocType WHERE name="%s"' % (fields, doctype), as_dict = as_dict) + +def set_dt_value(doctype, field, value): + return webnotes.conn.set_value('DocType', doctype, field, value) + +def is_single(doctype): + try: + return get_dt_values(doctype, 'issingle')[0][0] + except IndexError, e: + raise Exception, 'Cannot determine whether %s is single' % doctype + +#================================================================================= + +def get_parent_dt(dt): + parent_dt = webnotes.conn.sql('select parent from tabDocField where fieldtype="Table" and options="%s" and (parent not like "old_parent:%%") limit 1' % dt) + return parent_dt and parent_dt[0][0] or '' + +#================================================================================= + +def set_fieldname(field_id, fieldname): + webnotes.conn.set_value('DocField', field_id, 'fieldname', fieldname) + +#================================================================================= + +def get_link_fields(doctype): + return webnotes.conn.sql("SELECT fieldname, options, label FROM tabDocField WHERE parent='%s' and (fieldtype='Link' or (fieldtype='Select' and `options` like 'link:%%'))" % (doctype)) + +#================================================================================= + +def get_table_fields(doctype): + return webnotes.conn.sql("select options, fieldname from tabDocField where parent='%s' and fieldtype='Table'" % doctype) + +#================================================================================= + +def get_search_criteria(dt): + import webnotes.model.doc + # load search criteria for reports (all) + dl = [] + sc_list = webnotes.conn.sql("select name from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s' and (disabled!=1 OR disabled IS NULL)" % (dt, dt)) + for sc in sc_list: + if sc[0]: + dl += webnotes.model.doc.get('Search Criteria', sc[0]) + return dl + +#================================================================================= + +def get_print_format_html(name): + html = webnotes.conn.sql('select html from `tabPrint Format` where name="%s"' % name) + return html and html[0][0] or '' + \ No newline at end of file diff --git a/cgi-bin/webnotes/model/modules.py b/cgi-bin/webnotes/model/modules.py new file mode 100644 index 0000000000..f979273a39 --- /dev/null +++ b/cgi-bin/webnotes/model/modules.py @@ -0,0 +1,26 @@ +# Modules +# ----------- + +def get_module_items(mod, only_dt=0): + dl = [] + if only_dt: + transfer_types = ['DocType'] + else: + transfer_types = ['Role', 'Page', 'DocType', 'DocType Mapper', 'Search Criteria'] + dl = ['Module Def,'+mod] + + for dt in transfer_types: + try: + dl2 = sql('select name from `tab%s` where module="%s"' % (dt,mod)) + dl += [(dt+','+e[0]) for e in dl2] + except: + pass + + if not only_dt: + dl1 = sql('select doctype_list from `tabModule Def` where name=%s', mod) + dl += dl1[0][0].split('\n') + + # build finally + dl = [e.split(',') for e in dl] + dl = [[e[0].strip(), e[1].strip()] for e in dl] # remove blanks + return dl \ No newline at end of file diff --git a/cgi-bin/webnotes/model/triggers.py b/cgi-bin/webnotes/model/triggers.py new file mode 100644 index 0000000000..34654492dc --- /dev/null +++ b/cgi-bin/webnotes/model/triggers.py @@ -0,0 +1,68 @@ +""" +Add, manage, fire triggers (events / observers) +Standard events called by the framework are "save, submit, cancel" +""" + +import webnotes + +def insert_trigger(doctype, docname, event_name, method): + "inserts a new trigger record" + + from webnotes.model.doc import Document + d = Document('DocTrigger') + d.doc_type = doctype + d.doc_name = docname + d.event_name = event_name + d.method = method + d.save(1) + +def add_trigger(doctype, docname, event_name, method): + """Add a trigger to an event on a doctype, docname. The specified method will be called. + Wild card '*' is allowed in doctype, docname and/or event_name""" + + try: + if not trigger_exists(doctype, docname, event_name, method): + insert_trigger(doctype, docname, event_name, method) + except Exception, e: + if e.args[0]==1146: + setup() + insert_trigger(doctype, docname, event_name, method) + else: raise e + +def trigger_exists(doctype, docname, event_name, method): + "returns true if trigger exists" + return webnotes.conn.sql("select name from tabDocTrigger where doc_name=%s and doc_type=%s and event_name=%s and method=%s", \ + (doctype, docname, event_name, method)) + +def remove_trigger(doctype, docname, event_name, method): + "Remove a trigger on an event" + webnotes.conn.sql("delete from tabDocTrigger where doc_name=%s and doc_type=%s and event_name=%s and method=%s", \ + (doctype, docname, event_name, method)) + +def fire_event(doc, event_name): + "Fire all triggers on an event and passes the doc to the trigger" + try: + tl = webnotes.conn.sql("""select method from tabDocTrigger + where (doc_type=%s or doc_type='*') + and (doc_name=%s or doc_name='*') + and (event_name=%s or event_name='*')""", (doc.doctype, doc.name, event_name)) + except Exception, e: + if e.args[0]==1146: + setup() + tl = [] + else: raise e + + for t in tl: + module, method = '.'.join(t[0].split('.')[:-1]), t[0].split('.')[-1] + exec 'from %s import %s' % (module, method) in locals() + locals()[method](doc) +# +# setup +# +def setup(): + "creates the DocTrigger table from core" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core','doctype','doctrigger') + webnotes.conn.begin() + \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/__init__.py b/cgi-bin/webnotes/modules/__init__.py new file mode 100644 index 0000000000..665c77013c --- /dev/null +++ b/cgi-bin/webnotes/modules/__init__.py @@ -0,0 +1,65 @@ +""" + Utilities for using modules +""" + +transfer_types = ['Role', 'Print Format','DocType','Page','DocType Mapper','GL Mapper','Search Criteria', 'Patch'] + +def scrub(txt): + return txt.replace(' ','_').replace('-', '_').replace('/', '_').lower() + +def scrub_dt_and_dn(dt, dn): + """ + Returns in lowercase and code friendly names of doctype and name for certain types + """ + ndt, ndn = dt, dn + if dt.lower() in ('doctype', 'search criteria', 'page'): + ndt, ndn = scrub(dt), scrub(dn) + + return ndt, ndn + +def get_item_file(module, dt, dn): + """ + Returns the path of the item file + """ + import os + ndt, ndn = scrub_dt_and_dn(dt, dn) + + return os.path.join(get_module_path(module), ndt, ndn, ndn + '.txt') + +def get_item_timestamp(module, dt, dn): + """ + Return ths timestamp of the given item (if exists) + """ + return get_file_timestamp(get_item_file(module, dt, dn)) + +def get_file_timestamp(fn): + """ + Returns timestamp of the given file + """ + import os + from webnotes.utils import cint + + try: + return str(cint(os.stat(fn).st_mtime)) + except OSError, e: + if e.args[0]!=2: + raise e + else: + return None + +def get_module_path(module): + """ + Returns path of the given module (imports it and reads it from __file__) + """ + import webnotes.defs, os, os.path + + try: + exec ('import ' + scrub(module)) in locals() + modules_path = eval(scrub(module) + '.__file__') + + modules_path = os.path.sep.join(modules_path.split(os.path.sep)[:-1]) + except ImportError, e: + # get module path by importing the module + modules_path = os.path.join(webnotes.defs.modules_path, scrub(module)) + + return modules_path \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/compress.py b/cgi-bin/webnotes/modules/compress.py new file mode 100644 index 0000000000..04bd96bc23 --- /dev/null +++ b/cgi-bin/webnotes/modules/compress.py @@ -0,0 +1,342 @@ +""" +Load compressed .js page scripts + +Will also replace $import(page) or $import(module.page) with the relevant js files +""" + + +# load "compressed" js code from modules +#============================================================================== + +def get_js_code(fn, extn='js'): + """ + Get js code from a file (uncompressed) + """ + import webnotes + from webnotes.modules import scrub, get_file_timestamp + + src_file_name = fn + '.' + extn + + # src_timestamp = get_file_timestamp(src_file_name) + + # if no source, return + #if not src_timestamp: + # return '' + + # if timestamps are not same, compress + #if src_timestamp != get_file_timestamp(comp_file_name): + # compress(src_file_name, comp_file_name) + + # get the code + try: + file = open(src_file_name, 'r') + except IOError, e: + return '' + + code = file.read() + file.close() + + # return + return code + +# get doctype client +#============================================================================== + +def sub_get_doctype_js(match): + name = match.group('name') + return get_doctype_js(name) + +def get_doctype_js(dt): + """ + Returns the client-side (js) code of the DocType. + Adds custom script + and replaces $import(dt) with the code of that DocType + """ + import webnotes, os + from webnotes.modules import scrub, get_module_path + from webnotes.model.code import get_custom_script + + module = scrub(webnotes.conn.get_value('DocType',dt,'module')) + + code = get_js_code(os.path.join(get_module_path(scrub(module)), 'doctype', scrub(dt), scrub(dt))) \ + + '\n' + (get_custom_script(dt, 'Client') or '') + + # compile for import + if code.strip(): + import re + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + + code = p.sub(sub_get_doctype_js, code) + + return code + +# get page client +#============================================================================== + +def sub_get_page_js(match): + from webnotes.model.doc import Document + + name = match.group('name') + + if '.' in name: + name = name.split('.') + return get_page_js(name[1], name[0]) + + return get_page_js(Document('Page', name)) + +def get_page_js(page, module=None): + """ + Returns the js code of a page. Will replace $import (page) or $import(module.page) + with the code from the file + """ + import webnotes, os + from webnotes.modules import scrub, get_module_path + + if type(page)==str: + page_name = page + else: + page_name, module = page.name, page.module + + code = get_js_code(os.path.join(get_module_path(module), 'page', scrub(page_name), scrub(page_name))) + + if not code and type(page)!=str: + code = page.script + + # compile for import + if code and code.strip(): + import re + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + + code = p.sub(sub_get_page_js, code) + + return code + + +# compress +#============================================================================== + +def compress(src, comp): + out = open(comp, 'w') + + jsm = JavascriptMinify() + jsm.minify(open(src,'r'), out) + + out.close() + + + + +#============================================================================== +#============================================================================== +# +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/export_module.py b/cgi-bin/webnotes/modules/export_module.py new file mode 100644 index 0000000000..b1232bd316 --- /dev/null +++ b/cgi-bin/webnotes/modules/export_module.py @@ -0,0 +1,237 @@ +# ============================================================================== +# export to files +# ============================================================================== + +updated_modules = [] + +from webnotes.modules import scrub, get_module_path + +def export_to_files(modules = [], record_list=[], from_db=None, from_ac=None, verbose=1, record_module=None): + # Multiple doctype and multiple modules export to be done + # for Module Def, right now using a hack..should consider table update in the next version + # all modules transfer not working, because source db not known + # get the items + + global updated_modules + + if from_ac or from_db: + init_db_login(from_ac, from_db) + + out = [] + import webnotes.model.doc + module_doclist =[] + if record_list: + for record in record_list: + module_doclist.append([d.fields for d in webnotes.model.doc.get(record[0], record[1])]) + + # build the doclist + if modules: + for m in modules: + module_doclist +=get_module_doclist(m) + + # write files + for doclist in module_doclist: + if verbose: + out.append("Writing for " + doclist[0]['doctype'] + " / " + doclist[0]['name']) + write_document_file(doclist, record_module) + + # write out attachments + for m in modules: + write_attachments(m) + + return out + +# ============================================================================== +# write module.info file with last updated timestamp +# ============================================================================== + +def write_attachments(m): + import webnotes, os + from webnotes.utils.file_manager import get_file + + try: + fl = webnotes.conn.sql("select name from `tabFile Data` where module=%s", m) + except Exception, e: + if e.args[0]==1054: # no field called module + return + else: + raise e + + # write the files + if fl: + folder = os.path.join(webnotes.defs.modules_path, m, 'files') + webnotes.create_folder(folder) + for f in fl: + file_det = get_file(f) + file = open(os.path.join(folder, file_det[0]), 'w+') + file.write(file_det[1]) + file.close() + + +# ============================================================================== +# write module.info file with last updated timestamp +# ============================================================================== + +def write_module_info(mod): + import webnotes.utils, os + + file = open(os.path.join(get_module_path(mod), 'module.info'), 'w') + file.write(str({'update_date': webnotes.utils.now()})) + file.close() + +# ============================================================================== +# prepare a list of items in a module +# ============================================================================== + +def get_module_items(mod): + import webnotes + from webnotes.modules import transfer_types + from webnotes.modules import scrub + + dl = [] + for dt in transfer_types: + try: + dl2 = webnotes.conn.sql('select name, modified from `tab%s` where module="%s"' % (dt,mod)) + for e in dl2: + dl += [dt + ',' + e[0] + ',0'] + + if e[0] == 'Control Panel': + dl += [e[0]+','+e[0]+',1'] + except: + pass + dl1 = webnotes.conn.sql('select doctype_list from `tabModule Def` where name=%s', mod) + dl1 = dl1 and dl1[0][0] or '' + if dl1: + dl1 = dl1.split('\n') + dl += [t+',1' for t in dl1] + dl += ['Module Def,'+mod+',0'] + # build finally + dl = [e.split(',') for e in dl] + dl = [[e[0].strip(), e[1].strip(), e[2]] for e in dl] # remove blanks + return dl + + +# ============================================================================== +# build a list of doclists of items in that module and send them +# ============================================================================== + +def get_module_doclist(module): + import webnotes + import webnotes.model.doc + item_list = get_module_items(module) + + # build the super_doclist + super_doclist = [] + for i in item_list: + dl = webnotes.model.doc.get(i[0], i[1]) + if i[2]=='1': + dl[0].module = module + # remove compiled code (if any) + if dl[0].server_code_compiled: + dl[0].server_code_compiled = None + + # add to super + super_doclist.append([d.fields for d in dl]) + + return super_doclist + +# ============================================================================== +# Create __init__.py files +# ============================================================================== + +def create_init_py(modules_path, dt, dn): + import os + from webnotes.modules import scrub + + # in module + if not '__init__.py' in os.listdir(modules_path): + open(os.path.join(modules_path, '__init__.py'), 'w').close() + + # in type and name folders + if dt in ['doctype', 'page', 'search_criteria']: + if not '__init__.py' in os.listdir(os.path.join(modules_path, dt)): + open(os.path.join(modules_path, dt, '__init__.py'), 'w').close() + + if not '__init__.py' in os.listdir(os.path.join(modules_path, dt, dn)): + open(os.path.join(modules_path, dt, dn, '__init__.py'), 'w').close() + + +# ============================================================================== +# Create module folders +# ============================================================================== + +def create_folder(module, dt, dn): + import webnotes, os + + # get module path by importing the module + modules_path = get_module_path(module) + + code_type = dt in ['DocType', 'Page', 'Search Criteria'] + + # create folder + folder = os.path.join(modules_path, code_type and scrub(dt) or dt, code_type and scrub(dn) or dn) + + webnotes.create_folder(folder) + + # create init_py_files + if code_type: + create_init_py(modules_path, scrub(dt), scrub(dn)) + + return folder + +# ============================================================================== +# Write doclist into file +# ============================================================================== + +def write_document_file(doclist, record_module=None): + import os + from webnotes.utils import pprint_dict + + global updated_modules + + # module name + if doclist[0]['doctype'] == 'Module Def': + module = doclist[0]['name'] + elif doclist[0]['doctype']=='Control Panel': + module = 'System' + elif record_module: + module = record_module + else: + module = doclist[0]['module'] + + updated_modules.append(module) + + # create the folder + code_type = doclist[0]['doctype'] in ['DocType','Page','Search Criteria'] + + # create folder + folder = create_folder(module, doclist[0]['doctype'], doclist[0]['name']) + + # separate code files + clear_code_fields(doclist, folder, code_type) + + # write the data file + fname = (code_type and scrub(doclist[0]['name'])) or doclist[0]['name'] + dict_list = [pprint_dict(d) for d in doclist] + + txtfile = open(os.path.join(folder, fname +'.txt'),'w+') + txtfile.write('[\n' + ',\n'.join(dict_list) + '\n]') + txtfile.close() + + +# ============================================================================== +# Create seperate files for code +# ============================================================================== + +def clear_code_fields(doclist, folder, code_type): + + import os + import webnotes + # code will be in the parent only + code_fields = webnotes.code_fields_dict.get(doclist[0]['doctype'], []) + + for code_field in code_fields: + if doclist[0].get(code_field[0]): + + doclist[0][code_field[0]] = None + diff --git a/cgi-bin/webnotes/modules/import_module.py b/cgi-bin/webnotes/modules/import_module.py new file mode 100644 index 0000000000..d0cb048bdd --- /dev/null +++ b/cgi-bin/webnotes/modules/import_module.py @@ -0,0 +1,278 @@ +""" +Imports Documents from modules (.txt) files in the filesystem +""" + +import webnotes + +# +# imports / updates all files in a module into the database +# +def import_module(module, verbose=0): + "imports the all the records and files from the given module" + from webnotes.modules import get_module_path + import os + + not_module = ('startup', 'event_handlers', 'files', 'patches') + if module in not_module: + if verbose: webnotes.msgprint('%s is not a module' % module) + return + + path = get_module_path(module) + + doctypes = listfolders(path, 1) + if 'doctype' in doctypes: + doctypes.remove('doctype') + doctypes = ['doctype'] + doctypes + + for doctype in doctypes: + for docname in listfolders(os.path.join(path, doctype), 1): + import_file(module, doctype, docname, path) + if verbose: webnotes.msgprint('Imported %s/%s/%s' % (module, doctype, docname)) + + import_attachments(module) + +# +# get doclist from file +# +def get_doclist(path, doctype, docname): + "returns a doclist (list of dictionaries) of multiple records for the given parameters" + import os + do_not_import = ('control_panel') + + fname = os.path.join(path,doctype,docname,docname+'.txt') + if os.path.exists(fname) and (doctype not in do_not_import): + f = open(fname,'r') + dl = eval(f.read()) + f.close() + return dl + else: + return None + +# +# import a file into the database +# +def import_file(module, doctype, docname, path=None): + "imports a given file into the database" + + if not path: + from webnotes.modules import get_module_path + path = get_module_path(module) + + doclist = get_doclist(path, doctype, docname) + + if doclist: + from webnotes.utils.transfer import set_doc + set_doc(doclist, 1, 1, 1) + +# +# list folders in a dir +# +def listfolders(path, only_name=0): + """returns the list of folders (with paths) in the given path, + if only_name is set, it returns only the folder names""" + + import os + out = [] + for each in os.listdir(path): + dirname = each.split(os.path.sep)[-1] + fullpath = os.path.join(path, dirname) + + if os.path.isdir(fullpath) and not dirname.startswith('.'): + out.append(only_name and dirname or fullname) + return out + + + + + + + +# ============================================================================== +# Import from files +# ============================================================================= +def import_from_files(modules = [], record_list = [], sync_cp = 0, target_db=None, target_ac=None): + + if target_db or target_ac: + init_db_login(target_ac, target_db) + + from webnotes.utils import transfer + # Get paths of folder which will be imported + folder_list = get_folder_paths(modules, record_list) + ret = [] + + if folder_list: + # get all doclist + all_doclist = get_all_doclist(folder_list) + + # import doclist + ret += accept_module(all_doclist) + + # import attachments + for m in modules: + import_attachments(m) + + # sync control panel + if sync_cp: + ret.append(sync_control_panel()) + else: + ret.append("Module/Record not found") + + return ret + + +# ============================================================================== +# Get list of folder path +# ============================================================================= +# record_list in format [[module,dt,dn], ..] +def get_folder_paths(modules, record_list): + import os + import webnotes + import fnmatch + import webnotes.defs + from webnotes.modules import transfer_types, get_module_path, scrub + + folder_list=[] + + # get the folder list + if record_list: + for record in record_list: + if scrub(record[1]) in ('doctype', 'page', 'search_criteria'): + record[1], record[2] = scrub(record[1]), scrub(record[2]) + + folder_list.append(os.path.join(get_module_path(scrub(record[0])), \ + record[1], record[2].replace('/','_'))) + + if modules: + # system modules will be transferred in a predefined order and before all other modules + sys_mod_ordered_list = ['roles', 'core','application_internal', 'mapper', 'settings'] + all_mod_ordered_list = [t for t in sys_mod_ordered_list if t in modules] + list(set(modules).difference(sys_mod_ordered_list)) + + for module in all_mod_ordered_list: + mod_path = get_module_path(module) + types_list = listfolders(mod_path, 1) + + # list of types + types_list = list(set(types_list).difference(['control_panel'])) + all_transfer_types =[t for t in transfer_types if t in types_list] + list(set(types_list).difference(transfer_types)) + + # build the folders + for d in all_transfer_types: + if d not in ('files', 'startup', 'patches'): + # get all folders inside type + folder_list+=listfolders(os.path.join(mod_path, d)) + + return folder_list + + +# ============================================================================== +# Get doclist for all folder +# ============================================================================= + + +def get_all_doclist(folder_list): + import fnmatch + import os + + doclist = [] + all_doclist = [] + + # build into doclist + for folder in folder_list: + # get the doclist + file_list = os.listdir(folder) + for each in file_list: + + if fnmatch.fnmatch(each,'*.txt'): + doclist = eval(open(os.path.join(folder,each),'r').read()) + # add code + all_doclist.append(doclist) + + return all_doclist + + +# ============================================================================== +# accept a module coming from a remote server +# ============================================================================== +def accept_module(super_doclist): + import webnotes + import webnotes.utils + from webnotes.utils import transfer + msg, i = [], 0 + + for dl in super_doclist: + if dl[0]['doctype']!='Control Panel': + msg.append(transfer.set_doc(dl, 1, 1, 1)) + + if dl[0]['doctype']=='Module Def': + update_module_timestamp(dl[0]['name']) + + if not webnotes.conn.in_transaction: + webnotes.conn.sql("START TRANSACTION") + + # clear cache + webnotes.conn.sql("DELETE from __DocTypeCache") + webnotes.conn.sql("COMMIT") + + return msg + +# ============================================================================= +# Update timestamp in Module Def table +# ============================================================================= +def update_module_timestamp(mod): + import webnotes, webnotes.defs, os + + try: + file = open(os.path.join(webnotes.defs.modules_path, mod, 'module.info'), 'r') + except Exception, e: + if e.args[0]==2: + return # module.info + else: + raise e + + module_info = eval(file.read()) + file.close() + +# ============================================================================= + +def update_module_timestamp_query(mod, timestamp): + import webnotes + webnotes.conn.sql("start transaction") + webnotes.conn.sql("update `tabModule Def` set last_updated_date=%s where name=%s", (timestamp, mod)) + webnotes.conn.sql("commit") + + +# ============================================================================= +# Import Attachments +# ============================================================================= + +def import_attachments(m): + import os, webnotes.defs + import webnotes.utils.file_manager + from webnotes.modules import get_module_path + + out = [] + + # get list + try: + folder = os.path.join(get_module_path(m), 'files') + fl = os.listdir(folder) + except OSError, e: + if e.args[0]==2: + return + else: + raise e + + # import files + for f in fl: + if not os.path.isdir(os.path.join(folder, f)): + # delete + webnotes.utils.file_manager.delete_file(f) + + # import + file = open(os.path.join(folder, f),'r') + webnotes.utils.file_manager.save_file(f, file.read(), m) + file.close() + + out.append(f) + + return out diff --git a/cgi-bin/webnotes/modules/module_manager.py b/cgi-bin/webnotes/modules/module_manager.py new file mode 100644 index 0000000000..90679df0b2 --- /dev/null +++ b/cgi-bin/webnotes/modules/module_manager.py @@ -0,0 +1,187 @@ +#============================================================================== +# script to change the module name in the database & update svn +#============================================================================== + +def change_module(dt, dn, from_module, to_module): + import os, webnotes.defs + from webnotes.modules import scrub + + # change in db + webnotes.conn.sql("update `tab%s` set module=%s where name=%s" % (dt, '%s', '%s'), (to_module, dn)) + + # export files + from webnotes.modules.export_module import export_to_files + export_to_files(record_list = [[dt, dn]]) + + if dt in ['DocType','Page','Search Criteria']: + dt, dn = scrub(dt), scrub(dn) + + # svn add + webnotes.msgprint(os.popen("svn add %s" % os.path.join(webnotes.defs.modules_path, scrub(to_module), dt, dn)).read()) + + # svn remove + webnotes.msgprint(os.popen("svn remove %s" % os.path.join(webnotes.defs.modules_path, scrub(from_module), dt, dn)).read()) + + + +#============================================================================== +# SYNC +#============================================================================== +def reload_doc(module, dt, dn): + "alias for webnotes.modules.import_module.import_file" + from webnotes.modules.import_module import import_file + + import_file(module, dt, dn) + +# +# get list of doctypes and their last update times +# +def get_doc_list(dt): + """ + returns the list of records and their last update times from the table + if the column _last_update does not exist, it will add it to the table + """ + + import webnotes + module = dt=='Module Def' and 'name' or 'module' + q = "select %s, name, _last_update from `tab%s`" % (module, dt) + try: + return webnotes.conn.sql(q) + except Exception, e: + if e.args[0]==1054: + webnotes.conn.commit() + webnotes.conn.sql("alter table `tab%s` add column _last_update varchar(32)" % dt) + webnotes.conn.begin() + return webnotes.conn.sql(q) + elif e.args[0]==1146: + return [] + else: + raise e + +# +# sync dt +# +def sync_one_doc(d, dt, ts): + import webnotes + from webnotes.model.db_schema import updatedb + reload_doc(d[0], dt, d[1]) + + # update schema(s) + if dt=='DocType': + updatedb(d[1]) + webnotes.conn.sql("update `tab%s` set _last_update=%s where name=%s" % (dt, '%s', '%s'), (ts, d[1])) + +# +# sync doctypes, mappers and +# +def sync_meta(): + import webnotes, os + from webnotes.modules import scrub, get_module_path + from webnotes.utils import cint + + tl = ['DocType', 'DocType Mapper', 'Module Def'] + + for dt in tl: + dtl = get_doc_list(dt) + + for d in filter(lambda x: x[0], dtl): + try: + ndt, ndn = dt, d[1] + if dt == 'DocType': + ndt, ndn = scrub(dt), scrub(d[1]) + + mp = get_module_path(scrub(d[0])) + ts = cint(os.stat(os.path.join(mp, ndt, ndn, ndn + '.txt')).st_mtime) + + if d[2] != str(ts): + sync_one_doc(d, dt, ts) + except OSError, e: + pass + + + + + + +#============================================================================== + +def get_module_details(m): + from export_module import get_module_items + return {'in_files': get_module_items_from_files(m), \ + 'in_system':[[i[0], i[1], get_modified(i[0], i[1])] for i in get_module_items(m)]} + +#============================================================================== + +def get_modified(dt, dn): + import webnotes + try: + return str(webnotes.conn.sql("select modified from `tab%s` where replace(name,' ','_')=%s" % (dt,'%s'), dn)[0][0]) + except: + pass + +#============================================================================== + +def get_module_items_from_files(m): + import os, webnotes.defs + from import_module import listfolders + + items = [] + for item_type in listfolders(os.path.join(webnotes.defs.modules_path, m), 1): + for item_name in listfolders(os.path.join(webnotes.defs.modules_path, m, item_type), 1): + # read the file + file = open(os.path.join(webnotes.defs.modules_path, m, item_type, item_name, item_name)+'.txt','r') + doclist = eval(file.read()) + file.close() + + # append + items.append([item_type, item_name, doclist[0]['modified']]) + + return items + +#============================================================================== + +def get_last_update_for(mod): + import webnotes + try: + return webnotes.conn.sql("select last_updated_date from `tabModule Def` where name=%s", mod)[0][0] + except: + return '' + +#============================================================================== + +def init_db_login(ac_name, db_name): + import webnotes + import webnotes.db + import webnotes.profile + + if ac_name: + webnotes.conn = webnotes.db.Database(ac_name = ac_name) + webnotes.conn.use(webnotes.conn.user) + elif db_name: + webnotes.conn = webnotes.db.Database(user=db_name) + webnotes.conn.use(db_name) + else: + webnotes.conn = webnotes.db.Database(use_default=1) + + webnotes.session = {'user':'Administrator'} + webnotes.user = webnotes.profile.Profile() + +#============================================================================== +# Return module names present in File System +#============================================================================== +def get_modules_from_filesystem(): + import os, webnotes.defs + from import_module import listfolders + + modules = listfolders(webnotes.defs.modules_path, 1) + out = [] + modules.sort() + modules = filter(lambda x: x!='patches', modules) + + for m in modules: + file = open(os.path.join(webnotes.defs.modules_path, m, 'module.info'), 'r') + out.append([m, eval(file.read()), get_last_update_for(m), \ + webnotes.conn.exists('Module Def',m) and 'Installed' or 'Not Installed']) + file.close() + + return out \ No newline at end of file diff --git a/cgi-bin/webnotes/modules/patch.py b/cgi-bin/webnotes/modules/patch.py new file mode 100644 index 0000000000..401510b3c2 --- /dev/null +++ b/cgi-bin/webnotes/modules/patch.py @@ -0,0 +1,36 @@ +# patch manager + +def run(log_exception=1): + import webnotes + from patches import patch + from webnotes.utils import cint + + next_patch = cint(webnotes.conn.get_global('next_patch')) + + if next_patch <= patch.last_patch: + for i in range(next_patch, patch.last_patch+1): + webnotes.conn.begin() + if log_exception: + try: + patch.execute(i) + except Exception, e: + write_log() + return + else: + patch.execute(i) + + webnotes.conn.set_global('next_patch', str(i+1)) + webnotes.conn.commit() + +def write_log(): + import os + import webnotes.defs + import webnotes + + patch_log = open(os.path.join(webnotes.defs.modules_path, 'patches', 'patch.log'), 'a') + patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback()) + patch_log.close() + + webnotes.msgprint("There were errors in running patches, please call the Administrator") + + diff --git a/cgi-bin/webnotes/multi_tenant/__init__.py b/cgi-bin/webnotes/multi_tenant/__init__.py new file mode 100644 index 0000000000..f29b0ef95a --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/__init__.py @@ -0,0 +1 @@ +shared_tables = ['DocType','DocPerm','DocField','Role','Print Format','Module Def'] diff --git a/cgi-bin/webnotes/multi_tenant/query_parser.py b/cgi-bin/webnotes/multi_tenant/query_parser.py new file mode 100644 index 0000000000..2bbf7447e2 --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/query_parser.py @@ -0,0 +1,38 @@ +import sqlparse +import webnotes +import webnotes.query_parser + +def get_tables(parsed): + start = 0 + for t in parsed[0].tokens: + if str(t.ttype)=='Token.Keyword' and t.value.lower()=='from': + start = 1 + if start and type(t).__name__=='Identifier': + return [(str(t.get_real_name())),] + + if start and type(t).__name__=='IdentifierList': + return [str(i.get_real_name()) for i in t.get_identifiers()] + + return tl + +def add_condition(query): + parsed = sqlparse.parse(query) + + # get the tables + tl = get_tables(parsed) + + # rebuild the query till the where clause + q = '' + for t in parsed[0].tokens: + q += str(t) + + # where clause comes here + if type(t).__name__=='Where': + + # add the conditions for the tables + for t in tl: + if t not in webnotes.query_parser.shared_tables: + q += ' and %s._tenant_id=%s' % (t, webnotes.tenant_id) + + return q + diff --git a/cgi-bin/webnotes/multi_tenant/setup.py b/cgi-bin/webnotes/multi_tenant/setup.py new file mode 100644 index 0000000000..5d9b9e3bd5 --- /dev/null +++ b/cgi-bin/webnotes/multi_tenant/setup.py @@ -0,0 +1,19 @@ +import webnotes + +# setup all tables for multi-tenant +# --------------------------------- +def setup_tables(): + import webnotes.multi_tenant + + tl = webnotes.conn.sql("show tables") + for t in tl: + add_tenant_id(t[0]) + change_primary_key(t[0]) + +def add_tenant_id(tname): + webnotes.conn.sql("alter table `%s` add column _tenant_id int(10) default 0 not null") + +def change_primary_key(tname): + webnotes.conn.sql("alter table `%s` drop primary key name") + webnotes.conn.sql("alter table `%s` add primary key (name, _tenant_id)") + diff --git a/cgi-bin/webnotes/profile.py b/cgi-bin/webnotes/profile.py new file mode 100644 index 0000000000..b20c93282e --- /dev/null +++ b/cgi-bin/webnotes/profile.py @@ -0,0 +1,239 @@ +import webnotes + +class Profile: + """ + A profile object is created at the beginning of every request with details of the use. + The global profile object is `webnotes.user` + """ + def __init__(self, name=''): + self.name = name or webnotes.session.get('user') + self.roles = [] + + self.can_create = [] + self.can_read = [] + self.can_write = [] + self.can_get_report = [] + + def _load_roles(self): + res = webnotes.conn.sql('select role from tabUserRole where parent = "%s"' % self.name) + self.roles = [] + for t in res: + if t[0]: self.roles.append(t[0]) + if webnotes.session.get('user') == 'Guest': + self.roles.append('Guest') + else: + self.roles.append('All') + + return self.roles + + def get_roles(self): + """ + get list of roles + """ + if self.roles: + return self.roles + + return self._load_roles() + + def get_allow_list(self, key): + """ + Internal - get list of DocType where `key` is allowed. Key is either 'read', 'write' or 'create' + """ + conn = webnotes.conn + roles = self.get_roles() + return [r[0] for r in conn.sql('SELECT DISTINCT t1.parent FROM `tabDocPerm` t1, tabDocType t2 WHERE t1.`%s`=1 AND t1.parent not like "old_parent:%%" AND t1.parent = t2.name AND IFNULL(t2.istable,0) = 0 AND t1.role in ("%s") order by t1.parent' % (key, '", "'.join(roles)))] + + def get_create_list(self): + """ + Get list of DocTypes the user can create. Will filter DocTypes tagged with 'not_in_create' and table + """ + cl = self.get_allow_list('create') + conn = webnotes.conn + no_create_list = [r[0] for r in conn.sql('select name from tabDocType where ifnull(in_create,0)=1 or ifnull(istable,0)=1 or ifnull(issingle,0)=1')] + self.can_create = filter(lambda x: x not in no_create_list, cl) + return self.can_create + + def get_read_list(self): + """ + Get list of DocTypes the user can read + """ + self.can_read = list(set(self.get_allow_list('read') + self.get_allow_list('write'))) + return self.can_read + + def get_report_list(self): + + conn = webnotes.conn + + # get all tables list + res = conn.sql('SELECT parent, options from tabDocField where fieldtype="Table"') + table_types, all_tabletypes = {}, [] + + # make a dictionary fo all table types + for t in res: + all_tabletypes.append(t[1]) + if not table_types.has_key(t[0]): + table_types[t[0]] = [] + table_types[t[0]].append(t[1]) + + no_search_list = [r[0] for r in conn.sql('SELECT name FROM tabDocType WHERE read_only = 1 ORDER BY name')] + # make the lists + for f in self.can_read: + tl = table_types.get(f, None) + if tl: + for t in tl: + if t and (not t in self.can_get_report) and (not t in no_search_list): + self.can_get_report.append(t) + + if f and (not f in self.can_get_report) and (not f in no_search_list): + self.can_get_report.append(f) + + return self.can_get_report + + def get_write_list(self): + """ + Get list of DocTypes the user can write + """ + self.can_write = self.get_allow_list('write') + return self.can_write + + def get_home_page(self): + """ + Get the name of the user's home page from the `Control Panel` + """ + try: + hpl = webnotes.conn.sql("select role, home_page from `tabDefault Home Page` where parent='Control Panel' order by idx asc") + for h in hpl: + if h[0] in self.get_roles(): + return h[1] + except: + pass + return webnotes.conn.get_value('Control Panel',None,'home_page') + + def get_defaults(self): + """ + Get the user's default values based on user and role profile + """ + roles = self.get_roles() + [self.name] + res = webnotes.conn.sql('select defkey, defvalue from `tabDefaultValue` where parent in ("%s")' % '", "'.join(roles)) + + self.defaults = {'owner': [self.name,]} + + for rec in res: + if not self.defaults.has_key(rec[0]): + self.defaults[rec[0]] = [] + self.defaults[rec[0]].append(rec[1] or '') + + return self.defaults + + def get_hide_tips(self): + try: + return webnotes.conn.sql("select hide_tips from tabProfile where name=%s", self.name)[0][0] or 0 + except: + return 0 + + def get_random_password(self): + """ + Generate a random password + """ + import string + from random import choice + + size = 9 + pwd = ''.join([choice(string.letters + string.digits) for i in range(size)]) + return pwd + + def reset_password(self): + """ + Reset the user's password and send an email + """ + pwd = self.get_random_password() + + # get profile + profile = webnotes.conn.sql("SELECT name, email, first_name, last_name FROM tabProfile WHERE name=%s OR email=%s",(self.name, self.name)) + + if not profile: + raise Exception, "Profile %s not found" % self.name + + # update tab Profile + webnotes.conn.sql("UPDATE tabProfile SET password=password(%s) WHERE name=%s", (pwd, profile[0][0])) + + self.send_email("Password Reset", "

Dear %s%s,

your password has been changed to %s

[Automatically Generated]

" % (profile[0][2], (profile[0][3] and (' ' + profile[0][3]) or ''), pwd), profile[0][1]) + + def send_email(self, subj, mess, email): + import webnotes.utils.email_lib + + webnotes.utils.email_lib.sendmail(email, msg=mess, subject=subj) + + # update recent documents + def update_recent(self, dt, dn): + """ + Update the user's `Recent` list with the given `dt` and `dn` + """ + conn = webnotes.conn + + # get list of child tables, so we know what not to add in the recent list + child_tables = [t[0] for t in conn.sql('select name from tabDocType where istable = 1')] + if not (dt in ['Print Format', 'Start Page', 'Event', 'ToDo Item', 'Search Criteria']) and not webnotes.is_testing and not (dt in child_tables): + r = webnotes.conn.sql("select recent_documents from tabProfile where name=%s", self.name)[0][0] or '' + new_str = dt+'~~~'+dn + '\n' + if new_str in r: + r = r.replace(new_str, '') + + self.recent = new_str + r + + if len(self.recent.split('\n')) > 50: + self.recent = '\n'.join(self.recent.split('\n')[:50]) + + webnotes.conn.sql("update tabProfile set recent_documents=%s where name=%s", (self.recent, self.name)) + + def load_profile(self): + """ + Return a dictionary of user properites to be stored in the session + """ + t = webnotes.conn.sql('select email, first_name, last_name, recent_documents from tabProfile where name = %s', self.name)[0] + + d = {} + d['name'] = self.name + d['email'] = t[0] or '' + d['first_name'] = t[1] or '' + d['last_name'] = t[2] or '' + d['recent'] = t[3] or '' + + d['hide_tips'] = self.get_hide_tips() + + d['roles'] = self.get_roles() + d['defaults'] = self.get_defaults() + + d['can_create'] = self.get_create_list() + d['can_read'] = self.get_read_list() + d['can_write'] = self.get_write_list() + d['can_get_report'] = self.get_report_list() + + return d + + def load_from_session(self, d): + """ + Setup the user profile from the dictionary saved in the session (generated by `load_profile`) + """ + self.can_create = d['can_create'] + self.can_read = d['can_read'] + self.can_write = d['can_write'] + self.can_get_report = d['can_get_report'] + + self.roles = d['roles'] + self.defaults = d['defaults'] + +def get_user_img(): + if not webnotes.form.getvalue('username'): + webnotes.response['message'] = 'no_img_m' + return + + f = webnotes.conn.sql("select file_list from tabProfile where name=%s", webnotes.form.getvalue('username','')) + if f: + if f[0][0]: + lst = f[0][0].split('\n') + webnotes.response['message'] = lst[0].split(',')[1] + else: + webnotes.response['message'] = 'no_img_m' + else: + webnotes.response['message'] = 'no_img_m' diff --git a/cgi-bin/webnotes/session_cache.py b/cgi-bin/webnotes/session_cache.py new file mode 100644 index 0000000000..70e539e91f --- /dev/null +++ b/cgi-bin/webnotes/session_cache.py @@ -0,0 +1,183 @@ +# session_cache.py + +# clear cache +# ================================================== + +def clear(): + clear_cache() + + import webnotes + webnotes.response['message'] = "Cache Cleared" + +def clear_cache(user=''): + import webnotes + try: + if user: + webnotes.conn.sql("delete from __SessionCache where user=%s", user) + else: + webnotes.conn.sql("delete from __SessionCache") + except Exception, e: + if e.args[0]==1146: + make_cache_table() + else: + raise e + +# load cache +# ================================================== + +def get(): + import webnotes + import webnotes.defs + + + # get country + country = webnotes.session['data'].get('ipinfo', {}).get('countryName', 'Unknown Country') + + # run patches + try: + import webnotes.modules.patch + webnotes.modules.patch.run() + except ImportError, e: + pass # no patches - do nothing + + # check if cache exists + if not getattr(webnotes.defs,'auto_cache_clear',None): + cache = load(country) + if cache: + return cache + + # if not create it + sd = build() + dump(sd, country) + + # update profile from cache + webnotes.session['data']['profile'] = sd['profile'] + + return sd + +# load cache +# ================================================== + +def load(country): + import webnotes + + try: + sd = webnotes.conn.sql("select cache from __SessionCache where user='%s' %s" % (webnotes.session['user'], (country and (" and country='%s'" % country) or ''))) + if sd: + return eval(sd[0][0]) + else: + return None + except Exception, e: + if e.args[0]==1146: + make_cache_table() + else: + raise e + +# make the cache table +# ================================================== + +def make_cache_table(): + import webnotes + webnotes.conn.commit() + webnotes.conn.sql("create table `__SessionCache` (user VARCHAR(120), country VARCHAR(120), cache LONGTEXT)") + webnotes.conn.begin() + +# dump session to cache +# ================================================== + +def dump(sd, country): + import webnotes + import webnotes.model.doclist + + if sd.get('docs'): + sd['docs'] = webnotes.model.doclist.compress(sd['docs']) + + # delete earlier (?) + webnotes.conn.sql("delete from __SessionCache where user=%s and country=%s", (webnotes.session['user'], country)) + + # make new + webnotes.conn.sql("insert into `__SessionCache` (user, country, cache) VALUES (%s, %s, %s)", (webnotes.session['user'], country, str(sd))) + +# ================================================== + +def get_letter_heads(): + import webnotes + try: + lh = {} + ret = webnotes.conn.sql("select name, content from `tabLetter Head` where ifnull(disabled,0)=0") + for r in ret: + lh[r[0]] = r[1] + return lh + except Exception, e: + if e.args[0]==1146: + return {} + else: + raise Exception, e + +# ================================================== +# load startup.js and startup.css from the modules/startup folder + +def load_startup(cp): + from webnotes.modules import compress + + try: from webnotes.defs import modules_path + except ImportError: return + + import os + + try: + cp.startup_code = compress.get_js_code(os.path.join(modules_path, 'startup', 'startup')) + startup_css = open(os.path.join(modules_path, 'startup', 'startup.css'), 'r') + cp.startup_css = startup_css.read() + startup_css.close() + except IOError, e: + if e.args[0]!=2: # no startup module! + raise e + +# build it +# ================================================== + +def build(): + sd = {} + + import webnotes + import webnotes.model + import webnotes.model.doc + import webnotes.model.doctype + import webnotes.widgets.page + import webnotes.widgets.menus + import webnotes.profile + import webnotes.defs + + sql = webnotes.conn.sql + + webnotes.conn.begin() + sd['profile'] = webnotes.user.load_profile() + + doclist = [] + doclist += webnotes.model.doc.get('Control Panel') + cp = doclist[0] + load_startup(cp) + + doclist += webnotes.model.doctype.get('Event') + doclist += webnotes.model.doctype.get('Search Criteria') + home_page = webnotes.user.get_home_page() + + if home_page: + doclist += webnotes.widgets.page.get(home_page) + + sd['account_name'] = cp.account_id or '' + sd['sysdefaults'] = webnotes.utils.get_defaults() + sd['n_online'] = int(sql("SELECT COUNT(DISTINCT user) FROM tabSessions")[0][0] or 0) + sd['docs'] = doclist + sd['letter_heads'] = get_letter_heads() + sd['home_page'] = home_page or '' + sd['start_items'] = webnotes.widgets.menus.get_menu_items() + if webnotes.session['data'].get('ipinfo'): + sd['ipinfo'] = webnotes.session['data']['ipinfo'] + + webnotes.session['data']['profile'] = sd['profile'] + sd['dt_labels'] = webnotes.model.get_dt_labels() + webnotes.conn.commit() + + return sd diff --git a/cgi-bin/webnotes/settings/__init__.py b/cgi-bin/webnotes/settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/settings/account_map_template.py b/cgi-bin/webnotes/settings/account_map_template.py new file mode 100644 index 0000000000..dd634cd2ba --- /dev/null +++ b/cgi-bin/webnotes/settings/account_map_template.py @@ -0,0 +1,10 @@ +# Account/Domain Name to Database Mapping file +# -------------------------------------------- +# last updated on: 2011-02-02 14:31:14 + +default_db_name = "webnotesdb" + +db_name_map = {'wnframework':'webnotesdb'} +#{'main_acc_name';'db_name'} +domain_name_map = {'localhost':'webnotesdb'} + diff --git a/cgi-bin/webnotes/utils/__init__.py b/cgi-bin/webnotes/utils/__init__.py new file mode 100644 index 0000000000..c40b9cab24 --- /dev/null +++ b/cgi-bin/webnotes/utils/__init__.py @@ -0,0 +1,550 @@ +# util __init__.py + +import webnotes + +user_time_zone = None +month_name = ['','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] +month_name_full = ['','January','February','March','April','May','June','July','August','September','October','November','December'] +no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image', 'Graph'] +default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus'] + +def getCSVelement(v): + """ + Returns the CSV value of `v`, For example: + + * apple becomes "apple" + * hi"there becomes "hi""there" + """ + v = cstr(v) + if not v: return '' + if (',' in v) or ('\n' in v) or ('"' in v): + if '"' in v: v = v.replace('"', '""') + return '"'+v+'"' + else: return v or '' + +def validate_email_add(email_str): + """ + Validates the email string + """ + s = email_str + if '<' in s: + s = s.split('<')[1].split('>')[0] + if s: s = s.strip().lower() + import re + #return re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email_str) + return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", s) + +def sendmail(recipients, sender='', msg='', subject='[No Subject]', parts=[], cc=[], attach=[]): + """ + Send an email. For more details see :func:`email_lib.sendmail` + """ + import webnotes.utils.email_lib + return email_lib.sendmail(recipients, sender, msg, subject, parts, cc, attach) + +def generate_hash(): + """ + Generates reandom hash for session id + """ + import sha, time + return sha.new(str(time.time())).hexdigest() + +def db_exists(dt, dn): + return webnotes.conn.sql('select name from `tab%s` where name="%s"' % (dt, dn)) + +def load_json(arg): + + # already a dictionary? + if type(arg)!=str: + return arg + + try: import json + except: import simplejson as json + + #return json.loads(unicode(arg, 'iso-8859-15')) + return json.loads(arg) + +# Get Traceback +# ============================================================================== + +def getTraceback(): + """ + Returns the traceback of the Exception + """ + import sys, traceback, string + type, value, tb = sys.exc_info() + + body = "Traceback (innermost last):\n" + list = traceback.format_tb(tb, None) + traceback.format_exception_only(type, value) + body = body + "%-20s %s" % (string.join(list[:-1], ""), list[-1]) + + if webnotes.logger: + webnotes.logger.error('Db:'+(webnotes.conn and webnotes.conn.cur_db_name or '') + ' - ' + body) + + return body + +# Log +# ============================================================================== + +def log(event, details): + webnotes.logger.info(details) + +# Date and Time +# ============================================================================== + + +def getdate(string_date): + """ + Coverts string date (yyyy-mm-dd) to datetime.date object + """ + import datetime + + if type(string_date)==unicode: + string_date = str(string_date) + + if type(string_date) in (datetime.datetime, datetime.date): + return string_date + + if ' ' in string_date: + string_date = string_date.split(' ')[0] + t = string_date.split('-') + if len(t)==3: + return datetime.date(cint(t[0]), cint(t[1]), cint(t[2])) + else: + return '' + +def add_days(date, days): + """ + Adds `days` to the given `string_date` + """ + import datetime + if not date: + date = now_datetime() + + if type(date) not in (datetime.datetime, datetime.date): + date = getdate(date) + + return (date + datetime.timedelta(days)).strftime('%Y-%m-%d') + +def add_months(string_date, months): + import datetime + return webnotes.conn.sql("select DATE_ADD('%s',INTERVAL '%s' MONTH)" % (getdate(string_date),months))[0][0] + +def add_years(string_date, years): + import datetime + return webnotes.conn.sql("select DATE_ADD('%s',INTERVAL '%s' YEAR)" % (getdate(string_date),years))[0][0] + +def date_diff(string_ed_date, string_st_date=None): + import datetime + return webnotes.conn.sql("SELECT DATEDIFF('%s','%s')" %(getdate(string_ed_date), getdate(string_st_date)))[0][0] + +def now_datetime(): + global user_time_zone + from datetime import datetime + from pytz import timezone + + # get localtime + if not user_time_zone: + user_time_zone = webnotes.conn.get_value('Control Panel', None, 'time_zone') or 'Asia/Calcutta' + + # convert to UTC + utcnow = timezone('UTC').localize(datetime.utcnow()) + + # convert to user time zone + return utcnow.astimezone(timezone(user_time_zone)) + +def now(): + """ + Returns `time.strftime('%Y-%m-%d %H:%M:%S')` + """ + return now_datetime().strftime('%Y-%m-%d %H:%M:%S') + +def nowdate(): + """ + Returns time.strftime('%Y-%m-%d') + """ + return now_datetime().strftime('%Y-%m-%d') + +def get_first_day(dt, d_years=0, d_months=0): + """ + Returns the first day of the month for the date specified by date object + Also adds `d_years` and `d_months` if specified + """ + import datetime + # d_years, d_months are "deltas" to apply to dt + y, m = dt.year + d_years, dt.month + d_months + a, m = divmod(m-1, 12) + return datetime.date(y+a, m+1, 1) + +def get_last_day(dt): + """ + Returns last day of the month using: + `get_first_day(dt, 0, 1) + datetime.timedelta(-1)` + """ + import datetime + return get_first_day(dt, 0, 1) + datetime.timedelta(-1) + +user_format = None +""" + User format specified in :term:`Control Panel` + + Examples: + + * dd-mm-yyyy + * mm-dd-yyyy + * dd/mm/yyyy +""" + +def formatdate(string_date): + """ + Convers the given string date to :data:`user_format` + """ + global user_format + if not user_format: + user_format = webnotes.conn.get_value('Control Panel', None, 'date_format') + d = string_date.split('-'); + out = user_format + return out.replace('dd', ('%.2i' % cint(d[2]))).replace('mm', ('%.2i' % cint(d[1]))).replace('yyyy', d[0]) + +def dict_to_str(args, sep='&'): + """ + Converts a dictionary to URL + """ + import urllib + t = [] + for k in args.keys(): + t.append(str(k)+'='+urllib.quote(str(args[k] or ''))) + return sep.join(t) + +def timestamps_equal(t1, t2): + """Returns true if same the two string timestamps are same""" + scrub = lambda x: x.replace(':', ' ').replace('-',' ').split() + + t1, t2 = scrub(t1), scrub(t2) + + if len(t1) != len(t2): + return + + for i in range(len(t1)): + if t1[i]!=t2[i]: + return + return 1 + +def global_date_format(date): + import datetime + + if type(date) in (str, unicode): + date = getdate(date) + + return date.strftime('%d') + ' ' + month_name_full[int(date.strftime('%m'))] + ' ' + date.strftime('%Y') + + + + +# Datatype +# ============================================================================== + +def isNull(v): + """ + Returns true if v='' or v is `None` + """ + return (v=='' or v==None) + +def has_common(l1, l2): + """ + Returns true if there are common elements in lists l1 and l2 + """ + for l in l1: + if l in l2: + return 1 + return 0 + +def flt(s): + """ + Convert to float (ignore commas) + """ + if type(s)==str: # if string + s = s.replace(',','') + try: tmp = float(s) + except: tmp = 0 + return tmp + +def cint(s): + """ + Convert to integer + """ + try: tmp = int(float(s)) + except: tmp = 0 + return tmp + +def cstr(s): + """ + Convert to string + """ + if s==None: + return '' + else: + if hasattr(s, 'encode'): + try: + s = s.encode('utf-8', 'ignore') + except: + pass + return str(s) + +def str_esc_quote(s): + """ + Escape quotes + """ + if s==None:return '' + return s.replace("'","\'") + +def replace_newlines(s): + """ + Replace newlines by '
' + """ + if s==None:return '' + return s.replace("\n","
") + + +# ============================================================================== + +def parse_val(v): + """ + Converts to simple datatypes from SQL query results + """ + import datetime + + try: import decimal # for decimal Python 2.5 (?) + except: pass + + if type(v)==datetime.date: + v = str(v) + elif type(v)==datetime.timedelta: + v = ':'.join(str(v).split(':')[:2]) + elif type(v)==datetime.datetime: + v = str(v) + elif type(v)==long: v=int(v) + + try: + if type(v)==decimal.Decimal: v=float(v) + except: pass + + return v + +# ============================================================================== + +def fmt_money(amount, fmt = '%.2f'): + """ + Convert to string with commas for thousands, millions etc + """ + curr = webnotes.conn.get_value('Control Panel', None, 'currency_format') or 'Millions' + + val = 2 + if curr == 'Millions': val = 3 + + if cstr(amount).find('.') == -1: temp = '00' + else: temp = cstr(amount).split('.')[1] + + l = [] + minus = '' + if flt(amount) < 0: minus = '-' + + amount = ''.join(cstr(amount).split(',')) + amount = cstr(abs(flt(amount))).split('.')[0] + + # main logic + if len(cstr(amount)) > 3: + nn = amount[len(amount)-3:] + l.append(nn) + amount = amount[0:len(amount)-3] + while len(cstr(amount)) > val: + nn = amount[len(amount)-val:] + l.insert(0,nn) + amount = amount[0:len(amount)-val] + + if len(amount) > 0: l.insert(0,amount) + + amount = ','.join(l)+'.'+temp + amount = minus + amount + return amount + +# +# convet currency to words +# +def money_in_words(number, main_currency = None, fraction_currency=None): + """ + Returns string in words with currency and fraction currency. + """ + + d = get_defaults() + if not main_currency: + main_currency = d.get('currency', 'INR') + if not fraction_currency: + fraction_currency = d.get('fraction_currency', 'paise') + + n = str(flt(number)) + main, fraction = n.split('.') + if len(fraction)==1: fraction += '0' + + out = main_currency + ' ' + in_words(main).title() + if cint(fraction): + out = out + ' and ' + in_words(fraction).title() + ' ' + fraction_currency + + return out + ' only.' + +# +# convert number to words +# +def in_words(integer): + """ + Returns string in words for the given integer. + """ + + in_million = webnotes.conn.get_value('Control Panel',None,'currency_format')=='Millions' and 1 or 0 + + + n=int(integer) + known = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', + 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', + 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'} + + def psn(n, known, xpsn): + import sys; + if n in known: return known[n] + bestguess, remainder = str(n), 0 + + if n<=20: + print >>sys.stderr, n, "How did this happen?" + assert 0 + elif n < 100: + bestguess= xpsn((n//10)*10, known, xpsn) + '-' + xpsn(n%10, known, xpsn) + return bestguess + elif n < 1000: + bestguess= xpsn(n//100, known, xpsn) + ' ' + 'hundred' + remainder = n%100 + else: + if in_million: + if n < 1000000: + bestguess= xpsn(n//1000, known, xpsn) + ' ' + 'thousand' + remainder = n%1000 + elif n < 1000000000: + bestguess= xpsn(n//1000000, known, xpsn) + ' ' + 'million' + remainder = n%1000000 + else: + bestguess= xpsn(n//1000000000, known, xpsn) + ' ' + 'billion' + remainder = n%1000000000 + else: + if n < 100000: + bestguess= xpsn(n//1000, known, xpsn) + ' ' + 'thousand' + remainder = n%1000 + elif n < 10000000: + bestguess= xpsn(n//100000, known, xpsn) + ' ' + 'lakh' + remainder = n%100000 + else: + bestguess= xpsn(n//10000000, known, xpsn) + ' ' + 'crore' + remainder = n%10000000 + if remainder: + if remainder >= 100: + comma = ',' + else: + comma = '' + return bestguess + comma + ' ' + xpsn(remainder, known, xpsn) + else: + return bestguess + + return psn(n, known, psn) + + +# Get Defaults +# ============================================================================== + +def get_defaults(key=None): + """ + Get dictionary of default values from the :term:`Control Panel`, or a value if key is passed + """ + if key: + res = webnotes.conn.sql('select defvalue from `tabDefaultValue` where parent = "Control Panel" where defkey=%s', key) + return res and res[0][0] or None + else: + res = webnotes.conn.sql('select defkey, defvalue from `tabDefaultValue` where parent = "Control Panel"') + d = {} + for rec in res: + d[rec[0]] = rec[1] or '' + return d + +def set_default(key, val): + """ + Set / add a default value to :term:`Control Panel` + """ + res = webnotes.conn.sql('select defkey from `tabDefaultValue` where defkey="%s" and parent = "Control Panel"' % key) + if res: + webnotes.conn.sql('update `tabDefaultValue` set defvalue="%s" where parent = "Control Panel" and defkey="%s"' % (val, key)) + else: + from webnotes.model.doc import Document + d = Document('DefaultValue') + d.parent = 'Control Panel' + d.parenttype = 'Control Panel' + d.parentfield = 'system_defaults' + d.defkey = key + d.defvalue = val + d.save(1) + +# +# Clear recycle bin +# +def clear_recycle_bin(): + sql = webnotes.conn.sql + + tl = sql('show tables') + total_deleted = 0 + for t in tl: + fl = [i[0] for i in sql('desc `%s`' % t[0])] + + if 'name' in fl: + total_deleted += sql("select count(*) from `%s` where name like '__overwritten:%%'" % t[0])[0][0] + sql("delete from `%s` where name like '__overwritten:%%'" % t[0]) + + if 'parent' in fl: + total_deleted += sql("select count(*) from `%s` where parent like '__oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like '__oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'oldparent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'oldparent:%%'" % t[0]) + + total_deleted += sql("select count(*) from `%s` where parent like 'old_parent:%%'" % t[0])[0][0] + sql("delete from `%s` where parent like 'old_parent:%%'" % t[0]) + + return "%s records deleted" % str(int(total_deleted)) + + +# Send Error Report +# ============================================================================== + +def send_error_report(): + sql = webnotes.conn.sql + m = '' + acc_id = webnotes.conn.get_value('Control Panel',None,'account_id') or '' + if acc_id: m = 'Account Id : '+acc_id + form = webnotes.form + err_msg = ''' + %s
+ Comment: %s + Err Msg : %s + ''' % (m, form.getvalue('msg') or '', form.getvalue('err_msg')) + sendmail([webnotes.conn.get_value('Control Panel',None,'support_email_id') or 'support@iwebnotes.com'], sender=webnotes.session['user'], msg=err_msg, subject='Error Report '+m) + +# pretty print a dict +# ============================================================================== + +def pprint_dict(d, level=1): + indent = '' + for i in range(0,level): + indent += '\t' + lines = [] + kl = d.keys() + kl.sort() + for key in kl: + tmp = {key: d[key]} + lines.append(indent + str(tmp)[1:-1] ) + return indent + '{\n' \ + + indent + ',\n\t'.join(lines) \ + + '\n' + indent + '}' diff --git a/cgi-bin/webnotes/utils/archive.py b/cgi-bin/webnotes/utils/archive.py new file mode 100644 index 0000000000..de945f58d6 --- /dev/null +++ b/cgi-bin/webnotes/utils/archive.py @@ -0,0 +1,107 @@ +import webnotes + +sql = webnotes.conn.sql + +# main function +# ------------------------- + +def archive_doc(doctype, name, restore=0): + archive_record(doctype, name, restore) + + tables = sql("select options from tabDocField where parent=%s and fieldtype='Table'", doctype) + for t in tables: + try: + rec_list = sql("select name from `%s%s` where parent=%s" % ((restore and 'arc' or 'tab') ,t[0], '%s'), name) + except Exception,e: + if e.args[0]==1146: # no child table + rec_list = [] + else: + raise e + + for r in rec_list: + archive_record(t[0], r[0], restore) + +# archive individual record +# ------------------------- + +def archive_record(doctype, name, restore = 0): + src_tab = (restore and 'arc' or 'tab') + doctype + tar_tab = (restore and 'tab' or 'arc') + doctype + + # get the record + try: + rec = sql("select * from `%s` where name=%s for update" % (src_tab, '%s'), name, as_dict=1)[0] + except Exception, e: + if e.args[0]==1146: + return # source table does not exist + else: + raise e + + # insert the record + insert_record(doctype, tar_tab, name) + + # put it field by field (ignore missing columns) + for field in rec.keys(): + if rec.get(field): + update_value(src_tab, tar_tab, name, rec, field) + + # delete from main + try: + sql("delete from `%s` where name=%s limit 1" % (src_tab, '%s'), name) + except Exception, e: + if e.args[0]==1451: + webnotes.msgprint("Cannot archive %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name)) + + # delete from target, as it will create a double copy! + sql("delete from `%s` where name=%s limit 1" % (tar_tab, '%s'), name) + +# insert the record +# ------------------------- + +def insert_record_name(tab, name): + sql("insert ignore into `%s` (name) values (%s)" % (tab, '%s'), name) + +# insert record +# ------------------------- + +def insert_record(doctype, tar_tab, name): + try: + insert_record_name(tar_tab, name) + except Exception, e: + if e.args[0]==1146: + # missing table - create it + from webnotes.model.db_schema import updatedb + updatedb(doctype, 1) + + # again + insert_record_name(tar_tab, name) + else: + raise e + +# update single value +# ------------------------- + +def update_single_value(tab, field, value, name): + sql("update `%s` set `%s`=%s where name=%s" % (tab, field, '%s', '%s'), (value, name)) + + +# update value +# ------------------------- + +def update_value(src_tab, tar_tab, name, rec, field): + try: + update_single_value(tar_tab, field, rec[field], name) + except Exception, e: + if e.args[0]==1054: + # column missing.... add it? + ftype = sql("show columns from `%s` like '%s'" % (src_tab, field))[0][1] + + webnotes.conn.commit() # causes implict commit + sql("alter table `%s` add column `%s` %s" % (tar_tab, field, ftype)) + webnotes.conn.begin() + + # again + update_single_value(tar_tab, field, rec[field], name) + else: + raise e + diff --git a/cgi-bin/webnotes/utils/backups.py b/cgi-bin/webnotes/utils/backups.py new file mode 100644 index 0000000000..804750fa29 --- /dev/null +++ b/cgi-bin/webnotes/utils/backups.py @@ -0,0 +1,107 @@ +import webnotes + +backup_folder = '/backups' +mysql_path = '' +download_folder = 'backups' + +def mysqldump(db, folder=''): + global mysql_path + import os + import webnotes.defs + + os.system('%(path)smysqldump %(db)s > %(folder)s%(db)s.sql -u %(db)s -p%(pwd)s --ignore-table=%(db)s.__DocTypeCache' % {'path':mysql_path, 'db':db, 'pwd':webnotes.defs.db_password, 'folder':folder}) + +def backup_db(db, conn, from_all=0): + import os + global backup_folder + + try: + # Check processlist + if from_all or len(conn.sql("show processlist")) == 1: + p = backup_folder + if from_all: p = backup_folder + '/dumps' + + # clear old file + os.system('rm %s/%s.tar.gz' % (p,db)) + + # dump + mysqldump(db, p+'/') + + # zip + os.system('tar czf %s/%s.tar.gz %s/%s.sql' % (p, db, p, db)) + os.system('rm %s/%s.sql' % (p, db)) + else: + print("Another process is running in database. Please try again") + except Exception, e: + #sql('unlock tables') + raise e + +def backup_all(): + # backups folder + import os + import webnotes.db + global backup_folder + + conn = webnotes.db.Database(use_default=1) + dblist = conn.sql('select db_name from tabAccount') + + # backup -all in /backups folder + for d in (('accounts',),) + dblist: + backup_db(d[0], conn, 1) + + conn.close() + + # dump all in /daily folder + import time, datetime + fname = 'daily-' + time.strftime('%Y-%m-%d') + '.tar.gz' + + # daily dump + os.system('tar czf %s/daily/%s %s/dumps' % (backup_folder, fname, backup_folder)) + + # keep only three files + if len(os.listdir(backup_folder + '/daily')) > 3: + delete_oldest_file(backup_folder + '/daily') + + # if sunday, then copy to weekly + if datetime.datetime.now().weekday()==6: + os.system('cp '+backup_folder+'/daily/'+fname+' '+backup_folder+'/weekly/'+fname) + + # keep only three files + if len(os.listdir(backup_folder + '/weekly')) > 3: + delete_oldest_file(backup_folder + '/weekly') + +def delete_oldest_file(folder): + import os + a = sorted(os.listdir(folder), key=lambda fn: os.stat(folder+'/'+fn).st_mtime, reverse=False) + if a: + os.system('rm %s/%s' % (folder, a[0])) + +def get_backup(): + import webnotes + import os, time + + global backup_folder, download_folder + + # get the last nightly backup file from the backups folder + os.chdir(download_folder) + + if webnotes.conn.cur_db_name: + fname = webnotes.conn.cur_db_name + '.tar.gz' + + # rename it + from random import choice + lnd='0123456789' + new_name = ''.join(map(lambda x,y=lnd: choice(y), range(8))) + '.sql.gz' + folder = backup_folder + '/dumps/' + + # get the newest file + if os.path.exists(folder): + os.system('cp '+ folder + webnotes.conn.cur_db_name+'.sql.gz' + ' ./' + new_name) + webnotes.msgprint('Your nightly backup is available for download by clicking here (only for the next few hours)') + + # delete any files older than a day + now = time.time() + for f in os.listdir('.'): + if os.stat(f).st_mtime < (now - 86400): + if os.path.isfile(f): + os.remove(f) diff --git a/cgi-bin/webnotes/utils/cache.py b/cgi-bin/webnotes/utils/cache.py new file mode 100644 index 0000000000..a77427eada --- /dev/null +++ b/cgi-bin/webnotes/utils/cache.py @@ -0,0 +1,57 @@ +""" +Simple Caching: + +Stores key-value pairs in database and enables simple caching + +get_item(key).get() returns the cached value if not expired (else returns null) +get_item(key).set(interval = 60000) sets a value to cache, expiring after x seconds +get_item(key).clear() clears an old value +setup() sets up cache +""" + +import webnotes + +class CacheItem: + def __init__(self, key): + """create a new cache""" + self.key = key + + def get(self): + """get value""" + try: + return webnotes.conn.sql("select `value` from __CacheItem where `key`=%s and expires_on > NOW()", self.key)[0][0] + except Exception: + return None + + def set(self, value, interval=6000): + """set a new value, with interval""" + try: + self.clear() + webnotes.conn.sql("""INSERT INTO + __CacheItem (`key`, `value`, expires_on) + VALUES + (%s, %s, addtime(now(), sec_to_time(%s))) + """, (self.key, str(value), interval)) + except Exception, e: + if e.args[0]==1146: + setup() + self.set(value, interval) + else: raise e + + def clear(self): + """clear the item""" + webnotes.conn.sql("delete from __CacheItem where `key`=%s", self.key) + +def setup(): + webnotes.conn.commit() + webnotes.conn.sql("""create table __CacheItem( + `key` VARCHAR(180) NOT NULL PRIMARY KEY, + `value` TEXT, + `expires_on` TIMESTAMP + )""") + webnotes.conn.begin() + +def get_item(key): + """returns get CacheItem object""" + return CacheItem(key) + pass \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/email_lib/__init__.py b/cgi-bin/webnotes/utils/email_lib/__init__.py new file mode 100644 index 0000000000..abda347923 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/__init__.py @@ -0,0 +1,88 @@ +import webnotes + +def sendmail_html(sender, recipients, subject, html, text=None, template=None, send_now=1, reply_to=None): + """ + Send an html mail with alternative text and using Page Templates + """ + sendmail(recipients, sender, html, subject, send_now = send_now, reply_to = reply_to, template = template) + +def make_html_body(content, template = None): + """ + Generate html content from a Page Template object + """ + template_html = '%(content)s' + + if template: + from webnotes.model.code import get_code + template_html = get_code(webnotes.conn.get_value('Page Template', template, 'module'), 'Page Template', template, 'html', fieldname='template') + + return template_html % {'content': content} + + +def sendmail(recipients, sender='', msg='', subject='[No Subject]', parts=[], cc=[], attach=[], send_now=1, reply_to=None, template=None): + """ + send an html email as multipart with attachments and all + """ + + from webnotes.utils.email_lib.html2text import html2text + from webnotes.utils.email_lib.send import EMail + + email = EMail(sender, recipients, subject, reply_to=reply_to) + email.cc = cc + + if msg: + if template: + msg = make_html_body(msg, template) + else: + # if not html, then lets put some whitespace + if (not '
' in msg) or (not '

' in msg): + msg = msg.replace('\n','
') + + footer = get_footer() + msg = msg + (footer or '') + email.set_text(html2text(msg)) + email.set_html(msg) + for p in parts: + email.set_message(p[1]) + for a in attach: + email.attach(a) + + email.send(send_now) + + +def get_footer(): + """ + Returns combination of footer from globals and Control Panel + """ + + footer = webnotes.conn.get_value('Control Panel',None,'mail_footer') or '' + footer += (webnotes.conn.get_global('global_mail_footer') or '') + return footer + + +def send_form(): + """ + Emails a print format (form) + Called from form UI + """ + + from webnotes.utils.email_lib.form_email import FormEmail + FormEmail().send() + + +def get_contact_list(): + """ + Returns contacts (from autosuggest) + """ + import webnotes + + cond = ['`%s` like "%s%%"' % (f, webnotes.form.getvalue('txt')) for f in webnotes.form.getvalue('where').split(',')] + cl = webnotes.conn.sql("select `%s` from `tab%s` where %s" % ( + webnotes.form.getvalue('select') + ,webnotes.form.getvalue('from') + ,' OR '.join(cond) + ) + ) + webnotes.response['cl'] = filter(None, [c[0] for c in cl]) + + diff --git a/cgi-bin/webnotes/utils/email_lib/form_email.py b/cgi-bin/webnotes/utils/email_lib/form_email.py new file mode 100644 index 0000000000..5bd3be8007 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/form_email.py @@ -0,0 +1,160 @@ +import webnotes +from webnotes.utils import cint + +form = webnotes.form + +from webnotes.utils.email_lib import get_footer +from webnotes.utils.email_lib.send import EMail + +class FormEmail: + """ + Represents an email sent from a Form + """ + def __init__(self): + """ + Get paramteres from the cgi form object + """ + self.__dict__.update(webnotes.form_dict) + + self.recipients = None + if self.sendto: + self.recipients = self.sendto.replace(';', ',') + self.recipients = self.recipients.split(',') + + def update_contacts(self): + """ + Add new email contact to database + """ + import webnotes + from webnotes.model.doc import Document + + for r in self.recipients: + r = r.strip() + try: + if not webnotes.conn.sql("select email_id from tabContact where email_id=%s", r): + d = Document('Contact') + d.email_id = r + d.save(1) + except Exception, e: + if e.args[0]==1146: pass # no table + else: raise e + + def make_full_links(self): + """ + Adds server name the relative links, so that images etc can be seen correctly + """ + # only domain + if not self.__dict__.get('full_domain'): + return + + def make_full_link(match): + import os + link = match.group('name') + if not link.startswith('http'): + link = os.path.join(self.full_domain, link) + return 'src="%s"' % link + + import re + p = re.compile('src[ ]*=[ ]*" (?P [^"]*) "', re.VERBOSE) + self.body = p.sub(make_full_link, self.body) + + p = re.compile("src[ ]*=[ ]*' (?P [^']*) '", re.VERBOSE) + self.body = p.sub(make_full_link, self.body) + + def get_form_link(self): + """ + Returns publicly accessible form link + """ + public_domain = webnotes.conn.get_value('Control Panel', None, 'public_domain') + from webnotes.utils.encrypt import encrypt + + if not public_domain: + return '' + + args = { + 'dt': self.dt, + 'dn':self.dn, + 'acx': webnotes.conn.get_value('Control Panel', None, 'account_id'), + 'server': public_domain, + 'akey': encrypt(self.dn) + } + return '

If you are unable to view the form below click here to see it in your browser
' % args + + def set_attachments(self): + """ + Set attachments to the email from the form + """ + al = [] + try: + al = webnotes.conn.sql('select file_list from `tab%s` where name="%s"' % (form.getvalue('dt'), form.getvalue('dn'))) + if al: + al = (al[0][0] or '').split('\n') + except Exception, e: + if e.args[0]==1146: + pass # no attachments in single types! + else: + raise Exception, e + return al + + def build_message(self): + """ + Builds the message object + """ + + self.email = EMail(self.sendfrom, self.recipients, self.subject, alternative = 1) + + from webnotes.utils.email_lib.html2text import html2text + + self.make_full_links() + + # message + if not self.__dict__.get('message'): + self.message = 'Please find attached %s: %s\n' % (self.dt, self.dn) + + html_message = text_message = self.message.replace('\n','
') + + # separator + html_message += '
' + + # form itself (only in the html message) + html_message += self.body + + # form link + html_message += self.get_form_link() + text_message += self.get_form_link() + + # footer + footer = get_footer() + if footer: + html_message += footer + text_message += footer + + # message as text + self.email.set_text(html2text(text_message)) + self.email.set_html(html_message) + + def send(self): + """ + Send the form with html attachment + """ + + if not self.recipients: + webnotes.msgprint('No one to send to!') + return + + self.build_message() + + # print format (as attachment also - for text-only clients) + self.email.add_attachment(self.dn.replace(' ','').replace('/','-') + '.html', self.body) + + # attachments + if cint(self.with_attachments): + for a in self.set_attachments(): + a and self.email.attach(a.split(',')[0]) + + # cc + if self.cc: + self.email.cc = [self.cc] + + self.email.send(send_now=1) + webnotes.msgprint('Sent') \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/email_lib/html2text.py b/cgi-bin/webnotes/utils/email_lib/html2text.py new file mode 100644 index 0000000000..66258d2477 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/html2text.py @@ -0,0 +1,491 @@ +#!/usr/bin/env python +"""html2text: Turn HTML into equivalent Markdown-structured text.""" +__version__ = "3.02" +__author__ = "Aaron Swartz (me@aaronsw.com)" +__copyright__ = "(C) 2004-2008 Aaron Swartz. GNU GPL 3." +__contributors__ = ["Martin 'Joey' Schulze", "Ricardo Reyes", "Kevin Jay North"] + +# TODO: +# Support decoded entities with unifiable. + +try: + True +except NameError: + setattr(__builtins__, 'True', 1) + setattr(__builtins__, 'False', 0) + +def has_key(x, y): + if hasattr(x, 'has_key'): return x.has_key(y) + else: return y in x + +try: + import htmlentitydefs + import urlparse + import HTMLParser +except ImportError: #Python3 + import html.entities as htmlentitydefs + import urllib.parse as urlparse + import html.parser as HTMLParser +try: #Python3 + import urllib.request as urllib +except: + import urllib +import optparse, re, sys, codecs, types + +try: from textwrap import wrap +except: pass + +# Use Unicode characters instead of their ascii psuedo-replacements +UNICODE_SNOB = 0 + +# Put the links after each paragraph instead of at the end. +LINKS_EACH_PARAGRAPH = 0 + +# Wrap long lines at position. 0 for no wrapping. (Requires Python 2.3.) +BODY_WIDTH = 78 + +# Don't show internal links (href="#local-anchor") -- corresponding link targets +# won't be visible in the plain text file anyway. +SKIP_INTERNAL_LINKS = False + +### Entity Nonsense ### + +def name2cp(k): + if k == 'apos': return ord("'") + if hasattr(htmlentitydefs, "name2codepoint"): # requires Python 2.3 + return htmlentitydefs.name2codepoint[k] + else: + k = htmlentitydefs.entitydefs[k] + if k.startswith("&#") and k.endswith(";"): return int(k[2:-1]) # not in latin-1 + return ord(codecs.latin_1_decode(k)[0]) + +unifiable = {'rsquo':"'", 'lsquo':"'", 'rdquo':'"', 'ldquo':'"', +'copy':'(C)', 'mdash':'--', 'nbsp':' ', 'rarr':'->', 'larr':'<-', 'middot':'*', +'ndash':'-', 'oelig':'oe', 'aelig':'ae', +'agrave':'a', 'aacute':'a', 'acirc':'a', 'atilde':'a', 'auml':'a', 'aring':'a', +'egrave':'e', 'eacute':'e', 'ecirc':'e', 'euml':'e', +'igrave':'i', 'iacute':'i', 'icirc':'i', 'iuml':'i', +'ograve':'o', 'oacute':'o', 'ocirc':'o', 'otilde':'o', 'ouml':'o', +'ugrave':'u', 'uacute':'u', 'ucirc':'u', 'uuml':'u'} + +unifiable_n = {} + +for k in unifiable.keys(): + unifiable_n[name2cp(k)] = unifiable[k] + +def charref(name): + if name[0] in ['x','X']: + c = int(name[1:], 16) + else: + c = int(name) + + if not UNICODE_SNOB and c in unifiable_n.keys(): + return unifiable_n[c] + else: + try: + return unichr(c) + except NameError: #Python3 + return chr(c) + +def entityref(c): + if not UNICODE_SNOB and c in unifiable.keys(): + return unifiable[c] + else: + try: name2cp(c) + except KeyError: return "&" + c + ';' + else: + try: + return unichr(name2cp(c)) + except NameError: #Python3 + return chr(name2cp(c)) + +def replaceEntities(s): + s = s.group(1) + if s[0] == "#": + return charref(s[1:]) + else: return entityref(s) + +r_unescape = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") +def unescape(s): + return r_unescape.sub(replaceEntities, s) + +### End Entity Nonsense ### + +def onlywhite(line): + """Return true if the line does only consist of whitespace characters.""" + for c in line: + if c is not ' ' and c is not ' ': + return c is ' ' + return line + +def optwrap(text): + """Wrap all paragraphs in the provided text.""" + if not BODY_WIDTH: + return text + + assert wrap, "Requires Python 2.3." + result = '' + newlines = 0 + for para in text.split("\n"): + if len(para) > 0: + if para[0] != ' ' and para[0] != '-' and para[0] != '*': + for line in wrap(para, BODY_WIDTH): + result += line + "\n" + result += "\n" + newlines = 2 + else: + if not onlywhite(para): + result += para + "\n" + newlines = 1 + else: + if newlines < 2: + result += "\n" + newlines += 1 + return result + +def hn(tag): + if tag[0] == 'h' and len(tag) == 2: + try: + n = int(tag[1]) + if n in range(1, 10): return n + except ValueError: return 0 + +class _html2text(HTMLParser.HTMLParser): + def __init__(self, out=None, baseurl=''): + HTMLParser.HTMLParser.__init__(self) + + if out is None: self.out = self.outtextf + else: self.out = out + try: + self.outtext = unicode() + except NameError: # Python3 + self.outtext = str() + self.quiet = 0 + self.p_p = 0 + self.outcount = 0 + self.start = 1 + self.space = 0 + self.a = [] + self.astack = [] + self.acount = 0 + self.list = [] + self.blockquote = 0 + self.pre = 0 + self.startpre = 0 + self.lastWasNL = 0 + self.abbr_title = None # current abbreviation definition + self.abbr_data = None # last inner HTML (for abbr being defined) + self.abbr_list = {} # stack of abbreviations to write later + self.baseurl = baseurl + + def outtextf(self, s): + self.outtext += s + + def close(self): + HTMLParser.HTMLParser.close(self) + + self.pbr() + self.o('', 0, 'end') + + return self.outtext + + def handle_charref(self, c): + self.o(charref(c)) + + def handle_entityref(self, c): + self.o(entityref(c)) + + def handle_starttag(self, tag, attrs): + self.handle_tag(tag, attrs, 1) + + def handle_endtag(self, tag): + self.handle_tag(tag, None, 0) + + def previousIndex(self, attrs): + """ returns the index of certain set of attributes (of a link) in the + self.a list + + If the set of attributes is not found, returns None + """ + if not has_key(attrs, 'href'): return None + + i = -1 + for a in self.a: + i += 1 + match = 0 + + if has_key(a, 'href') and a['href'] == attrs['href']: + if has_key(a, 'title') or has_key(attrs, 'title'): + if (has_key(a, 'title') and has_key(attrs, 'title') and + a['title'] == attrs['title']): + match = True + else: + match = True + + if match: return i + + def handle_tag(self, tag, attrs, start): + #attrs = fixattrs(attrs) + + if hn(tag): + self.p() + if start: self.o(hn(tag)*"#" + ' ') + + if tag in ['p', 'div']: self.p() + + if tag == "br" and start: self.o(" \n") + + if tag == "hr" and start: + self.p() + self.o("* * *") + self.p() + + if tag in ["head", "style", 'script']: + if start: self.quiet += 1 + else: self.quiet -= 1 + + if tag in ["body"]: + self.quiet = 0 # sites like 9rules.com never close + + if tag == "blockquote": + if start: + self.p(); self.o('> ', 0, 1); self.start = 1 + self.blockquote += 1 + else: + self.blockquote -= 1 + self.p() + + if tag in ['em', 'i', 'u']: self.o("_") + if tag in ['strong', 'b']: self.o("**") + if tag == "code" and not self.pre: self.o('`') #TODO: `` `this` `` + if tag == "abbr": + if start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + + self.abbr_title = None + self.abbr_data = '' + if has_key(attrs, 'title'): + self.abbr_title = attrs['title'] + else: + if self.abbr_title != None: + self.abbr_list[self.abbr_data] = self.abbr_title + self.abbr_title = None + self.abbr_data = '' + + if tag == "a": + if start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + if has_key(attrs, 'href') and not (SKIP_INTERNAL_LINKS and attrs['href'].startswith('#')): + self.astack.append(attrs) + self.o("[") + else: + self.astack.append(None) + else: + if self.astack: + a = self.astack.pop() + if a: + i = self.previousIndex(a) + if i is not None: + a = self.a[i] + else: + self.acount += 1 + a['count'] = self.acount + a['outcount'] = self.outcount + self.a.append(a) + self.o("][" + str(a['count']) + "]") + + if tag == "img" and start: + attrsD = {} + for (x, y) in attrs: attrsD[x] = y + attrs = attrsD + if has_key(attrs, 'src'): + attrs['href'] = attrs['src'] + alt = attrs.get('alt', '') + i = self.previousIndex(attrs) + if i is not None: + attrs = self.a[i] + else: + self.acount += 1 + attrs['count'] = self.acount + attrs['outcount'] = self.outcount + self.a.append(attrs) + self.o("![") + self.o(alt) + self.o("]["+ str(attrs['count']) +"]") + + if tag == 'dl' and start: self.p() + if tag == 'dt' and not start: self.pbr() + if tag == 'dd' and start: self.o(' ') + if tag == 'dd' and not start: self.pbr() + + if tag in ["ol", "ul"]: + if start: + self.list.append({'name':tag, 'num':0}) + else: + if self.list: self.list.pop() + + self.p() + + if tag == 'li': + if start: + self.pbr() + if self.list: li = self.list[-1] + else: li = {'name':'ul', 'num':0} + self.o(" "*len(self.list)) #TODO: line up
  1. s > 9 correctly. + if li['name'] == "ul": self.o("* ") + elif li['name'] == "ol": + li['num'] += 1 + self.o(str(li['num'])+". ") + self.start = 1 + else: + self.pbr() + + if tag in ["table", "tr"] and start: self.p() + if tag == 'td': self.pbr() + + if tag == "pre": + if start: + self.startpre = 1 + self.pre = 1 + else: + self.pre = 0 + self.p() + + def pbr(self): + if self.p_p == 0: self.p_p = 1 + + def p(self): self.p_p = 2 + + def o(self, data, puredata=0, force=0): + if self.abbr_data is not None: self.abbr_data += data + + if not self.quiet: + if puredata and not self.pre: + data = re.sub('\s+', ' ', data) + if data and data[0] == ' ': + self.space = 1 + data = data[1:] + if not data and not force: return + + if self.startpre: + #self.out(" :") #TODO: not output when already one there + self.startpre = 0 + + bq = (">" * self.blockquote) + if not (force and data and data[0] == ">") and self.blockquote: bq += " " + + if self.pre: + bq += " " + data = data.replace("\n", "\n"+bq) + + if self.start: + self.space = 0 + self.p_p = 0 + self.start = 0 + + if force == 'end': + # It's the end. + self.p_p = 0 + self.out("\n") + self.space = 0 + + + if self.p_p: + self.out(('\n'+bq)*self.p_p) + self.space = 0 + + if self.space: + if not self.lastWasNL: self.out(' ') + self.space = 0 + + if self.a and ((self.p_p == 2 and LINKS_EACH_PARAGRAPH) or force == "end"): + if force == "end": self.out("\n") + + newa = [] + for link in self.a: + if self.outcount > link['outcount']: + self.out(" ["+ str(link['count']) +"]: " + urlparse.urljoin(self.baseurl, link['href'])) + if has_key(link, 'title'): self.out(" ("+link['title']+")") + self.out("\n") + else: + newa.append(link) + + if self.a != newa: self.out("\n") # Don't need an extra line when nothing was done. + + self.a = newa + + if self.abbr_list and force == "end": + for abbr, definition in self.abbr_list.items(): + self.out(" *[" + abbr + "]: " + definition + "\n") + + self.p_p = 0 + self.out(data) + self.lastWasNL = data and data[-1] == '\n' + self.outcount += 1 + + def handle_data(self, data): + if r'\/script>' in data: self.quiet -= 1 + self.o(data, 1) + + def unknown_decl(self, data): pass + +def wrapwrite(text): + text = text.encode('utf-8') + try: #Python3 + sys.stdout.buffer.write(text) + except AttributeError: + sys.stdout.write(text) + +def html2text_file(html, out=wrapwrite, baseurl=''): + h = _html2text(out, baseurl) + h.feed(html) + h.feed("") + return h.close() + +def html2text(html, baseurl=''): + return optwrap(html2text_file(html, None, baseurl)) + +if __name__ == "__main__": + baseurl = '' + + p = optparse.OptionParser('%prog [(filename|url) [encoding]]', + version='%prog ' + __version__) + args = p.parse_args()[1] + if len(args) > 0: + file_ = args[0] + encoding = None + if len(args) == 2: + encoding = args[1] + if len(args) > 2: + p.error('Too many arguments') + + if file_.startswith('http://') or file_.startswith('https://'): + baseurl = file_ + j = urllib.urlopen(baseurl) + text = j.read() + if encoding is None: + try: + from feedparser import _getCharacterEncoding as enc + except ImportError: + enc = lambda x, y: ('utf-8', 1) + encoding = enc(j.headers, text)[0] + if encoding == 'us-ascii': + encoding = 'utf-8' + data = text.decode(encoding) + + else: + data = open(file_, 'rb').read() + if encoding is None: + try: + from chardet import detect + except ImportError: + detect = lambda x: {'encoding': 'utf-8'} + encoding = detect(data)['encoding'] + data = data.decode(encoding) + else: + data = sys.stdin.read() + wrapwrite(html2text(data, baseurl)) diff --git a/cgi-bin/webnotes/utils/email_lib/receive.py b/cgi-bin/webnotes/utils/email_lib/receive.py new file mode 100644 index 0000000000..3827fa46e3 --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/receive.py @@ -0,0 +1,142 @@ +""" + This module contains classes for managing incoming emails +""" + +class IncomingMail: + """ + Single incoming email object. Extracts, text / html and attachments from the email + """ + def __init__(self, content): + """ + Parse the incoming mail content + """ + import email + + self.mail = email.message_from_string(content) + self.text_content = '' + self.html_content = '' + self.attachments = [] + self.parse() + + def get_text_content(self): + """ + Returns the text parts of the email. If None, then HTML parts + """ + return self.text_content or self.html_content + + def get_charset(self, part): + """ + Guesses character set + """ + charset = part.get_content_charset() + if not charset: + import chardet + charset = chardet.detect(str(part))['encoding'] + + return charset + + def get_payload(self, part, charset): + """ + get utf-8 encoded part content + """ + return unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') + + def get_attachment(self, part, charset): + """ + Extracts an attachment + """ + self.attachments.append({ + 'content-type': part.get_content_type(), + 'filename': part.get_filename(), + 'content': self.get_payload(part, charset) + }) + + def parse(self): + """ + Extracts text, html and attachments from the mail + """ + for part in self.mail.walk(): + self.process_part(part) + + def get_thread_id(self): + """ + Extracts thread id of the message between first [] + from the subject + """ + subject = self.mail.get('Subject', '') + if '[' in subject and ']' in subject: + return subject.split('[')[1].split(']')[0] + + def process_part(self, part): + """ + Process a single part of an email + """ + charset = self.get_charset(part) + content_type = part.get_content_type() + + if content_type == 'text/plain': + self.text_content += self.get_payload(part, charset) + + if content_type == 'text/html': + self.html_content += self.get_payload(part, charset) + + if part.get_filename(): + self.get_attachment(part, charset) + +class POP3Mailbox: + """ + A simple pop3 mailbox, abstracts connection and mail extraction + To use, subclass it and override method process_message(from, subject, text, thread_id) + """ + + def __init__(self, settings_doc): + """ + settings_doc must contain + is_ssl, host, username, password + """ + from webnotes.model.doc import Document + self.settings = Document(settings_doc, settings_doc) + + def connect(self): + """ + Connects to the mailbox + """ + import poplib + + if self.settings.use_ssl: + self.pop = poplib.POP3_SSL(self.settings.host) + else: + self.pop = poplib.POP3(self.settings.host) + self.pop.user(self.settings.username) + self.pop.pass_(self.settings.password) + + + def get_messages(self): + """ + Loads messages from the mailbox and calls + process_message for each message + """ + + if not self.check_mails(): + return # nothing to do + + self.connect() + num = len(self.pop.list()[1]) + for m in range(num): + msg = self.pop.retr(m+1) + self.process_message(IncomingMail('\n'.join(msg[1]))) + self.pop.dele(m+1) + self.pop.quit() + + def check_mails(self): + """ + To be overridden + If mailbox is to be scanned, returns true + """ + return true + + def process_message(self, mail): + """ + To be overriden + """ + pass diff --git a/cgi-bin/webnotes/utils/email_lib/send.py b/cgi-bin/webnotes/utils/email_lib/send.py new file mode 100644 index 0000000000..2eff8ed9bc --- /dev/null +++ b/cgi-bin/webnotes/utils/email_lib/send.py @@ -0,0 +1,293 @@ +""" +Sends email via outgoing server specified in "Control Panel" +Allows easy adding of Attachments of "File" objects +""" + +import webnotes +import webnotes.defs +from webnotes import msgprint +import email + +class EMail: + """ + Wrapper on the email module. Email object represents emails to be sent to the client. + Also provides a clean way to add binary `FileData` attachments + Also sets all messages as multipart/alternative for cleaner reading in text-only clients + """ + def __init__(self, sender='', recipients=[], subject='', from_defs=0, alternative=0, reply_to=None): + from email.mime.multipart import MIMEMultipart + if type(recipients)==str: + recipients = recipients.replace(';', ',') + recipients = recipients.split(',') + + self.from_defs = from_defs + self.sender = sender + self.reply_to = reply_to or sender + self.recipients = recipients + self.subject = subject + + self.msg_root = MIMEMultipart('mixed') + self.msg_multipart = MIMEMultipart('alternative') + self.msg_root.attach(self.msg_multipart) + self.cc = [] + + def set_text(self, message): + """ + Attach message in the text portion of multipart/alternative + """ + from email.mime.text import MIMEText + part = MIMEText(message, 'plain') + self.msg_multipart.attach(part) + + def set_html(self, message): + """ + Attach message in the html portion of multipart/alternative + """ + from email.mime.text import MIMEText + part = MIMEText(message, 'html') + self.msg_multipart.attach(part) + + def set_message(self, message, mime_type='text/html', as_attachment=0, filename='attachment.html'): + """ + Append the message with MIME content to the root node (as attachment) + """ + from email.mime.text import MIMEText + + maintype, subtype = mime_type.split('/') + part = MIMEText(message, _subtype = subtype) + + if as_attachment: + part.add_header('Content-Disposition', 'attachment', filename=filename) + + self.msg_root.attach(part) + + def attach_file(self, n): + """ + attach a file from the `FileData` table + """ + from webnotes.utils.file_manager import get_file + res = get_file(n) + if not res: + return + + self.add_attachment(res[0], res[1]) + + def add_attachment(self, fname, fcontent, content_type=None): + + from email.mime.audio import MIMEAudio + from email.mime.base import MIMEBase + from email.mime.image import MIMEImage + from email.mime.text import MIMEText + + import mimetypes + + if not content_type: + content_type, encoding = mimetypes.guess_type(fname) + + if content_type is None: + # No guess could be made, or the file is encoded (compressed), so + # use a generic bag-of-bits type. + content_type = 'application/octet-stream' + + maintype, subtype = content_type.split('/', 1) + if maintype == 'text': + # Note: we should handle calculating the charset + part = MIMEText(fcontent, _subtype=subtype) + elif maintype == 'image': + part = MIMEImage(fcontent, _subtype=subtype) + elif maintype == 'audio': + part = MIMEAudio(fcontent, _subtype=subtype) + else: + part = MIMEBase(maintype, subtype) + part.set_payload(fcontent) + # Encode the payload using Base64 + from email import encoders + encoders.encode_base64(part) + + # Set the filename parameter + if fname: + part.add_header('Content-Disposition', 'attachment', filename=fname) + + self.msg_root.attach(part) + + def validate(self): + """ + validate the email ids + """ + if not self.sender: + self.sender = webnotes.conn.get_value('Control Panel',None,'auto_email_id') + + from webnotes.utils import validate_email_add + # validate ids + if self.sender and (not validate_email_add(self.sender)): + webnotes.msgprint("%s is not a valid email id" % self.sender, raise_exception = 1) + + if self.reply_to and (not validate_email_add(self.reply_to)): + webnotes.msgprint("%s is not a valid email id" % self.reply_to, raise_exception = 1) + + for e in self.recipients: + if not validate_email_add(e): + webnotes.msgprint("%s is not a valid email id" % e, raise_exception = 1) + + def setup(self): + """ + setup the SMTP (outgoing) server from `Control Panel` or defs.py + """ + if self.from_defs: + self.server = getattr(webnotes.defs,'mail_server','') + self.login = getattr(webnotes.defs,'mail_login','') + self.port = getattr(webnotes.defs,'mail_port',None) + self.password = getattr(webnotes.defs,'mail_password','') + self.use_ssl = getattr(webnotes.defs,'use_ssl',0) + + else: + import webnotes.model.doc + from webnotes.utils import cint + + # get defaults from control panel + cp = webnotes.model.doc.Document('Control Panel','Control Panel') + self.server = cp.outgoing_mail_server or getattr(webnotes.defs,'mail_server','') + self.login = cp.mail_login or getattr(webnotes.defs,'mail_login','') + self.port = cp.mail_port or getattr(webnotes.defs,'mail_port',None) + self.password = cp.mail_password or getattr(webnotes.defs,'mail_password','') + self.use_ssl = cint(cp.use_ssl) + + def make_msg(self): + self.msg_root['Subject'] = self.subject + self.msg_root['From'] = self.sender + self.msg_root['To'] = ', '.join([r.strip() for r in self.recipients]) + if self.reply_to and self.reply_to != self.sender: + self.msg_root['Reply-To'] = self.reply_to + if self.cc: + self.msg_root['CC'] = ', '.join([r.strip() for r in self.cc]) + + def add_to_queue(self): + # write to a file called "email_queue" or as specified in email + q = EmailQueue() + q.push({ + 'server': self.server, + 'port': self.port, + 'use_ssl': self.use_ssl, + 'login': self.login, + 'password': self.password, + 'sender': self.sender, + 'recipients': self.recipients, + 'msg': self.msg_root.as_string() + }) + q.close() + + def send(self, send_now = 0): + """ + send the message + """ + from webnotes.utils import cint + + self.setup() + self.validate() + self.make_msg() + + if (not send_now) and getattr(webnotes.defs, 'batch_emails', 0): + self.add_to_queue() + return + + import smtplib + sess = smtplib.SMTP(self.server, self.port or None) + + if self.use_ssl: + sess.ehlo() + sess.starttls() + sess.ehlo() + + ret = sess.login(self.login, self.password) + + # check if logged correctly + if ret[0]!=235: + msgprint(ret[1]) + raise Exception + + sess.sendmail(self.sender, self.recipients, self.msg_root.as_string()) + + try: + sess.quit() + except: + pass + + + + +# =========================================== +# Email Queue +# Maintains a list of emails in a file +# Flushes them when called from cron +# Defs settings: +# email_queue: (filename) [default: email_queue.py] +# +# From the scheduler, call: flush(qty) +# =========================================== + +class EmailQueue: + def __init__(self): + self.server = self.login = self.sess = None + self.filename = getattr(webnotes.defs, 'email_queue', 'email_queue.py') + + try: + f = open(self.filename, 'r') + self.queue = eval(f.read() or '[]') + f.close() + except IOError, e: + if e.args[0]==2: + self.queue = [] + else: + raise e + + def push(self, email): + self.queue.append(email) + + def close(self): + f = open(self.filename, 'w') + f.write(str(self.queue)) + f.close() + + def get_smtp_session(self, e): + if self.server==e['server'] and self.login==e['login'] and self.sess: + return self.sess + + webnotes.msgprint('getting server') + + import smtplib + + sess = smtplib.SMTP(e['server'], e['port'] or None) + + if self.use_ssl: + sess.ehlo() + sess.starttls() + sess.ehlo() + + ret = sess.login(e['login'], e['password']) + + # check if logged correctly + if ret[0]!=235: + webnotes.msgprint(ret[1]) + raise Exception + + self.sess = sess + self.server, self.login = e['server'], e['login'] + + return sess + + def flush(self, qty = 100): + f = open(self.filename, 'r') + + self.queue = eval(f.read() or '[]') + + if len(self.queue) < 100: + qty = len(self.queue) + + for i in range(qty): + e = self.queue[i] + sess = self.get_smtp_session(e) + sess.sendmail(e['sender'], e['recipients'], e['msg']) + + self.queue = self.queue[:(len(self.queue) - qty)] + self.close() + diff --git a/cgi-bin/webnotes/utils/encrypt.py b/cgi-bin/webnotes/utils/encrypt.py new file mode 100644 index 0000000000..80de8bf983 --- /dev/null +++ b/cgi-bin/webnotes/utils/encrypt.py @@ -0,0 +1,54 @@ +""" +XTEA Block Encryption Algorithm +Author: Paul Chakravarti (paul_dot_chakravarti_at_gmail_dot_com) +License: Public Domain +""" + +def get_key(): + # Encryption key is datetime of creation of DocType, DocType" + import webnotes + return webnotes.conn.sql("select creation from tabDocType where name='DocType'")[0][0].strftime('%Y%m%d%H%M%s')[:16] + +def encrypt(data, encryption_key = None): + if not encryption_key: + encryption_key = get_key() + return crypt(encryption_key, data).encode('hex') + +def decrypt(data, encryption_key = None): + if not encryption_key: + encryption_key = get_key() + return crypt(encryption_key, data.decode('hex')) + +def crypt(key,data,iv='\00\00\00\00\00\00\00\00',n=32): + def keygen(key,iv,n): + while True: + iv = xtea_encrypt(key,iv,n) + for k in iv: + yield ord(k) + xor = [ chr(x^y) for (x,y) in zip(map(ord,data),keygen(key,iv,n)) ] + return "".join(xor) + +def xtea_encrypt(key,block,n=32,endian="!"): + import struct + v0,v1 = struct.unpack(endian+"2L",block) + k = struct.unpack(endian+"4L",key) + sum,delta,mask = 0L,0x9e3779b9L,0xffffffffL + for round in range(n): + v0 = (v0 + (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & mask + sum = (sum + delta) & mask + v1 = (v1 + (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 3]))) & mask + return struct.pack(endian+"2L",v0,v1) + +def xtea_decrypt(key,block,n=32,endian="!"): + import struct + + v0,v1 = struct.unpack(endian+"2L",block) + k = struct.unpack(endian+"4L",key) + delta,mask = 0x9e3779b9L,0xffffffffL + sum = (delta * n) & mask + for round in range(n): + v1 = (v1 - (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 3]))) & mask + sum = (sum - delta) & mask + v0 = (v0 - (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & mask + return struct.pack(endian+"2L",v0,v1) + diff --git a/cgi-bin/webnotes/utils/file_manager.py b/cgi-bin/webnotes/utils/file_manager.py new file mode 100644 index 0000000000..26575ffd5f --- /dev/null +++ b/cgi-bin/webnotes/utils/file_manager.py @@ -0,0 +1,202 @@ +def upload(): + import webnotes + form = webnotes.form + + # get record details + dt = form.getvalue('doctype') + dn = form.getvalue('docname') + at_id = form.getvalue('at_id') + + # save + fid, fname = save_uploaded() + + if fid: + # refesh the form! + webnotes.response['result'] = """ + + """ % (dt, dn, fid, fname.replace("'", "\\'"), at_id, dt, dn) + +# ------------------------------------------------------- + +def make_thumbnail(blob, size): + from PIL import Image + import cStringIO + + fobj = cStringIO.StringIO(blob) + image = Image.open(fobj) + image.thumbnail((tn,tn*2), Image.ANTIALIAS) + outfile = cStringIO.StringIO() + image.save(outfile, 'JPEG') + outfile.seek(0) + fcontent = outfile.read() + + return fcontent + + +def save_uploaded(js_okay='window.parent.msgprint("File Upload Successful")', js_fail=''): + import webnotes + import webnotes.utils + + webnotes.response['type'] = 'iframe' + + form, fid, fname = webnotes.form, None, None + + try: + # has attachment? + if 'filedata' in form: + i = form['filedata'] + + fname, content = i.filename, i.file.read() + + # thumbnail + if webnotes.form_dict.get('thumbnail'): + try: + content = make_thumbnail(content, int(form.get('thumbnail'))) + # change extension to jpg + fname = '.'.join(fname.split('.')[:-1])+'.jpg' + except Exception, e: + pass + + # get the file id + fid = save_file(fname, content) + + # okay + webnotes.response['result'] = """""" % js_okay + else: + webnotes.response['result'] = """""" % js_fail + + except Exception, e: + webnotes.response['result'] = """""" % (str(e), webnotes.utils.getTraceback().replace('\n','
    ').replace('"', '\\"'), js_fail) + + return fid, fname + +# ------------------------------------------------------- + +def save_file(fname, content, module=None): + import webnotes + from webnotes.model.doc import Document + + # some browsers return the full path + if '\\' in fname: + fname = fname.split('\\')[-1] + if '/' in fname: + fname = fname.split('/')[-1] + + # generate the ID (?) + f = Document('File Data') + f.file_name = fname + if module: + f.module = module + f.save(1) + + write_file(f.name, content) + + return f.name + +# ------------------------------------------------------- + +def write_file(fid, content): + import webnotes, os, webnotes.defs + + # test size + max_file_size = 1000000 + if hasattr(webnotes.defs, 'max_file_size'): + max_file_size = webnotes.defs.max_file_size + + if len(content) > max_file_size: + raise Exception, 'Maximum File Limit (%s MB) Crossed' % (int(max_file_size / 1000000)) + + # no slashes + fid = fid.replace('/','-') + + # save to a folder (not accessible to public) + folder = webnotes.get_files_path() + + # create account folder (if not exists) + webnotes.create_folder(folder) + + # write the file + file = open(os.path.join(folder, fid),'w+') + file.write(content) + file.close() + + +# ------------------------------------------------------- +def get_file_system_name(fname): + # get system name from File Data table + import webnotes + return webnotes.conn.sql("select name, file_name from `tabFile Data` where name=%s or file_name=%s", (fname, fname)) + +# ------------------------------------------------------- +def delete_file(fname, verbose=0): + import webnotes, os + + for f in get_file_system_name(fname): + webnotes.conn.sql("delete from `tabFile Data` where name=%s", f[0]) + + # delete file + file_id = f[0].replace('/','-') + try: + os.remove(os.path.join(webnotes.get_files_path(), file_id)) + except OSError, e: + if e.args[0]!=2: + raise e + + if verbose: webnotes.msgprint('File Deleted') + +# Get File +# ------------------------------------------------------- + +def get_file(fname): + import webnotes + in_fname = fname + + # from the "File" table + if webnotes.conn.exists('File',fname): + fname = webnotes.conn.sql("select file_list from tabFile where name=%s", fname) + fname = fname and fname[0][0] + fname = fname.split('\n')[0].split(',')[1] + + + if get_file_system_name(fname): + f = get_file_system_name(fname)[0] + else: + f = None + + + # read the file + import os + + file_id = f[0].replace('/','-') + file = open(os.path.join(webnotes.get_files_path(), file_id), 'r') + content = file.read() + file.close() + return [f[1], content] + +# Conversion Patch +# ------------------------------------------------------- + +def convert_to_files(verbose=0): + import webnotes + + # nfiles + fl = webnotes.conn.sql("select name from `tabFile Data`") + for f in fl: + # get the blob + blob = webnotes.conn.sql("select blob_content from `tabFile Data` where name=%s", f[0])[0][0] + + if blob: + + if hasattr(blob, 'tostring'): + blob = blob.tostring() + + # write the file + write_file(f[0], blob) + + if verbose: + webnotes.msgprint('%s updated' % f[0]) + +# ------------------------------------------------------- diff --git a/cgi-bin/webnotes/utils/jsmin.py b/cgi-bin/webnotes/utils/jsmin.py new file mode 100644 index 0000000000..f0d45b7b44 --- /dev/null +++ b/cgi-bin/webnotes/utils/jsmin.py @@ -0,0 +1,213 @@ +import os, os.path, shutil + +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/nestedset.py b/cgi-bin/webnotes/utils/nestedset.py new file mode 100644 index 0000000000..13af8ec4de --- /dev/null +++ b/cgi-bin/webnotes/utils/nestedset.py @@ -0,0 +1,80 @@ +# Tree (Hierarchical) Nested Set Model (nsm) +# +# To use the nested set model, +# use the following pattern +# 1. name your parent field as "parent_node" if not have a property nsm_parent_field as your field name in the document class +# 2. have a field called "old_parent" in your fields list - this identifies whether the parent has been changed +# 3. call update_nsm(doc_obj) in the on_upate method + +# ------------------------------------------ + +import webnotes + +# called in the on_update method +def update_nsm(doc_obj): + # get fields, data from the DocType + d = doc_obj.doc + pf, opf = 'parent_node', 'old_parent' + if hasattr(doc_obj,'nsm_parent_field'): + pf = doc_obj.nsm_parent_field + if hasattr(doc_obj,'nsm_oldparent_field'): + opf = doc_obj.nsm_oldparent_field + p, op = d.fields[pf], d.fields.get(opf, '') + + # has parent changed (?) or parent is None (root) + if not doc_obj.doc.lft and not doc_obj.doc.rgt: + update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + elif op != p: + update_remove_node(doc_obj.doc.doctype, doc_obj.doc.name) + update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + # set old parent + webnotes.conn.set(d, opf, p or '') + +def rebuild_tree(doctype, parent_field): + # get all roots + right = 1 + result = webnotes.conn.sql("SELECT name FROM `tab%s` WHERE `%s`='' or `%s` IS NULL" % (doctype, parent_field, parent_field)) + for r in result: + right = rebuild_node(doctype, r[0], right, parent_field) + +def rebuild_node(doctype, parent, left, parent_field): + # the right value of this node is the left value + 1 + right = left+1 + + # get all children of this node + result = webnotes.conn.sql("SELECT name FROM `tab%s` WHERE `%s`='%s'" % (doctype, parent_field, parent)) + for r in result: + right = rebuild_node(doctype, r[0], right, parent_field) + + # we've got the left value, and now that we've processed + # the children of this node we also know the right value + webnotes.conn.sql('UPDATE `tab%s` SET lft=%s, rgt=%s WHERE name="%s"' % (doctype,left,right,parent)) + + #return the right value of this node + 1 + return right+1 + +def update_add_node(doctype, name, parent, parent_field): + # get the last sibling of the parent + if parent: + right = webnotes.conn.sql("select rgt from `tab%s` where name='%s'" % (doctype, parent))[0][0] + else: # root + right = webnotes.conn.sql("select ifnull(max(rgt),0)+1 from `tab%s` where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0] + right = right or 1 + + # update all on the right + webnotes.conn.sql("update `tab%s` set rgt = rgt+2 where rgt >= %s" %(doctype,right)) + webnotes.conn.sql("update `tab%s` set lft = lft+2 where lft >= %s" %(doctype,right)) + + #$ update index of new node + webnotes.conn.sql("update `tab%s` set lft=%s, rgt=%s where name='%s'" % (doctype,right,right+1,name)) + return right + +def update_remove_node(doctype, name): + left = webnotes.conn.sql("select lft from `tab%s` where name='%s'" % (doctype,name)) + if left[0][0]: + # reset this node + webnotes.conn.sql("update `tab%s` set lft=0, rgt=0 where name='%s'" % (doctype,name)) + + # update all on the right + webnotes.conn.sql("update `tab%s` set rgt = rgt-2 where rgt > %s" %(doctype,left[0][0])) + webnotes.conn.sql("update `tab%s` set lft = lft-2 where lft > %s" %(doctype,left[0][0])) diff --git a/cgi-bin/webnotes/utils/scheduler.py b/cgi-bin/webnotes/utils/scheduler.py new file mode 100644 index 0000000000..9520caf865 --- /dev/null +++ b/cgi-bin/webnotes/utils/scheduler.py @@ -0,0 +1,166 @@ +""" +Simple Scheduler + +This scheduler is used to fire events across multiple databases. A database +master_scheduler is maintained with one event and one log table + +Events are added by different databases in the master scheduler using the +`set_event` method and they are executed by the cron. + +__main__ will call run + +To install: +----------- + +python install_lib.py [root] [password] master_scheduler + +In cron: +-------- + +python [path]webnotes/utils/scheduler.py + +""" + + +class Scheduler: + def connect(self): + if hasattr(self,'conn'): return + + import webnotes.defs, webnotes.db + try: + self.conn = webnotes.db.Database(user='master_scheduler', password=webnotes.defs.db_password) + except Exception, e: + self.setup() + self.connect() + + def set(self, event, interval, recurring, db_name=None): + """ + Add an event to the Event table in the master scheduler + """ + self.connect() + + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + self.clear(db_name, event) + self.conn.sql("""insert into + Event (`db_name`, `event`, `interval`, next_execution, recurring) + values (%s, %s, %s, ADDTIME(NOW(), SEC_TO_TIME(%s)), %s) + """, (webnotes.conn.cur_db_name, event, interval, interval, recurring)) + + def get_events(self, db_name=None): + """ + Returns list of upcoming events + """ + self.connect() + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + return self.conn.sql("select * from Event where db_name=%s", db_name, as_dict=1) + + + def get_log(self, db_name=None): + """ + Returns log of events + """ + self.connect() + if not db_name: + import webnotes + db_name = webnotes.conn.cur_db_name + + return self.conn.sql("select * from EventLog where db_name=%s limit 50", db_name, as_dict=1) + + def clear(self, db_name, event): + """ + Clears the event + """ + self.connect() + self.conn.sql("delete from Event where `event`=%s and db_name=%s", (event, db_name)) + + def execute(self, db_name, event): + """ + Executes event in the specifed db + """ + import webnotes, webnotes.defs, webnotes.db + + try: + webnotes.conn = webnotes.db.Database(user=db_name, password=webnotes.defs.db_password) + webnotes.session = {'user':'Administrator'} + + module = '.'.join(event.split('.')[:-1]) + method = event.split('.')[-1] + + exec 'from %s import %s' % (module, method) + + webnotes.conn.begin() + ret = locals()[method]() + webnotes.conn.commit() + webnotes.conn.close() + + self.log(db_name, event, ret or 'Ok') + + except Exception, e: + self.log(db_name, event, webnotes.getTraceback()) + + def log(self, db_name, event, traceback): + """ + Log an event error + """ + self.conn.sql("insert into `EventLog`(db_name, event, log, executed_on) values (%s, %s, %s, now())", \ + (db_name, event, traceback)) + + # delete old logs + self.conn.sql("delete from EventLog where executed_on < subdate(curdate(), interval 30 day)") + + def run(self): + """ + Run scheduled (due) events and reset time for recurring events + """ + el = self.conn.sql("""select `db_name`, `event`, `recurring`, `interval` + from `Event` + where next_execution < NOW()""", as_dict=1) + + for e in el: + # execute the event + self.execute(e['db_name'], e['event']) + + # if recurring, update next_execution + if e['recurring']: + self.conn.sql("update Event set next_execution = addtime(now(), sec_to_time(%s))", e['interval']) + + # else clear + else: + self.clear(e['db_name'], e['event']) + +def set_event(event, interval=60*60*24, recurring=1): + """ + Adds an event to the master scheduler + """ + return Scheduler().set(event, interval, recurring) + + +def cancel_event(event): + """ + Cancels an event + """ + import webnotes + return Scheduler().clear(webnotes.conn.cur_db_name, event) + +# to be called from cron +if __name__=='__main__': + import os,sys + + cgi_bin_path = os.path.sep.join(__file__.split(os.path.sep)[:-3]) + + sys.path.append(cgi_bin_path) + + import webnotes + import webnotes.defs + sys.path.append(getattr(webnotes.defs,'modules_path',None)) + + sch = Scheduler() + sch.connect() + sch.run() + \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/sitemap.py b/cgi-bin/webnotes/utils/sitemap.py new file mode 100644 index 0000000000..ffa0471b81 --- /dev/null +++ b/cgi-bin/webnotes/utils/sitemap.py @@ -0,0 +1,34 @@ +# to generate sitemaps + +frame_xml = """ +%s +""" + +link_xml = """\n%s%s""" + +# generate the sitemap XML +def generate_xml(conn, site_prefix): + global frame_xml, link_xml + import urllib + + # settings + max_doctypes = 10 + max_items = 1000 + + site_map = '' + + if site_prefix: + # list of all Guest pages (static content) + for r in conn.sql("SELECT name, modified FROM tabPage WHERE ifnull(publish,0)=1 ORDER BY modified DESC"): + page_url = site_prefix + '#!' + urllib.quote(r[0]) + site_map += link_xml % (page_url, r[1].strftime('%Y-%m-%d')) + + # list of all Records that are viewable by guests (Blogs, Articles etc) + try: + from event_handlers import get_sitemap_items + for i in get_sitemap_items(site_prefix): + site_map += link_xml % (i[0], i[1]) + except ImportError, e: + pass + + return frame_xml % site_map \ No newline at end of file diff --git a/cgi-bin/webnotes/utils/transfer.py b/cgi-bin/webnotes/utils/transfer.py new file mode 100644 index 0000000000..3a389b02f4 --- /dev/null +++ b/cgi-bin/webnotes/utils/transfer.py @@ -0,0 +1,300 @@ +import webnotes +from webnotes.model.doc import Document + +def set_doc(doclist, ovr=0, ignore=1, onupdate=1): + dt = doclist[0]['doctype'] + + if webnotes.conn.exists(doclist[0]['doctype'], doclist[0]['name']): + # exists, merge if possible + + if dt=='DocType': + ud = UpdateDocType(doclist) + elif dt == 'Module Def': + ud = UpdateModuleDef(doclist) + elif dt == 'DocType Mapper': + ud = UpdateDocTypeMapper(doclist) + else: + ud = UpdateDocument(doclist) + else: + ud = UpdateDocument(doclist) + + ud.sync() + return '\n'.join(ud.log) + + + + +# +# Class to sync incoming document +# +class UpdateDocument: + def __init__(self, in_doclist=[]): + self.in_doclist = in_doclist + self.doc = Document(fielddata = in_doclist[0]) + self.modified = self.doc.modified # make a copy + self.doclist = [] + + self.log = [] + self.exists = 0 + + # sync + def sync(self): + is_mod = self.is_modified() + + if (not self.exists) or (is_mod): + webnotes.conn.begin() + if self.exists: + self.delete_existing() + self.save() + self.update_modified() + self.run_on_update() + webnotes.conn.commit() + + # check modified + def is_modified(self): + try: + timestamp = webnotes.conn.sql("select modified from `tab%s` where name=%s" % (self.doc.doctype, '%s'), self.doc.name) + except Exception ,e: + if(e.args[0]==1146): + return + else: + raise e + + if timestamp: + self.exists = 1 + if str(timestamp[0][0]) == self.doc.modified: + self.log.append('%s %s, No change' % (self.doc.doctype, self.doc.name)) + else: return 1 + + # delete existing + def delete_existing(self): + from webnotes.model import delete_doc + webnotes.conn.sql("set foreign_key_checks=0") + delete_doc(self.doc.doctype, self.doc.name) + webnotes.conn.sql("set foreign_key_checks=1") + + # update modified timestamp + def update_modified(self): + webnotes.conn.set(self.doc, 'modified', self.modified) + + def save(self): + # parent + self.doc.save(new = 1, ignore_fields = 1, check_links=0) + self.doclist = [self.doc] + self.save_children() + + def save_children(self): + for df in self.in_doclist[1:]: + self.save_one_doc(df) + + def save_one_doc(self, df, as_new=1): + d = Document(fielddata = df) + d.save(new = as_new, ignore_fields = 1, check_links=0) + self.doclist.append(d) + + def run_on_update(self): + from webnotes.model.code import get_server_obj + so = get_server_obj(self.doc, self.doclist) + if hasattr(so, 'on_update'): + so.on_update() + + + +# +# "Merge incoming doctype" +# +class UpdateDocumentMerge(UpdateDocument): + def __init__(self, in_doclist): + self.to_update_doctype = [] + UpdateDocument.__init__(self, in_doclist) + + def delete_existing(self): + pass + + def get_id(self, d): + pass + + def to_update(self, d): + return 1 + + def child_exists(self, d): + return self.get_id(d) + + def on_save(self): + pass + + def save(self): + if self.exists: + # save main doc + self.keep_values(self.doc) + self.doc.save(ignore_fields = 1, check_links=0) + self.doclist.append(self.doc) + self.save_children() + self.on_save() + self.log.append('Updated %s' % self.doc.name) + else: + UpdateDocument.save(self) + + def save_children(self): + for df in self.in_doclist[1:]: + d = Document(fielddata = df) + + # update doctype? + if d.doctype in self.to_update_doctype: + + # update this record? + if self.to_update(d): + + # is it new? + if self.child_exists(d): + self.keep_values(d) + d.save(ignore_fields = 1, check_links=0) + self.log.append('updated %s, %s' % (d.doctype, d.name)) + else: + d.save(1, ignore_fields = 1, check_links=0) + self.log.append('new %s' % d.doctype) + self.doclist.append(d) + + def keep_values(self, d): + if hasattr(self, 'get_orignal_values'): + ov = self.get_orignal_values(d) + if ov: + d.fields.update(ov) + + + +# +# Class to sync incoming doctype +# +class UpdateDocType(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['DocType', 'DocField'] + + def to_udpate(self, d): + if (d.fieldtype not in ['Section Break', 'Column Break', 'HTML']) and (d.fieldname or d.label): + return 1 + + def get_id(self, d): + key = d.fieldname and 'fieldname' or 'label' + return webnotes.conn.sql("""select name, options, permlevel, reqd, print_hide, hidden + from tabDocField where %s=%s and parent=%s""" % (key, '%s', '%s'), (d.fields[key], d.parent)) + + def on_save(self): + self.renum() + + def child_exists(self, d): + if d.doctype=='DocField': + return self.get_id(d) + + def get_orignal_values(self, d): + if d.doctype=='DocField': + t = self.get_id(d)[0] + return {'name': t[0], 'options': t[1], 'reqd':t[3], 'print_hide':t[4], 'hidden':t[5]} + + if d.doctype=='DocType': + return webnotes.conn.sql("select server_code, client_script from `tabDocType` where name=%s", d.name, as_dict = 1)[0] + + # renumber the indexes + def renum(self): + extra = self.get_extra_fields() + self.clear_section_breaks() + self.add_section_breaks_and_renum() + self.fix_extra_fields(extra) + + # get fields not in the incoming list (to preserve order) + def get_extra_fields(self): + prev_field, prev_field_key, extra = '', '', [] + + # get new fields and labels + fieldnames = [d.get('fieldname') for d in self.in_doclist] + labels = [d.get('label') for d in self.in_doclist] + + # check if all existing are present + for f in webnotes.conn.sql("select fieldname, label, idx from tabDocField where parent=%s and fieldtype not in ('Section Break', 'Column Break', 'HTML') order by idx asc", self.doc.name): + if f[0] and not f[0] in fieldnames: + extra.append([f[0], f[1], prev_field, prev_field_key]) + elif f[1] and not f[1] in labels: + extra.append([f[0], f[1], prev_field, prev_field_key]) + + prev_field, prev_field_key = f[0] or f[1], f[0] and 'fieldname' or 'label' + + return extra + + # clear section breaks + def clear_section_breaks(self): + webnotes.conn.sql("delete from tabDocField where fieldtype in ('Section Break', 'Column Break', 'HTML') and parent=%s and ifnull(options,'')!='Custom'", self.doc.name) + + # add section breaks + def add_section_breaks_and_renum(self): + for d in self.in_doclist: + if d.get('parentfield')=='fields': + if d.get('fieldtype') in ('Section Break', 'Column Break', 'HTML'): + tmp = Document(fielddata = d) + tmp.fieldname = '' + tmp.name = None + tmp.save(1, ignore_fields = 1, check_links=0) + else: + webnotes.conn.sql("update tabDocField set idx=%s where %s=%s and parent=%s" % \ + ('%s', d.get('fieldname') and 'fieldname' or 'label', '%s', '%s'), (d.get('idx'), d.get('fieldname') or d.get('label'), self.doc.name)) + + + # adjust the extra fields + def fix_extra_fields(self, extra): + # push fields down at new idx + for e in extra: + # get idx of the prev to extra field + idx = 0 + if e[2]: + idx = webnotes.conn.sql("select idx from tabDocField where %s=%s and parent=%s" % (e[3], '%s', '%s'), (e[2], self.doc.name)) + idx = idx and idx[0][0] or 0 + + if idx: + webnotes.conn.sql("update tabDocField set idx=idx+1 where idx>%s and parent=%s", (idx, self.doc.name)) + webnotes.conn.sql("update tabDocField set idx=%s where %s=%s and parent=%s" % \ + ('%s', e[0] and 'fieldname' or 'label', '%s', '%s'), (idx+1, e[0] or e[1], self.doc.name)) + + + + +# +# update module def +# +class UpdateModuleDef(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['Module Def', 'Module Def Item'] + + def get_id(self, d): + return webnotes.conn.sql("select name from `tabModule Def Item` where doc_type=%s and doc_name=%s and display_name=%s and parent=%s", (d.doc_type, d.doc_name, d.display_name, d.parent)) + + def to_update(self, d): + if d.doctype=='Module Def Item': return 1 + + def get_orignal_values(self, d): + if d.doctype=='Module Def Item': + return {'name': self.get_id(d)[0][0]} + if d.doctype=='Module Def': + return webnotes.conn.sql("select module_seq, disabled, is_hidden from `tabModule Def` where name=%s", d.name, as_dict = 1)[0] + + + +# +# update module def +# +class UpdateDocTypeMapper(UpdateDocumentMerge): + def __init__(self, in_doclist): + UpdateDocumentMerge.__init__(self, in_doclist) + self.to_update_doctype = ['Field Mapper Detail', 'Table Mapper Detail'] + + def get_id(self, d): + if d.doctype=='Field Mapper Detail': + return webnotes.conn.sql("select name from `tabField Mapper Detail` where from_field=%s and to_field=%s and match_id=%s and parent=%s", (d.from_field, d.to_field, d.match_id, d.parent)) + elif d.doctype=='Table Mapper Detail': + return webnotes.conn.sql("select name from `tabTable Mapper Detail` where from_table=%s and to_table = %s and match_id=%s and parent=%s", (d.from_table, d.to_table, d.match_id, d.parent)) + + def get_orignal_values(self, d): + if d.doctype in ['Field Mapper Detail', 'Table Mapper Detail']: + return {'name': self.get_id(d)[0][0]} + + diff --git a/cgi-bin/webnotes/utils/webservice.py b/cgi-bin/webnotes/utils/webservice.py new file mode 100644 index 0000000000..c3bb8ceba9 --- /dev/null +++ b/cgi-bin/webnotes/utils/webservice.py @@ -0,0 +1,111 @@ +import webnotes +import webnotes.utils + +class FrameworkServer: + """ + Connect to a remote server via HTTP (webservice). + + * `remote_host` is the the address of the remote server + * `path` is the path of the Framework (excluding index.cgi) + """ + def __init__(self, remote_host, path, user='', password='', account='', cookies=None, opts=None, https = 0): + # validate + if not (remote_host and path): + raise Exception, "Server address and path necessary" + + if not ((user and password) or (cookies)): + raise Exception, "Either cookies or user/password necessary" + + self.remote_host = remote_host + self.path = path + self.cookies = cookies or {} + self.webservice_method='POST' + self.account = account + self.account_id = None + self.https = https + self.conn = None + + # login + if not cookies: + args = { 'usr': user, 'pwd': password, 'acx': account } + + if opts: + args.update(opts) + + res = self.http_get_response('login', args) + + ret = res.read() + try: + ret = eval(ret) + except Exception, e: + webnotes.msgprint(ret) + raise Exception, e + + if ret.get('message') and ret.get('message')!='Logged In': + raise Exception, ret.get('message') + + if ret.get('exc'): + raise Exception, ret.get('exc') + + self._extract_cookies(res) + + self.account_id = self.cookies.get('account_id') + self.sid = self.cookies.get('sid') + + self.login_response = res + self.login_return = ret + + # ----------------------------------------------------------------------------------------- + + def http_get_response(self, method, args): + """ + Run a method on the remote server, with the given arguments + """ + # get response from remote server + + import urllib, urllib2, os + + args['cmd'] = method + if self.path.startswith('/'): self.path = self.path[1:] + + protocol = self.https and 'https://' or 'http://' + req = urllib2.Request(protocol + os.path.join(self.remote_host, self.path, 'index.cgi'), urllib.urlencode(args)) + for key in self.cookies: + req.add_header('cookie', '; '.join(['%s=%s' % (key, self.cookies[key]) for key in self.cookies])) + return urllib2.urlopen(req) + + # ----------------------------------------------------------------------------------------- + + def _extract_cookies(self, res): + import Cookie + cookies = Cookie.SimpleCookie() + cookies.load(res.headers.get('set-cookie')) + for c in cookies.values(): + self.cookies[c.key] = c.value.rstrip(',') + + # ----------------------------------------------------------------------------------------- + + + def runserverobj(self, doctype, docname, method, arg=''): + """ + Returns the response of a remote method called on a system object specified by `doctype` and `docname` + """ + res = self.http_get_response('runserverobj', args = { + 'doctype':doctype + ,'docname':docname + ,'method':method + ,'arg':arg + }) + ret = eval(res.read()) + if ret.get('exc'): + raise Exception, ret.get('exc') + return ret + + # ----------------------------------------------------------------------------------------- + + def run_method(self, method, args): + res = self.http_get_response(method, args) + ret = eval(res.read()) + if ret.get('exc'): + raise Exception, ret.get('exc') + return ret diff --git a/cgi-bin/webnotes/widgets/__init__.py b/cgi-bin/webnotes/widgets/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cgi-bin/webnotes/widgets/auto_master.py b/cgi-bin/webnotes/widgets/auto_master.py new file mode 100644 index 0000000000..003b1153e9 --- /dev/null +++ b/cgi-bin/webnotes/widgets/auto_master.py @@ -0,0 +1,53 @@ +# auto masters +# _ + fieldname is the table +# 'value' is the column name, pkey + +import webnotes + +# create masters for a doctype +def create_auto_masters(dt): + fl = webnotes.conn.sql("select fieldname from tabDocField where fieldtype='Data' and options='Suggest' and parent=%s", dt) + for f in fl: + make_auto_master(f[0]) + +# create master table +def make_auto_master(fieldname): + try: + webnotes.conn.sql("select `value` from `__%s` limit 1" % fieldname) + except Exception, e: + if e.args[0]==1146: + webnotes.conn.commit() + webnotes.conn.sql("create table `__%s` (`value` varchar(220), primary key (`value`))" % fieldname) + webnotes.conn.begin() + +# get auto master fields +def get_master_fields(dt): + if not webnotes.session['data'].get('auto_masters'): + webnotes.session['data']['auto_masters'] = {} + + if webnotes.session['data']['auto_masters'].get(dt, None)==None: + fl = webnotes.conn.sql("select fieldname from tabDocField where fieldtype='Data' and options='Suggest' and parent=%s", dt) + webnotes.session['data']['auto_masters'][dt] = fl + + return webnotes.session['data']['auto_masters'][dt] + + +# update value +def update_auto_masters(doc): + if not doc.doctype: + return + + fl = get_master_fields(doc.doctype) + + # save masters in session cache + for f in fl: + if doc.fields.get(f[0]): + add_to_master(f[0], doc.fields.get(f[0])) + +# add to master +def add_to_master(fieldname, value): + try: + webnotes.conn.sql("insert into `__%s` (`value`) values (%s)" % (fieldname,'%s'), value) + except Exception, e: + # primary key + pass \ No newline at end of file diff --git a/cgi-bin/webnotes/widgets/event.py b/cgi-bin/webnotes/widgets/event.py new file mode 100644 index 0000000000..8bb999d04b --- /dev/null +++ b/cgi-bin/webnotes/widgets/event.py @@ -0,0 +1,48 @@ +# Event +# ------------- + +def get_cal_events(m_st, m_end): + import webnotes + import webnotes.model.doc + + sql = webnotes.conn.sql + + # load owned events + res1 = sql("select name from `tabEvent` WHERE ifnull(event_date,'2000-01-01') between '%s' and '%s' and owner = '%s' and event_type != 'Public' and event_type != 'Cancel'" % (m_st, m_end, webnotes.user.name)) + + # load individual events + res2 = sql("select t1.name from `tabEvent` t1, `tabEvent User` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t2.person = '%s' and t1.name = t2.parent and t1.event_type != 'Cancel'" % (m_st, m_end, webnotes.user.name)) + + # load role events + roles = webnotes.user.get_roles() + myroles = ['t2.role = "%s"' % r for r in roles] + myroles = '(' + (' OR '.join(myroles)) + ')' + res3 = sql("select t1.name from `tabEvent` t1, `tabEvent Role` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t1.name = t2.parent and t1.event_type != 'Cancel' and %s" % (m_st, m_end, myroles)) + + # load public events + res4 = sql("select name from `tabEvent` where ifnull(event_date,'2000-01-01') between '%s' and '%s' and event_type='Public'" % (m_st, m_end)) + + doclist, rl = [], [] + for r in res1 + res2 + res3 + res4: + if not r in rl: + doclist += webnotes.model.doc.get('Event', r[0]) + rl.append(r) + + return doclist + + +# Load Month Events +# ----------------- + +def load_month_events(): + import webnotes + from webnotes.utils import cint + + form = webnotes.form + + mm = form.getvalue('month') + yy = form.getvalue('year') + m_st = str(yy) + '-%.2i' % cint(mm) + '-01' + m_end = str(yy) + '-%.2i' % cint(mm) + '-31' + + webnotes.response['docs'] = get_cal_events(m_st, m_end) \ No newline at end of file diff --git a/cgi-bin/webnotes/widgets/follow.py b/cgi-bin/webnotes/widgets/follow.py new file mode 100644 index 0000000000..2766d742c6 --- /dev/null +++ b/cgi-bin/webnotes/widgets/follow.py @@ -0,0 +1,134 @@ +""" +Server side methods for the follower pattern (Follow button used in forms) +""" + +import webnotes +form = webnotes.form_dict + +# +# Follow +# +def follow(dt=None, dn=None, user=None, verbose=0): + "Add as follower to a particular record. If no parameteres, then take from the http request (form)" + + if not dt: + dt, dn, user = form.get('dt'), form.get('dn'), form.get('user') + verbose = 1 + + if not user: return + + if not is_follower(dt, dn, user): + make_follower(dt, dn, user, verbose) + else: + if verbose: webnotes.msgprint("%s is already a follower!" % user) + + return load_followers(dt, dn) + +def make_follower(dt, dn, user, verbose): + "Add the user as a follower" + if has_permission(dt, user): + from webnotes.model.doc import Document + d = Document('Follower') + d.doc_type = dt + d.doc_name = dn + d.owner = user + d.save(1) + else: + if verbose: webnotes.msgprint('%s does not have sufficient permission to follow' % user) + +def has_permission(dt, user): + "Check to see if the user has permission to follow" + + return webnotes.conn.sql("select name from tabDocPerm where parent=%s and ifnull(`read`,0)=1 and role in ('%s') limit 1" \ + % ('%s', ("', '".join(webnotes.user.get_roles()))), dt) + +def is_follower(dt, dn, user): + "returns true if given user is a follower" + + return webnotes.conn.sql(""" + select name from tabFollower + where ifnull(doc_type,'')=%s + and ifnull(doc_name,'')=%s + and owner=%s""", (dt, dn, user)) +# +# Unfollow +# +def unfollow(dt=None, dn=None, user=None): + "Unfollow a particular record. If no parameteres, then take from the http request (form)" + + if not dt: + dt, dn, user = form.get('dt'), form.get('dn'), form.get('user') + + webnotes.conn.sql("delete from tabFollower where doc_name=%s and doc_type=%s and owner=%s", (dn, dt, user)) + + return load_followers(dt, dn) + +# +# Load followers +# +def load_followers(dt=None, dn=None): + "returns list of followers (Full Names) for a particular object" + + if not dt: dt, dn = form.get('dt'), form.get('dn') + + try: + return [t[0] for t in webnotes.conn.sql(""" + SELECT IFNULL(CONCAT(t1.first_name, if(t1.first_name IS NULL, '', ' '), t1.last_name), t1.name) + FROM tabProfile t1, tabFollower t2 WHERE t2.doc_type=%s AND t2.doc_name=%s + AND t1.name = t2.owner""", (dt, dn))] + + except Exception, e: + if e.args[0] in (1146, 1054): + setup() + return [] + else: + raise e + +# +# Email followers +# +def email_followers(dt, dn, msg_html=None, msg_text=None): + "Send an email to all followers of this object" + pass + +# +# Update feed +# +def on_docsave(doc): + "Add the owner and all linked Profiles as followers" + follow(doc.doctype, doc.name, doc.owner) + for p in get_profile_fields(doc.doctype): + follow(doc.doctype, doc.name, doc.fields.get(p)) + + update_followers(doc = doc) + +# +# update the follower record timestamp and subject +# +def update_followers(dt=None, dn=None, subject=None, update_by=None, doc=None): + "Updates the timestamp and subject in follower table (for feed generation)" + from webnotes.utils import now + webnotes.conn.sql("update tabFollower set modified=%s, subject=%s, modified_by=%s where doc_type=%s and doc_name=%s", \ + (now(), + subject or doc.fields.get('subject'), \ + update_by or webnotes.session['user'],\ + dt or doc.doctype, + dn or doc.name)) + +# +# get type of "Profile" fields +# +def get_profile_fields(dt): + "returns a list of all profile link fields from the doctype" + return [f[0] for f in \ + webnotes.conn.sql("select fieldname from tabDocField where parent=%s and fieldtype='Link' and options='Profile'", dt)] + +# +# setup - make followers table +# +def setup(): + "Make table for followers - if missing" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core', 'doctype', 'follower') + webnotes.conn.begin() diff --git a/cgi-bin/webnotes/widgets/form.py b/cgi-bin/webnotes/widgets/form.py new file mode 100644 index 0000000000..9a25608608 --- /dev/null +++ b/cgi-bin/webnotes/widgets/form.py @@ -0,0 +1,490 @@ +""" +Server side handler for "Form" events +""" + +import webnotes +import webnotes.model.doc +import webnotes.model.meta +from webnotes.model.triggers import fire_event + +def getdoc(): + """ + Loads a doclist for a given document. This method is called directly from the client. + Requries "doctype", "docname" as form variables. If "from_archive" is set, it will get from archive. + Will also call the "onload" method on the document. + """ + + import webnotes + from webnotes.utils import cint + + form = webnotes.form_dict + doctype, docname = form.get('doctype'), form.get('name') + prefix = cint(form.get('from_archive')) and 'arc' or 'tab' + + if not (doctype and docname): + raise Exception, 'doctype and name required!' + + doclist = [] + # single + doclist = load_single_doc(doctype, docname, (form.get('user') or webnotes.session['user']), prefix) + + # load doctype along with the doc + if form.get('getdoctype'): + import webnotes.model.doctype + doclist += webnotes.model.doctype.get(doctype) + + # tag as archived + if prefix == 'arc': + doclist[0].__archived=1 + + webnotes.response['docs'] = doclist + +#=========================================================================================== + +def get_comments(doctype=None, docname=None, limit=5): + nc, cl = 0, [] + + if not doctype: + doctype, docname, limit = webnotes.form_dict.get('dt'), webnotes.form_dict.get('dn'), webnotes.form_dict.get('limit') + + try: + nc = int(webnotes.conn.sql("select count(*) from `tabComment Widget Record` where comment_doctype=%s and comment_docname=%s", (doctype, docname))[0][0]) + if nc: + cl = webnotes.conn.sql("select comment, ifnull(comment_by_fullname, comment_by) AS 'comment_by_fullname', creation from `tabComment Widget Record` where comment_doctype=%s and comment_docname=%s order by creation desc limit %s" % ('%s','%s',limit), (doctype, docname), as_dict=1) + + except Exception, e: + if e.args[0]==1146: + # no table + make_comment_table() + else: + raise e + + webnotes.response['n_comments'], webnotes.response['comment_list'] = nc, cl + +# +# make comment table +# +def make_comment_table(): + "Make table for comments - if missing via import module" + webnotes.conn.commit() + from webnotes.modules import reload_doc + reload_doc('core', 'doctype', 'comment_widget_record') + webnotes.conn.begin() + +#=========================================================================================== + +def add_comment(): + import time + args = webnotes.form_dict + + if args.get('comment'): + from webnotes.model.doc import Document + from webnotes.utils import nowdate + + cmt = Document('Comment Widget Record') + for arg in ['comment', 'comment_by', 'comment_by_fullname', 'comment_doctype', 'comment_docname']: + cmt.fields[arg] = args[arg] + cmt.comment_date = nowdate() + cmt.comment_time = time.strftime('%H:%M') + cmt.save(1) + +#=========================================================================================== + +def remove_comment(): + args = webnotes.form_dict + webnotes.conn.sql("delete from `tabComment Widget Record` where name=%s",args.get('id')) + + try: + get_obj('Feed Control').upate_comment_in_feed(args['dt'], args['dn']) + except: pass + +#=========================================================================================== + +def getdoctype(): + # load parent doctype too + import webnotes.model.doctype + + form, doclist = webnotes.form, [] + + dt = form.getvalue('doctype') + with_parent = form.getvalue('with_parent') + + # with parent (called from report builder) + if with_parent: + parent_dt = webnotes.model.meta.get_parent_dt(dt) + if parent_dt: + doclist = webnotes.model.doctype.get(parent_dt) + webnotes.response['parent_dt'] = parent_dt + + if not doclist: + doclist = webnotes.model.doctype.get(dt) + + # if single, send the record too + if doclist[0].issingle: + doclist += webnotes.model.doc.get(dt) + + # load search criteria for reports (all) + doclist += webnotes.model.meta.get_search_criteria(dt) + + + webnotes.response['docs'] = doclist + +#=========================================================================================== + +def load_single_doc(dt, dn, user, prefix): + import webnotes.model.code + + if not dn: dn = dt + dl = webnotes.model.doc.get(dt, dn, prefix=prefix) + + # archive, done + if prefix=='arc': + return dl + + try: + so, r = webnotes.model.code.get_server_obj(dl[0], dl), None + if hasattr(so, 'onload'): + r = webnotes.model.code.run_server_obj(so, 'onload') + if hasattr(so, 'custom_onload'): + r = webnotes.model.code.run_server_obj(so, 'custom_onload') + if r: + webnotes.msgprint(r) + except Exception, e: + webnotes.errprint(webnotes.utils.getTraceback()) + webnotes.msgprint('Error in script while loading') + raise e + + if dl and not dn.startswith('_'): + webnotes.user.update_recent(dt, dn) + + # load search criteria ---- if doctype + if dt=='DocType': + dl += webnotes.model.meta.get_search_criteria(dt) + + return dl + +# Check Guest Access +#=========================================================================================== +def check_guest_access(doc): + if webnotes.session['user']=='Guest' and not webnotes.conn.sql("select name from tabDocPerm where role='Guest' and parent=%s and ifnull(`read`,0)=1", doc.doctype): + webnotes.msgprint("Guest not allowed to call this object") + raise Exception + +# Runserverobj - run server calls from form +#=========================================================================================== + +def runserverobj(): + import webnotes.model.code + import webnotes.model.doclist + from webnotes.utils import cint + + form = webnotes.form + + + method = form.getvalue('method') + doclist, clientlist = [], [] + arg = form.getvalue('arg') + dt = form.getvalue('doctype') + dn = form.getvalue('docname') + + if dt: # not called from a doctype (from a page) + if not dn: dn = dt # single + so = webnotes.model.code.get_obj(dt, dn) + + else: + clientlist = webnotes.model.doclist.expand(form.getvalue('docs')) + + # find main doc + for d in clientlist: + if cint(d.get('docstatus')) != 2 and not d.get('parent'): + main_doc = webnotes.model.doc.Document(fielddata = d) + + # find child docs + for d in clientlist: + doc = webnotes.model.doc.Document(fielddata = d) + if doc.fields.get('parent'): + doclist.append(doc) + + so = webnotes.model.code.get_server_obj(main_doc, doclist) + + # check integrity + if not check_integrity(so.doc): + return + + check_guest_access(so.doc) + + if so: + r = webnotes.model.code.run_server_obj(so, method, arg) + doclist = so.doclist # reference back [in case of null] + if r: + try: + if r['doclist']: + clientlist += r['doclist'] + except: + pass + + #build output as csv + if cint(webnotes.form.getvalue('as_csv')): + make_csv_output(r, so.doc.doctype) + else: + webnotes.response['message'] = r + + if clientlist: + doclist.append(main_doc) + webnotes.response['docs'] = doclist + +def make_csv_output(res, dt): + import webnotes + from webnotes.utils import getCSVelement + + txt = [] + if type(res)==list: + for r in res: + txt.append(','.join([getCSVelement(i) for i in r])) + + txt = '\n'.join(txt) + + else: + txt = 'Output was not in list format\n' + r + + webnotes.response['result'] = txt + webnotes.response['type'] = 'csv' + webnotes.response['doctype'] = dt.replace(' ','') + + +# Document Save +#=========================================================================================== + +def _get_doclist(clientlist): + # converts doc dictionaries into Document objects + + from webnotes.model.doc import Document + form = webnotes.form + + midx = 0 + for i in range(len(clientlist)): + if clientlist[i]['name'] == form.getvalue('docname'): + main_doc = Document(fielddata = clientlist[i]) + midx = i + else: + clientlist[i] = Document(fielddata = clientlist[i]) + + del clientlist[midx] + return main_doc, clientlist + +def _do_action(doc, doclist, so, method_name, docstatus=0): + + from webnotes.model.code import run_server_obj + set = webnotes.conn.set + + if so and hasattr(so, method_name): + errmethod = method_name + run_server_obj(so, method_name) + if hasattr(so, 'custom_'+method_name): + run_server_obj(so, 'custom_'+method_name) + errmethod = '' + + # fire triggers observers (if any) + fire_event(doc, method_name) + + # set docstatus for all children records + if docstatus: + for d in [doc] + doclist: + if int(d.docstatus or 0) != 2: + set(d, 'docstatus', docstatus) + +def check_integrity(doc): + import webnotes + + if (not webnotes.model.meta.is_single(doc.doctype)) and (not doc.fields.get('__islocal')): + tmp = webnotes.conn.sql('SELECT modified FROM `tab%s` WHERE name="%s" for update' % (doc.doctype, doc.name)) + if tmp and str(tmp[0][0]) != str(doc.modified): + webnotes.msgprint('Document has been modified after you have opened it. To maintain the integrity of the data, you will not be able to save your changes. Please refresh this document. [%s/%s]' % (tmp[0][0], doc.modified)) + return 0 + + return 1 + +#=========================================================================================== + +def savedocs(): + import webnotes.model.doclist + + from webnotes.model.code import get_server_obj + from webnotes.model.code import run_server_obj + import webnotes.utils + from webnotes.widgets.auto_master import update_auto_masters + + from webnotes.utils import cint + + sql = webnotes.conn.sql + form = webnotes.form + + # action + action = form.getvalue('action') + + # get docs + doc, doclist = _get_doclist(webnotes.model.doclist.expand(form.getvalue('docs'))) + + # get server object + server_obj = get_server_obj(doc, doclist) + + # check integrity + if not check_integrity(doc): + return + + if not doc.check_perm(verbose=1): + webnotes.msgprint("Not enough permission to save %s" % doc.doctype) + return + + # validate links + ret = webnotes.model.doclist.validate_links_doclist([doc] + doclist) + if ret: + webnotes.msgprint("[Link Validation] Could not find the following values: %s. Please correct and resave. Document Not Saved." % ret) + return + + # saving & post-saving + try: + # validate befor saving and submitting + if action in ('Save', 'Submit') and server_obj: + if hasattr(server_obj, 'validate'): + t = run_server_obj(server_obj, 'validate') + if hasattr(server_obj, 'custom_validate'): + t = run_server_obj(server_obj, 'custom_validate') + + # set owner and modified times + is_new = cint(doc.fields.get('__islocal')) + if is_new and not doc.owner: + doc.owner = form.getvalue('user') + + doc.modified, doc.modified_by = webnotes.utils.now(), webnotes.session['user'] + + # save main doc + try: + t = doc.save(is_new) + update_auto_masters(doc) + except NameError, e: + webnotes.msgprint('%s "%s" already exists' % (doc.doctype, doc.name)) + if webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doc.doctype, '%s'), doc.name)[0][0]==2: + webnotes.msgprint('[%s "%s" has been cancelled]' % (doc.doctype, doc.name)) + webnotes.errprint(webnotes.utils.getTraceback()) + raise e + + # save child docs + for d in doclist: + deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0) + + if cint(local) and cint(deleted): + pass + elif d.fields.has_key('parent'): + if d.parent and (not d.parent.startswith('old_parent:')): + d.parent = doc.name # rename if reqd + d.parenttype = doc.doctype + d.modified, d.modified_by = webnotes.utils.now(), webnotes.session['user'] + d.save(new = cint(local)) + update_auto_masters(d) + + # on_update + if action in ('Save','Submit') and server_obj: + if hasattr(server_obj, 'on_update'): + t = run_server_obj(server_obj, 'on_update') + if t: webnotes.msgprint(t) + + if hasattr(server_obj, 'custom_on_update'): + t = run_server_obj(server_obj, 'custom_on_update') + if t: webnotes.msgprint(t) + + fire_event(doc, 'on_update') + + # on_submit + if action == 'Submit': + _do_action(doc, doclist, server_obj, 'on_submit', 1) + + # for allow_on_submit type + if action == 'Update': + _do_action(doc, doclist, server_obj, 'on_update_after_submit', 0) + + # on_cancel + if action == 'Cancel': + _do_action(doc, doclist, server_obj, 'on_cancel', 2) + + # update recent documents + webnotes.user.update_recent(doc.doctype, doc.name) + + # send updated docs + webnotes.response['saved'] = '1' + webnotes.response['main_doc_name'] = doc.name + webnotes.response['docname'] = doc.name + webnotes.response['docs'] = [doc] + doclist + + except Exception, e: + webnotes.msgprint('Did not save') + webnotes.errprint(webnotes.utils.getTraceback()) + raise e + + +# Print Format +#=========================================================================================== +def _get_print_format(match): + name = match.group('name') + return webnotes.model.meta.get_print_format_html(name) + +def get_print_format(): + import re + import webnotes + + html = webnotes.model.meta.get_print_format_html(webnotes.form.getvalue('name')) + + p = re.compile('\$import\( (?P [^)]*) \)', re.VERBOSE) + out_html = '' + if html: + out_html = p.sub(_get_print_format, html) + + webnotes.response['message'] = out_html + +# remove attachment +#=========================================================================================== + +def remove_attach(): + import webnotes + import webnotes.utils.file_manager + + fid = webnotes.form.getvalue('fid') + webnotes.utils.file_manager.delete_file(fid, verbose=1) + +# Get Fields - Counterpart to $c_get_fields +#=========================================================================================== +def get_fields(): + import webnotes + r = {} + args = { + 'select':webnotes.form.getvalue('select') + ,'from':webnotes.form.getvalue('from') + ,'where':webnotes.form.getvalue('where') + } + ret = webnotes.conn.sql("select %(select)s from `%(from)s` where %(where)s limit 1" % args) + if ret: + fl, i = webnotes.form.getvalue('fields').split(','), 0 + for f in fl: + r[f], i = ret[0][i], i+1 + webnotes.response['message']=r + +# validate link +#=========================================================================================== +def validate_link(): + import webnotes + import webnotes.utils + + value, options, fetch = webnotes.form.getvalue('value'), webnotes.form.getvalue('options'), webnotes.form.getvalue('fetch') + + # no options, don't validate + if not options or options=='null' or options=='undefined': + webnotes.response['message'] = 'Ok' + return + + if webnotes.conn.sql("select name from `tab%s` where name=%s" % (options, '%s'), value): + + # get fetch values + if fetch: + webnotes.response['fetch_values'] = [webnotes.utils.parse_val(c) for c in webnotes.conn.sql("select %s from `tab%s` where name=%s" % (fetch, options, '%s'), value)[0]] + + webnotes.response['message'] = 'Ok' diff --git a/cgi-bin/webnotes/widgets/menus.py b/cgi-bin/webnotes/widgets/menus.py new file mode 100644 index 0000000000..1b414027ed --- /dev/null +++ b/cgi-bin/webnotes/widgets/menus.py @@ -0,0 +1,181 @@ +""" +Server side methods called from DocBrowser +""" + +import webnotes +from webnotes.utils import cint, cstr + +sql = webnotes.conn.sql + +def get_menu_items(): + """ + Returns a list of items to show in `Options` of the Web Notes Toolbar + List contains Pages and Single DocTypes + """ + import webnotes.utils + + rl = webnotes.user.get_roles() + [webnotes.session['user']] + role_options = ["role = '"+r+"'" for r in rl] + + sql = webnotes.conn.sql + menuitems = [] + + # pages + pages = sql("select distinct parent from `tabPage Role` where docstatus!=2 and (%s)" % (' OR '.join(role_options))) + + for p in pages: + tmp = sql("select icon, parent_node, menu_index, show_in_menu from tabPage where name = '%s'" % p[0]) + if tmp and tmp[0][3]: + menuitems.append(['Page', p[0] or '', tmp[0][1] or '', tmp[0][0] or '', webnotes.utils.cint(tmp[0][2])]) + + # singles + tmp = sql("select smallicon, parent_node, menu_index, name from tabDocType where (show_in_menu = 1 and show_in_menu is not null)") + singles = {} + for t in tmp: singles[t[3]] = t + + for p in webnotes.user.can_read: + tmp = singles.get(p, None) + if tmp: menuitems.append([p, p, tmp[1] or '', tmp[0] or '', int(tmp[2] or 0)]) + + return menuitems + +# -------------------------------------------------------------- +def has_result(): + return sql("select name from `tab%s` limit 1" % webnotes.form_dict.get('dt')) and 'Yes' or 'No' + +# -------------------------------------------------------------- + +def is_submittable(dt): + return sql("select name from tabDocPerm where parent=%s and ifnull(submit,0)=1 and docstatus<1 limit 1", dt) + +# -------------------------------------------------------------- + +def can_cancel(dt): + return sql('select name from tabDocPerm where parent="%s" and ifnull(cancel,0)=1 and docstatus<1 and role in ("%s") limit 1' % (dt, '", "'.join(webnotes.user.get_roles()))) + +# -------------------------------------------------------------- +def get_dt_trend(dt): + ret = {} + for r in sql("select datediff(now(),modified), count(*) from `tab%s` where datediff(now(),modified) between 0 and 30 group by date(modified)" % dt): + ret[cint(r[0])] = cint(r[1]) + return ret + +# -------------------------------------------------------------- + +def get_columns(out, sf, fl, dt, tag_fields): + if not fl: + fl = sf + + # subject + subject = webnotes.conn.get_value('DocType', dt, 'subject') + if subject: + out['subject'] = subject + + # get fields from subject + import re + fl = re.findall('\%\( (?P [^)]*) \)s', subject, re.VERBOSE) + + if tag_fields: + fl += [t.strip() for t in tag_fields.split(',')] + + res = [] + for f in tuple(set(fl)): + if f: + res += [[c or '' for c in r] for r in sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname='%s'" % (dt, f))] + + + return res + + +# -------------------------------------------------------------- +# NOTE: THIS SHOULD BE CACHED IN DOCTYPE CACHE +# -------------------------------------------------------------- + +def get_dt_details(): + """ + Returns details called by DocBrowser this includes: + the filters, columns, subject and tag_fields + also if the doctype is of type "submittable" + """ + fl = eval(webnotes.form_dict.get('fl')) + dt = webnotes.form_dict.get('dt') + tag_fields, description = webnotes.conn.get_value('DocType', dt, ['tag_fields', 'description']) + + submittable = is_submittable(dt) and 1 or 0 + + out = { + 'submittable':(is_submittable(dt) and 1 or 0), + 'can_cancel':(can_cancel(dt) and 1 or 0) + } + + # filters + # ------- + + sf = sql("select search_fields from tabDocType where name=%s", dt)[0][0] or '' + + # get fields from in_filter (if not in search_fields) + if not sf.strip(): + res = sql("select fieldname, label, fieldtype, options from tabDocField where parent=%s and `in_filter` = 1 and ifnull(fieldname,'') != ''", dt) + sf = [s[0] for s in res] + else: + sf = [s.strip() for s in sf.split(',')] + res = sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname in (%s)" % (dt, '"'+'","'.join(sf)+'"')) + + # select "link" options + res = [[c or '' for c in r] for r in res] + for r in res: + if r[2]=='Select' and r[3] and r[3].startswith('link:'): + tdt = r[3][5:] + ol = sql("select name from `tab%s` where docstatus!=2 order by name asc" % tdt) + r[3] = "\n".join([''] + [o[0] for o in ol]) + + if not res: + out['filters'] = [['name', 'ID', 'Data', '']] + else: + out['filters'] = [['name', 'ID', 'Data', '']] + res + + # columns + # ------- + res = get_columns(out, sf, fl, dt, tag_fields) + + from webnotes.widgets.tags import check_user_tags + check_user_tags(dt) + + out['columns'] = [['name', 'ID', 'Link', dt], ['modified', 'Modified', 'Data', ''], ['_user_tags', 'Tags', 'Data', '']] + res + out['tag_fields'] = tag_fields + out['description'] = description + + return out + + +# -------------------------------------------------------------- + +def get_trend(): + return {'trend': get_dt_trend(webnotes.form_dict.get('dt'))} + + + + + +# +# delete and archive in docbrowser +# +def delete_items(): + il = eval(webnotes.form_dict.get('items')) + from webnotes.model import delete_doc + from webnotes.model.code import get_obj + + for d in il: + dt_obj = get_obj(d[0], d[1]) + if hasattr(dt_obj, 'on_trash'): + dt_obj.on_trash() + delete_doc(d[0], d[1]) + +# -------------------------------------------------------------- + +def archive_items(): + il = eval(webnotes.form_dict.get('items')) + + from webnotes.utils.archive import archive_doc + for d in il: + archive_doc(d[0], d[1], webnotes.form_dict.get('action')=='Restore' and 1 or 0) diff --git a/cgi-bin/webnotes/widgets/page.py b/cgi-bin/webnotes/widgets/page.py new file mode 100644 index 0000000000..09fd79649f --- /dev/null +++ b/cgi-bin/webnotes/widgets/page.py @@ -0,0 +1,87 @@ +import webnotes +import webnotes.model.doc +import webnotes.model.code + +conn = webnotes.conn + +class Page: + """ + A page class helps in loading a Page in the system. On loading + + * Page will import Client Script from other pages where specified by `$import(page_name)` + * Execute dynamic HTML if the `content` starts with `#python` + """ + def __init__(self, name): + self.name = name + + def load(self): + """ + Returns :term:`doclist` of the `Page` + """ + from webnotes.modules import compress + from webnotes.model.code import get_code + + doclist = webnotes.model.doc.get('Page', self.name) + doc = doclist[0] + + doc.fields['__script'] = compress.get_page_js(doc) + doc.script = None + + template = '%(content)s' + # load code from template + if doc.template: + template = get_code(webnotes.conn.get_value('Page Template', doc.template, 'module'), 'Page Template', doc.template, 'html', fieldname='template') + + doc.content = get_code(doc.module, 'page', doc.name, 'html') or doc.content + + # execute content + if doc.content and doc.content.startswith('#!python'): + doc.__content = template % {'content': webnotes.model.code.execute(doc.content).get('content')} + else: + doc.__content = template % {'content': doc.content or ''} + + # local stylesheet + css = get_code(doc.module, 'page', doc.name, 'css') + if css: doc.style = css + + # add stylesheet + if doc.stylesheet: + doclist += self.load_stylesheet(doc.stylesheet) + + return doclist + + def load_stylesheet(self, stylesheet): + import webnotes + # load stylesheet + loaded = eval(webnotes.form_dict.get('stylesheets') or '[]') + if not stylesheet in loaded: + import webnotes.model.doc + from webnotes.model.code import get_code + + # doclist + sslist = webnotes.model.doc.get('Stylesheet', stylesheet) + + # stylesheet from file + css = get_code(sslist[0].module, 'Stylesheet', stylesheet, 'css') + + if css: sslist[0].stylesheet = css + + return sslist + else: + return [] + +def get(name): + """ + Return the :term:`doclist` of the `Page` specified by `name` + """ + return Page(name).load() + +def getpage(): + """ + Load the page from `webnotes.form` and send it via `webnotes.response` + """ + doclist = get(webnotes.form.getvalue('name')) + + # send + webnotes.response['docs'] = doclist + diff --git a/cgi-bin/webnotes/widgets/page_body.py b/cgi-bin/webnotes/widgets/page_body.py new file mode 100644 index 0000000000..f221511209 --- /dev/null +++ b/cgi-bin/webnotes/widgets/page_body.py @@ -0,0 +1,240 @@ +#: HTML Template of index.cgi +index_template = ''' + + + + + + + + + + + %(title)s + + + + + + + + + %(import_form)s + + + %(add_in_head)s + + + + + +
    + +
    + + +
    + + +
    + %(content)s +
    + +
    + +%(add_in_body)s + + +''' + +redirect_template = ''' + + +%s + + +Redirecting... + +''' + +page_properties = { + 'add_in_head':'', + 'add_in_body':'', + 'keywords':'', + 'site_description':'', + 'title':'', + 'content':'', + 'startup_data':'{}', + 'import_form':'' +} + + +import webnotes + +# remove 'id' attributes so they don't conflict +# --------------------------------------------- +def replace_id(match): + #webnotes.msgprint(match.group('name')) + return '' + +def scrub_ids(content): + import re + + p = re.compile('id=\"(?P [^\"]*)\"', re.VERBOSE) + content = p.sub(replace_id, content) + + p = re.compile('id=\'(?P [^\']*)\'', re.VERBOSE) + content = p.sub(replace_id, content) + + return content + +# +# load the page content and meta tags +# +def get_page_content(page): + """ + Gets the HTML content from `static_content` or `content` property of a `Page` + """ + from webnotes.model.code import get_code + from webnotes.model.doc import Document + global page_properties + + if not page: return + if '/' in page: page = page.split('/')[0] + if page=='Form': return + + try: + doc = Document('Page', page) + + load_page_metatags(doc) + + template = '%(content)s' + # content + if doc.template: + template = get_code(webnotes.conn.get_value('Page Template', doc.template, 'module'), 'Page Template', doc.template, 'html', fieldname='template') + + page_properties['content'] = get_code(doc.module, 'page', doc.name, 'html', fieldname='content') + + # dynamic (scripted) content + if page_properties['content'] and page_properties['content'].startswith('#!python'): + page_properties.update(webnotes.model.code.execute(page_properties['content'])) + + page_properties['content'] = scrub_ids(template % {'content':page_properties['content']}) + except: + pass + +# +# load metatags +# +def load_page_metatags(doc): + global page_properties + + try: + import startup + except: + startup = '' + + # page meta-tags + page_properties['title'] = doc.page_title or doc.name + page_properties['keywords'] = doc.keywords or webnotes.conn.get_value('Control Panel',None,'keywords') or '' + page_properties['site_description'] = doc.site_description or webnotes.conn.get_value('Control Panel',None,'site_description') or '' + page_properties['add_in_head'] = getattr(startup, 'add_in_head', '') + page_properties['add_in_body'] = getattr(startup, 'add_in_body', '') + +# +# load the form as page (deprecated) +# +def get_doc_content(dt, dn): + """ + Gets the HTML content of a document record by using the overridden or standard :method: `doclist.to_html` + """ + import webnotes.model.code + + if dt in webnotes.user.get_read_list(): + # generate HTML + do = webnotes.model.code.get_obj(dt, dn, with_children = 1) + if hasattr(do, 'to_html'): + return dn, do.to_html() + else: + import webnotes.model.doclist + return dn, webnotes.model.doclist.to_html(do.doclist) + else: + return 'Forbidden - 404', '

    Forbidden - 404

    ' + +# find the page to load as static +# ------------------------------- + +def load_properties(): + import webnotes.widgets.page + import urllib + + page_url = webnotes.form_dict.get('_escaped_fragment_', webnotes.form_dict.get('page', '')) + + if page_url: + if page_url.startswith('Page/'): + page_url = page_url[5:] + page_url = ['Page', urllib.unquote(page_url)] + else: + page_url = ['Page', webnotes.user.get_home_page()] + + # load content + # ----------------- + get_page_content(page_url[1]) + +# generate the page +# ----------------- +def load_default_properties(): + if not page_properites['keywords']: + page_properites['keywords'] = webnotes.conn.get_value('Control Panel',None,'keywords') or '' + if not page_properites['site_description']: + page_properites['site_description'] = webnotes.conn.get_value('Control Panel',None,'site_description') or '' + +# generate the page +# ----------------- +def get(): + """ + returns the full rendered index.cgi + Gets `keywords` and `site_description` from the `Control Panel` + """ + import webnotes + no_startup = webnotes.form.getvalue('no_startup') or None + + global index_template, redirect_template + import webnotes.session_cache + try: + import json + except: # python 2.4 + import simplejson as json + + page = webnotes.form_dict.get('page', '') + # sid in public display + # --------------------- + if webnotes.form_dict.get('sid'): + return redirect_template % ('Redirecting...', ('index.cgi' + (page and ('?page='+page) or ''))) + + if '%(content)s' in index_template: + load_properties() + + # load the session data + # --------------------- + try: + sd = webnotes.session_cache.get() + except: + import webnotes.utils + sd = {'exc':webnotes.utils.getTraceback()} + + # add debug messages + + sd['server_messages'] = '\n--------------\n'.join(webnotes.message_log) + + page_properties['startup_data'] = no_startup and '{}' or json.dumps(sd) + + # no form api required for guests + if webnotes.session['user']=='Guest': + page_properties['import_form'] = '' + + index_template = index_template % page_properties + + return index_template diff --git a/cgi-bin/webnotes/widgets/query_builder.py b/cgi-bin/webnotes/widgets/query_builder.py new file mode 100644 index 0000000000..cf272434e3 --- /dev/null +++ b/cgi-bin/webnotes/widgets/query_builder.py @@ -0,0 +1,333 @@ +import webnotes + +form = webnotes.form +session = webnotes.session +sql = webnotes.conn.sql +out = webnotes.response + +from webnotes.utils import cint + +def get_search_criteria_list(dt): + sc_list = sql("select criteria_name, doc_type from `tabSearch Criteria` where doc_type = '%s' or parent_doc_type = '%s'" % (dt, dt)) + return [list(s) for s in sc_list] + +def load_report_list(): + webnotes.response['rep_list'] = get_search_criteria_list(form.getvalue('dt')) + + +# Get, scrub metadata +# ==================================================================== + +def get_sql_tables(q): + if q.find('WHERE') != -1: + tl = q.split('FROM')[1].split('WHERE')[0].split(',') + elif q.find('GROUP BY') != -1: + tl = q.split('FROM')[1].split('GROUP BY')[0].split(',') + else: + tl = q.split('FROM')[1].split('ORDER BY')[0].split(',') + return [t.strip().strip('`')[3:] for t in tl] + + +def get_parent_dt(dt): + pdt = '' + if sql('select name from `tabDocType` where istable=1 and name="%s"' % dt): + res = sql('select parent from `tabDocField` where fieldtype="Table" and options="%s"' % dt) + if res: pdt = res[0][0] + return pdt + +def get_sql_meta(tl): + std_columns = { + 'owner':('Owner', '', '', '100'), + 'creation':('Created on', 'Date', '', '100'), + 'modified':('Last modified on', 'Date', '', '100'), + 'modified_by':('Modified By', '', '', '100') + } + + meta = {} + + for dt in tl: + meta[dt] = std_columns.copy() + + # for table doctype, the ID is the parent id + pdt = get_parent_dt(dt) + if pdt: + meta[dt]['parent'] = ('ID', 'Link', pdt, '200') + + # get the field properties from DocField + res = sql("select fieldname, label, fieldtype, options, width from tabDocField where parent='%s'" % dt) + for r in res: + if r[0]: + meta[dt][r[0]] = (r[1], r[2], r[3], r[4]); + + # name + meta[dt]['name'] = ('ID', 'Link', dt, '200') + + return meta + +# Additional conditions to fulfill match permission rules +# ==================================================================== + +def getmatchcondition(dt, ud, ur): + res = sql("SELECT `role`, `match` FROM tabDocPerm WHERE parent = '%s' AND (`read`=1) AND permlevel = 0" % dt) + cond = [] + for r in res: + if r[0] in ur: # role applicable to user + if r[1]: + defvalues = ud.get(r[1],['_NA']) + for d in defvalues: + cond.append('`tab%s`.`%s`="%s"' % (dt, r[1], d)) + else: # nomatch i.e. full read rights + return '' + + return ' OR '.join(cond) + +def add_match_conditions(q, tl, ur, ud): + sl = [] + for dt in tl: + s = getmatchcondition(dt, ud, ur) + if s: + sl.append(s) + + # insert the conditions + if sl: + condition_st = q.find('WHERE')!=-1 and ' AND ' or ' WHERE ' + + condition_end = q.find('ORDER BY')!=-1 and 'ORDER BY' or 'LIMIT' + condition_end = q.find('GROUP BY')!=-1 and 'GROUP BY' or condition_end + + if q.find('ORDER BY')!=-1 or q.find('LIMIT')!=-1 or q.find('GROUP BY')!=-1: # if query continues beyond conditions + q = q.split(condition_end) + q = q[0] + condition_st + '(' + ' OR '.join(sl) + ') ' + condition_end + q[1] + else: + q = q + condition_st + '(' + ' OR '.join(sl) + ')' + + return q + +# execute server-side script from Search Criteria +# ==================================================================== + +def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[], filter_values={}, query='', from_export=0): + col_idx, i, out, style, header_html, footer_html, page_template = {}, 0, None, [], '', '', '' + for c in colnames: + col_idx[c] = i + i+=1 + + # load globals (api) + from webnotes import * + from webnotes.utils import * + from webnotes.model.doc import * + from webnotes.model.doclist import getlist + from webnotes.model.db_schema import updatedb + from webnotes.model.code import get_obj + + set = webnotes.conn.set + sql = webnotes.conn.sql + get_value = webnotes.conn.get_value + convert_to_lists = webnotes.conn.convert_to_lists + NEWLINE = '\n' + + exec str(code) + + if out!=None: + res = out + + return res, style, header_html, footer_html, page_template + +# ==================================================================== + +def guess_type(m): + """ + Returns fieldtype depending on the MySQLdb Description + """ + import MySQLdb + if m in MySQLdb.NUMBER: + return 'Currency' + elif m in MySQLdb.DATE: + return 'Date' + else: + return 'Data' + +def build_description_simple(): + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + for m in webnotes.conn.get_description(): + colnames.append(m[0]) + coltypes.append(guess_type[m[0]]) + coloptions.append('') + colwidths.append('100') + + return colnames, coltypes, coloptions, colwidths + +# ==================================================================== + +def build_description_standard(meta, tl): + + desc = webnotes.conn.get_description() + + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + # merged metadata - used if we are unable to + # get both the table name and field name from + # the description - in case of joins + merged_meta = {} + for d in meta: + merged_meta.update(meta[d]) + + for f in desc: + fn, dt = f[0], '' + if '.' in fn: + dt, fn = fn.split('.') + + if (not dt) and merged_meta.get(fn): + # no "AS" given, find type from merged description + + desc = merged_meta[fn] + colnames.append(desc[0] or fn) + coltypes.append(desc[1] or '') + coloptions.append(desc[2] or '') + colwidths.append(desc[3] or '100') + + elif meta.get(dt,{}).has_key(fn): + # type specified for a multi-table join + # usually from Report Builder + + desc = meta[dt][fn] + colnames.append(desc[0] or fn) + coltypes.append(desc[1] or '') + coloptions.append(desc[2] or '') + colwidths.append(desc[3] or '100') + + else: + # nothing found + # guess + + colnames.append(fn) + coltypes.append(guess_type(f[1])) + coloptions.append('') + colwidths.append('100') + + return colnames, coltypes, coloptions, colwidths + +# Entry Point - Run the query +# ==================================================================== + +def runquery(q='', ret=0, from_export=0): + import webnotes.utils + + formatted = cint(form.getvalue('formatted')) + + # CASE A: Simple Query + # -------------------- + if form.getvalue('simple_query') or form.getvalue('is_simple'): + q = form.getvalue('simple_query') or form.getvalue('query') + if q.split()[0].lower() != 'select': + raise Exception, 'Query must be a SELECT' + + as_dict = cint(form.getvalue('as_dict')) + res = sql(q, as_dict = as_dict, as_list = not as_dict, formatted=formatted) + + # build colnames etc from metadata + colnames, coltypes, coloptions, colwidths = [], [], [], [] + + # CASE B: Standard Query + # ----------------------- + else: + if not q: q = form.getvalue('query') + + tl = get_sql_tables(q) + meta = get_sql_meta(tl) + + q = add_match_conditions(q, tl, webnotes.user.roles, webnotes.user.get_defaults()) + + # replace special variables + q = q.replace('__user', session['user']) + q = q.replace('__today', webnotes.utils.nowdate()) + + res = sql(q, as_list=1, formatted=formatted) + + colnames, coltypes, coloptions, colwidths = build_description_standard(meta, tl) + + # run server script + # ----------------- + style, header_html, footer_html, page_template = '', '', '', '' + if form.has_key('sc_id') and form.getvalue('sc_id'): + sc_id = form.getvalue('sc_id') + from webnotes.model.code import get_code + sc_details = webnotes.conn.sql("select module, standard, server_script from `tabSearch Criteria` where name=%s", sc_id)[0] + if sc_details[1]!='No': + code = get_code(sc_details[0], 'Search Criteria', sc_id, 'py') + else: + code = sc_details[2] + + if code: + filter_values = form.has_key('filter_values') and eval(form.getvalue('filter_values','')) or {} + res, style, header_html, footer_html, page_template = exec_report(code, res, colnames, colwidths, coltypes, coloptions, filter_values, q, from_export) + + out['colnames'] = colnames + out['coltypes'] = coltypes + out['coloptions'] = coloptions + out['colwidths'] = colwidths + out['header_html'] = header_html + out['footer_html'] = footer_html + out['page_template'] = page_template + + if style: + out['style'] = style + + # just the data - return + if ret==1: + return res + + out['values'] = res + + # return num of entries + qm = form.has_key('query_max') and form.getvalue('query_max') or '' + if qm and qm.strip(): + if qm.split()[0].lower() != 'select': + raise Exception, 'Query (Max) must be a SELECT' + if not form.has_key('simple_query'): + qm = add_match_conditions(qm, tl, webnotes.user.roles, webnotes.user.defaults) + + out['n_values'] = webnotes.utils.cint(sql(qm)[0][0]) + +# Export to CSV +# ==================================================================== + +def runquery_csv(): + from webnotes.utils import getCSVelement + + # run query + res = runquery(from_export = 1) + + q = form.getvalue('query') + + rep_name = form.getvalue('report_name') + if not form.has_key('simple_query'): + + # Report Name + if not rep_name: + rep_name = get_sql_tables(q)[0] + + if not rep_name: rep_name = 'DataExport' + + # Headings + heads = [] + for h in out['colnames']: + heads.append(getCSVelement(h)) + if form.has_key('colnames'): + for h in form.getvalue('colnames').split(','): + heads.append(getCSVelement(h)) + + # Output dataset + dset = [rep_name, ''] + if heads: + dset.append(','.join(heads)) + + # Data + for r in out['values']: + dset.append(','.join([getCSVelement(i) for i in r])) + + txt = '\n'.join(dset) + out['result'] = txt + out['type'] = 'csv' + out['doctype'] = rep_name diff --git a/cgi-bin/webnotes/widgets/search.py b/cgi-bin/webnotes/widgets/search.py new file mode 100644 index 0000000000..9d8da2b790 --- /dev/null +++ b/cgi-bin/webnotes/widgets/search.py @@ -0,0 +1,101 @@ +# Search +import webnotes + +# this is called when a new doctype is setup for search - to set the filters +def getsearchfields(): + + sf = webnotes.conn.sql("select search_fields from tabDocType where name=%s", webnotes.form.getvalue("doctype")) + sf = sf and sf[0][0] or '' + sf = [s.strip() for s in sf.split(',')] + if sf and sf[0]: + res = webnotes.conn.sql("select fieldname, label, fieldtype, options from tabDocField where parent='%s' and fieldname in (%s)" % (webnotes.form.getvalue("doctype","_NA"), '"'+'","'.join(sf)+'"')) + else: + res = [] + + res = [[c or '' for c in r] for r in res] + for r in res: + if r[2]=='Select' and r[3] and r[3].startswith('link:'): + dt = r[3][5:] + ol = webnotes.conn.sql("select name from `tab%s` where docstatus!=2 order by name asc" % dt) + r[3] = '\n'.join([''] + [o[0] for o in ol]) + + webnotes.response['searchfields'] = [['name', 'ID', 'Data', '']] + res + +def make_query(fields, dt, key, txt, start, length): + return """SELECT %(fields)s + FROM `tab%(dt)s` + WHERE `tab%(dt)s`.`%(key)s` LIKE '%(txt)s' AND `tab%(dt)s`.docstatus != 2 + ORDER BY `tab%(dt)s`.`%(key)s` + DESC LIMIT %(start)s, %(len)s """ % { + 'fields': fields, + 'dt': dt, + 'key': key, + 'txt': txt + '%', + 'start': start, + 'len': length + } + +def get_std_fields_list(dt, key): + # get additional search fields + sflist = webnotes.conn.sql("select search_fields from tabDocType where name = '%s'" % dt) + sflist = sflist and sflist[0][0] and sflist[0][0].split(',') or [] + + sflist = ['name'] + sflist + if not key in sflist: + sflist = sflist + [key] + + return ['`tab%s`.`%s`' % (dt, f.strip()) for f in sflist] + +def build_for_autosuggest(res): + from webnotes.utils import cstr + + results = [] + for r in res: + info = '' + if len(r) > 1: + info = ','.join([cstr(t) for t in r[1:]]) + if len(info) > 30: + info = info[:30] + '...' + + results.append({'id':r[0], 'value':r[0], 'info':info}) + return results + +def scrub_custom_query(query, key, txt): + if '%(key)s' in query: + query = query.replace('%(key)s', key) + if '%s' in query: + query = query.replace('%s', ((txt or '') + '%')) + return query + +# this is called by the Link Field +def search_link(): + import webnotes.widgets.query_builder + + txt = webnotes.form.getvalue('txt') + dt = webnotes.form.getvalue('dt') + query = webnotes.form.getvalue('query') + + if query: + res = webnotes.conn.sql(scrub_custom_query(query, 'name', txt)) + else: + q = make_query(', '.join(get_std_fields_list(dt, 'name')), dt, 'name', txt, '0', '10') + res = webnotes.widgets.query_builder.runquery(q, ret=1) + + # make output + webnotes.response['results'] = build_for_autosuggest(res) + +# this is called by the search box +def search_widget(): + import webnotes.widgets.query_builder + + dt = webnotes.form.getvalue('doctype') + txt = webnotes.form.getvalue('txt') or '' + key = webnotes.form.getvalue('searchfield') or 'name' # key field + user_query = webnotes.form.getvalue('query') or '' + + if user_query: + query = scrub_custom_query(user_query, key, txt) + else: + query = make_query(', '.join(get_std_fields_list(dt, key)), dt, key, txt, webnotes.form.getvalue('start') or 0, webnotes.form.getvalue('page_len') or 50) + + webnotes.widgets.query_builder.runquery(query) diff --git a/cgi-bin/webnotes/widgets/tags.py b/cgi-bin/webnotes/widgets/tags.py new file mode 100644 index 0000000000..b08429e8e8 --- /dev/null +++ b/cgi-bin/webnotes/widgets/tags.py @@ -0,0 +1,256 @@ +""" +Server side functions for tagging. + +- Tags can be added to any record (doctype, name) in the system. +- Items are filtered by tags +- Top tags are shown in the sidebar (?) +- Tags are also identified by the tag_fields property of the DocType + +Discussion: + +Tags are shown in the docbrowser and ideally where-ever items are searched. +There should also be statistics available for tags (like top tags etc) + + +Design: + +- free tags (user_tags) are stored in __user_tags +- doctype tags are set in tag_fields property of the doctype +- top tags merges the tags from both the lists (only refreshes once an hour (max)) + +""" + + +def check_user_tags(dt): + "if the user does not have a tags column, then it creates one" + try: + webnotes.conn.sql("select `_user_tags` from `tab%s` limit 1" % dt) + except Exception, e: + if e.args[0] == 1054: + DocTags(dt).setup() + + +# +# Add a new tag +# +def add_tag(): + "adds a new tag to a record, and creates the Tag master" + + f = webnotes.form_dict + tag, color = f.get('tag'), f.get('color') + dt, dn = f.get('dt'), f.get('dn') + + DocTags(dt).add(dn, tag) + + return tag + +# +# remove tag +# +def remove_tag(): + "removes tag from the record" + f = webnotes.form_dict + tag, dt, dn = f.get('tag'), f.get('dt'), f.get('dn') + + DocTags(dt).remove(dn, tag) + + + +import webnotes +from webnotes.utils import cint, cstr, load_json + +class DocTags: + """Tags for a particular doctype""" + def __init__(self, dt): + self.dt = dt + + def get_tag_fields(self): + """returns tag_fields property""" + return webnotes.conn.get_value('DocType', self.dt, 'tag_fields') + + def get_tags(self, dn): + """returns tag for a particular item""" + return webnotes.conn.get_value(self.dt, dn, '_user_tags') or '' + + def create(self, tag): + try: + webnotes.conn.sql("insert into tabTag(name) values (%s) on duplicate key ignore", tag) + except Exception, e: + if e.args[0]==1147: + self.setup_tag_master() + self.create(tag) + + def add(self, dn, tag): + """add a new user tag""" + self.create(tag) + tl = self.get_tags(dn).split(',') + if not tag in tl: + tl.append(tag) + self.update(dn, tl) + TagCounter(self.dt).update(tag, 1) + + def remove(self, dn, tag): + """remove a user tag""" + tl = self.get_tags(dn).split(',') + self.update(dn, filter(lambda x:x!=tag, tl)) + TagCounter(self.dt).update(tag, -1) + + def update(self, dn, tl): + """updates the _user_tag column in the table""" + + tl = list(set(filter(lambda x: x, tl))) + + try: + webnotes.conn.sql("update `tab%s` set _user_tags=%s where name=%s" % \ + (self.dt,'%s','%s'), (',' + ','.join(tl), dn)) + except Exception, e: + if e.args[0]==1054: + self.setup() + self.update(dn, tl) + else: raise e + + def setup_tags(self): + """creates the tabTag table if not exists""" + webnotes.conn.commit() + from webnotes.modules.module_manager import reload_doc + reload_doc('core','doctype','tag') + webnotes.conn.begin() + + def setup(self): + """adds the _user_tags column if not exists""" + webnotes.conn.commit() + webnotes.conn.sql("alter table `tab%s` add column `_user_tags` varchar(180)" % self.dt) + webnotes.conn.begin() + + + + + + + + +class TagCounter: + """ + Tag Counter stores tag count per doctype in table _tag_cnt + """ + def __init__(self, doctype): + self.doctype = doctype + + # setup / update tag cnt + # keeps tags in _tag_cnt (doctype, tag, cnt) + # if doctype cnt does not exist + # creates it for the first time + def update(self, tag, diff): + "updates tag cnt for a doctype and tag" + cnt = webnotes.conn.sql("select cnt from `_tag_cnt` where doctype=%s and tag=%s", (self.doctype, tag)) + + if not cnt: + # first time? build a cnt and add + self.new_tag(tag, 1) + else: + webnotes.conn.sql("update `_tag_cnt` set cnt = ifnull(cnt,0) + (%s) where doctype=%s and tag=%s",\ + (diff, self.doctype, tag)) + + + def new_tag(self, tag, cnt=0, dt=None): + "Creates a new row for the tag and doctype" + webnotes.conn.sql("insert into `_tag_cnt`(doctype, tag, cnt) values (%s, %s, %s)", \ + (dt or self.doctype, tag, cnt)) + + def build(self, dt): + "Builds / rebuilds the counting" + webnotes.conn.sql("delete from _tag_cnt where doctype=%s", dt) + + # count + tags = {} + for ut in webnotes.conn.sql("select _user_tags from `tab%s`" % dt): + if ut[0]: + tag_list = ut[0].split(',') + for t in tag_list: + if t: + tags[t] = tags.get(t, 0) + 1 + + # insert + for t in tags: + self.new_tag(t, tags[t], dt) + + def load_top(self): + try: + return webnotes.conn.sql("select tag, cnt from `_tag_cnt` where doctype=%s and cnt>0 order by cnt desc limit 10", self.doctype, as_list = 1) + except Exception, e: + if e.args[0]==1146: + self.setup() + return self.load_top() + else: raise e + + def setup(self): + "creates the tag cnt table from the DocType" + webnotes.conn.commit() + webnotes.conn.sql(""" + create table `_tag_cnt` ( + doctype varchar(180), tag varchar(22), cnt int(10), + primary key (doctype, tag), index cnt(cnt)) ENGINE=InnoDB + """) + webnotes.conn.begin() + + # build all + for dt in webnotes.conn.sql("select name from tabDocType where ifnull(issingle,0)=0 and docstatus<2"): + try: + self.build(dt[0]) + except Exception, e: + if e.args[0]==1054: pass + else: raise e + + + + +def get_top_field_tags(dt): + tf = webnotes.conn.get_value('DocType', dt, 'tag_fields') + if not tf: return [] + + # restrict to only 2 fields + tf = tuple(set(tf.split(',')))[:2] + tl = [] + + for t in tf: + t = t.strip() + # disastrous query but lets try it! + tl += webnotes.conn.sql("""select `%s`, count(*), '%s' from `tab%s` + where docstatus!=2 + and ifnull(`%s`, '')!='' + group by `%s` + order by count(*) desc + limit 10""" % (t, t, dt, t, t), as_list=1) + + if tl: + tl.sort(lambda x, y: y[1]-x[1]) + + return tl[:10] + +# returns the top ranked 10 tags for the +# doctype. +# merges the top tags from fields and user tags +def get_top_tags(args=''): + "returns the top 10 tags for the doctype from fields (7) and users (3)" + tl = None + dt = webnotes.form_dict['doctype'] + + from webnotes.utils.cache import get_item + + # if not reload, try and load from cache + if not cint(webnotes.form_dict.get('refresh')): + tl = get_item('tags-' + dt).get() + + if tl: + return eval(tl) + else: + tl = TagCounter(dt).load_top() + get_top_field_tags(dt) + if tl: + tl.sort(lambda x, y: y[1]-x[1]) + tl = tl[:20] + + # set in cache and don't reload for an hour + get_item('tags-' + dt).set(tl, 60*60) + + return tl + diff --git a/cgi-bin/webnotes/widgets/todo.py b/cgi-bin/webnotes/widgets/todo.py new file mode 100644 index 0000000000..40a118cd97 --- /dev/null +++ b/cgi-bin/webnotes/widgets/todo.py @@ -0,0 +1,49 @@ +# ToDO and Reminder +# ----------------- + +def add_todo(user, date, priority, desc, ref_type, ref_name): + nlist = [] + if type(user)==list: + for i in user: + nlist.append(add_todo_item(i, date, priority, desc, ref_type, ref_name)) + return nlist + else: + return add_todo_item(user, date, priority, desc, ref_type, ref_name) + +def add_todo_item(user, date, priority, desc, ref_type, ref_name): + if not date: + date = nowdate() + + d = Document('ToDo Item') + d.owner = user + d.date = date + d.priority = priority + d.description = desc + d.reference_type = ref_type + d.reference_name = ref_name + d.save(1) + return d.name + +def remove_todo(name): + if type(name)==list: + for i in name: + sql("delete from `tabToDo Item` where name='%s'" % i) + else: + sql("delete from `tabToDo Item` where name='%s'" % name) + +def get_todo_list(): + c = getcursor() + try: + role_options = ["role = '"+r+"'" for r in roles] + role_options = role_options and ' OR ' + ' OR '.join(role_options) or '' + c.execute("select * from `tabToDo Item` where owner='%s' %s" % (session['user'], role_options)) + except: # deprecated + c.execute("select * from `tabToDo Item` where owner='%s'" % session['user']) + dataset = c.fetchall() + l = [] + for i in range(len(dataset)): + d = Document('ToDo Item') + d.loadfields(dataset, i, c.description) + l.append(d) + + return l \ No newline at end of file diff --git a/change_log.txt b/change_log.txt new file mode 100644 index 0000000000..45b039f665 --- /dev/null +++ b/change_log.txt @@ -0,0 +1,143 @@ +# Framework change log + +# TODO +# ------- + +- renaming on first save - change to observer style +- table border issue in FF +- defaults in single? + +# LOG +# -------- + +15-Feb-08: + +- Rechanged structure to make it cleaner / CMS Friendly +- to make cgi run from anywhere + +23-Feb-08 + +- to start a new server + + - Concept: every server must have a base account called 'accounts' + - All different accounts on the server are logged in 'accounts' + + - make accounts database + - set accounts details in defs.py + - execute setup.cgi + - make "Account" doctype in the first database + - ac_name, db_name, db_login + - Autoname- field:ac_name + + - make account "accounts" with related db_name + +5-March-08 + +- added __account in each server call to avoid multiple login account + - exceptions : login and initdata (refresh) +- added __modified in savedocs to match if document has not been saved in between + and is the current copy in the database +- added hide for tablefield +- updated get_status in field +- added remove child function +- added print functionality to datatable +- added msgprint and errprint +- added freeze and unfreezing + +11-March-08 + +- added ip address blocking + - add ip_address in Profile to block +- client side triggers using "cscript" property +- activate / deactivate field in table (no triggers) + +14-March-08 + +- app2: onload function passed to copy_doc +- app2: allow_on_submit now works in Cancel +- app2: IE7 main heading bug fixed - was happening due to click->hide calendar??? + - change: create calendar first time on show. +- changed messaging logic + - all msgprints will be printed + - r.message is now r.server_messages + +15-16-March-08 + +- created Report API + - see test report + + +17-March-08 + +- activation logic changed for new rows in grids, + - make_newrow is called from add_template if there is no docname +- changes in report for page breaks + +21-March-08 + +- added trigger on section break +- multiple columns on link +- no print until submitted +- docstatus of submitted and cancelled documents changed for child elements + +26-March-08 + +- complete drill down + - added feature to have function executed + - added feature to have custom result + + +10-Apr-08 + +- Amendment added to Frm / Permissions + +14-Apr-08 + +- Finder 2.0 + +6-May-08 + +- Included AutoSuggest + +19-Dec-08 + +PIL --- Installation + +1. Donwload + unzip +2. python setup.py -build_ext -i +3. python selftest.py +4. python setup.py install + +To install jpeg library.. Download jpeg-6b + +1. ./configure --enable-shared --enable-static +2. make +3. make install + +09-July-09 + +- to start a new server + + - set server_prefix in defs.py + - open python shell, + - import server + - server.import_db('Framework') + + - set appropriate details in defs.py + + +31-July-09 + +mysqldump('s2u019','../data/') +create_account('xx','s2u019.sql') + +18-Sep-09 + +matplotlib - numpy, + + +------- Updates in httpd.conf + +RewriteEngine On +RewriteRule ^/uploads/(.*)$ /cgi-bin/getfile.cgi?name=$1 +RewriteRule \.py - [F] \ No newline at end of file diff --git a/compress.py b/compress.py new file mode 100644 index 0000000000..0ea1b6c79e --- /dev/null +++ b/compress.py @@ -0,0 +1,424 @@ +in_files_main = [ + 'utils/rsh.compressed.js' + ,'globals.js' + ,'utils/datatype.js' + ,'utils/browser_detect.js' + ,'utils/datetime.js' + ,'utils/dom.js' + ,'utils/handler.js' + ,'utils/msgprint.js' + ,'utils/json.js' + ,'utils/printElement.js' + ,'wn/widgets/dialog.js' + ,'widgets/dialog.js' + ,'widgets/listing.js' + ,'wn/widgets/listing.js' + ,'widgets/tree.js' + ,'widgets/menu.js' + ,'widgets/layout.js' + ,'widgets/tabbedpage.js' + ,'webpage/page_header.js' + ,'widgets/autosuggest.js' + ,'widgets/select.js' + ,'widgets/tags.js' + ,'widgets/export_query.js' + ,'widgets/list_selector.js' + ,'widgets/form/fields.js' + ,'webpage/wntoolbar.js' + ,'webpage/history.js' + ,'webpage/search.js' + ,'webpage/spinner.js' + ,'webpage/freeze_page.js' + ,'webpage/error_console.js' + ,'webpage/about.js' + ,'webpage/loaders.js' + ,'webpage/uploader.js' + ,'webpage/page.js' + ,'webpage/docbrowser.js' + ,'wn/page_layout.js' + #,'wn/widgets/doc_column_view.js' + ,'wn/widgets/page_sidebar.js' + ,'wn/widgets/footer.js' + #,'wn/widgets/follow.js' + ,'model/local_data.js' + ,'model/doclist.js' + ,'webpage/body.js' + ,'app.js' + ,'widgets/calendar.js' + ] + +out_file_main = 'js/wnf.compressed.js' + +#------------------------------------------------- + +in_files_lite = [ + 'utils/rsh.compressed.js' + ,'globals.js' + ,'utils/datatype.js' + ,'utils/browser_detect.js' + ,'utils/datetime.js' + ,'utils/dom.js' + ,'utils/handler.js' + ,'utils/msgprint.js' + ,'utils/json.js' + ,'wn/widgets/dialog.js' + ,'widgets/dialog.js' + ,'widgets/listing.js' + ,'widgets/layout.js' + ,'widgets/tabbedpage.js' + ,'webpage/page_header.js' + ,'widgets/autosuggest.js' + ,'widgets/tags.js' + ,'widgets/form/fields.js' + ,'webpage/history.js' + ,'webpage/search.js' + ,'webpage/spinner.js' + ,'webpage/freeze_page.js' + ,'webpage/error_console.js' + ,'webpage/about.js' + ,'webpage/loaders.js' + ,'webpage/uploader.js' + ,'webpage/page.js' + ,'wn/widgets/page_sidebar.js' + ,'wn/widgets/follow.js' + ,'model/local_data.js' + ,'model/doclist.js' + ,'webpage/body.js' + ,'app.js' + ] + +out_file_lite = 'js/wnf-lite.compressed.js' + +#------------------------------------------------- + +in_files_form = [ + 'widgets/form/form_container.js' + ,'widgets/form/form_header.js' + ,'widgets/form/form.js' + ,'widgets/form/form_fields.js' + ,'widgets/form/grid.js' + ,'widgets/form/form_grid.js' + ,'widgets/form/print_format.js' + ,'widgets/form/email.js' + ,'widgets/form/clientscriptAPI.js' + ,'widgets/form/form_comments.js' + ,'wn/widgets/form/sidebar.js' + ,'wn/widgets/form/comments.js' + ,'wn/widgets/form/attachments.js' +] + +out_file_form = 'js/form.compressed.js'; + +in_files_report = [ + 'widgets/report_builder/bargraph.js' + ,'widgets/report_builder/report_builder.js' + ,'widgets/report_builder/datatable.js' + ,'widgets/report_builder/calculator.js' +] + +out_file_report = 'js/report.compressed.js' + +in_files_css = [ + 'css/body.css', + 'css/menus.css', + 'css/messages.css', + 'css/forms.css', + 'css/grid.css', + 'css/listing.css', + 'css/report.css', + 'css/calendar.css', + 'css/autosuggest.css', + 'css/dialog.css', + 'css/wntoolbar.css', + 'css/tabs.css', + 'css/jqplot.css', + 'css/bw-icons.css', + 'css/sidebar.css', + 'css/doc_column_view.css', +] + +out_file_css = 'css/default.css' + + + +#in_files_main += in_files_form + +import os, os.path, shutil + +# This code is original from jsmin by Douglas Crockford, it was translated to +# Python by Baruch Even. The original code had the following copyright and +# license. +# +# /* jsmin.c +# 2007-05-22 +# +# Copyright (c) 2002 Douglas Crockford (www.crockford.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# The Software shall be used for Good, not Evil. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# */ + +from StringIO import StringIO + +def jsmin(js): + ins = StringIO(js) + outs = StringIO() + JavascriptMinify().minify(ins, outs) + str = outs.getvalue() + if len(str) > 0 and str[0] == '\n': + str = str[1:] + return str + +def isAlphanum(c): + """return true if the character is a letter, digit, underscore, + dollar sign, or non-ASCII character. + """ + return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or + (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126)); + +class UnterminatedComment(Exception): + pass + +class UnterminatedStringLiteral(Exception): + pass + +class UnterminatedRegularExpression(Exception): + pass + +class JavascriptMinify(object): + + def _outA(self): + self.outstream.write(self.theA) + def _outB(self): + self.outstream.write(self.theB) + + def _get(self): + """return the next character from stdin. Watch out for lookahead. If + the character is a control character, translate it to a space or + linefeed. + """ + c = self.theLookahead + self.theLookahead = None + if c == None: + c = self.instream.read(1) + if c >= ' ' or c == '\n': + return c + if c == '': # EOF + return '\000' + if c == '\r': + return '\n' + return ' ' + + def _peek(self): + self.theLookahead = self._get() + return self.theLookahead + + def _next(self): + """get the next character, excluding comments. peek() is used to see + if an unescaped '/' is followed by a '/' or '*'. + """ + c = self._get() + if c == '/' and self.theA != '\\': + p = self._peek() + if p == '/': + c = self._get() + while c > '\n': + c = self._get() + return c + if p == '*': + c = self._get() + while 1: + c = self._get() + if c == '*': + if self._peek() == '/': + self._get() + return ' ' + if c == '\000': + raise UnterminatedComment() + + return c + + def _action(self, action): + """do something! What you do is determined by the argument: + 1 Output A. Copy B to A. Get the next B. + 2 Copy B to A. Get the next B. (Delete A). + 3 Get the next B. (Delete B). + action treats a string as a single character. Wow! + action recognizes a regular expression if it is preceded by ( or , or =. + """ + if action <= 1: + self._outA() + + if action <= 2: + self.theA = self.theB + if self.theA == "'" or self.theA == '"': + while 1: + self._outA() + self.theA = self._get() + if self.theA == self.theB: + break + if self.theA <= '\n': + raise UnterminatedStringLiteral() + if self.theA == '\\': + self._outA() + self.theA = self._get() + + + if action <= 3: + self.theB = self._next() + if self.theB == '/' and (self.theA == '(' or self.theA == ',' or + self.theA == '=' or self.theA == ':' or + self.theA == '[' or self.theA == '?' or + self.theA == '!' or self.theA == '&' or + self.theA == '|' or self.theA == ';' or + self.theA == '{' or self.theA == '}' or + self.theA == '\n'): + self._outA() + self._outB() + while 1: + self.theA = self._get() + if self.theA == '/': + break + elif self.theA == '\\': + self._outA() + self.theA = self._get() + elif self.theA <= '\n': + raise UnterminatedRegularExpression() + self._outA() + self.theB = self._next() + + + def _jsmin(self): + """Copy the input to the output, deleting the characters which are + insignificant to JavaScript. Comments will be removed. Tabs will be + replaced with spaces. Carriage returns will be replaced with linefeeds. + Most spaces and linefeeds will be removed. + """ + self.theA = '\n' + self._action(3) + + while self.theA != '\000': + if self.theA == ' ': + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + elif self.theA == '\n': + if self.theB in ['{', '[', '(', '+', '-']: + self._action(1) + elif self.theB == ' ': + self._action(3) + else: + if isAlphanum(self.theB): + self._action(1) + else: + self._action(2) + else: + if self.theB == ' ': + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + elif self.theB == '\n': + if self.theA in ['}', ']', ')', '+', '-', '"', '\'']: + self._action(1) + else: + if isAlphanum(self.theA): + self._action(1) + else: + self._action(3) + else: + self._action(1) + + def minify(self, instream, outstream): + self.instream = instream + self.outstream = outstream + self.theA = '\n' + self.theB = None + self.theLookahead = None + + self._jsmin() + self.instream.close() + +def combine_css(): + global out_file_css, in_files_css + + data = '' + for f in in_files_css: + fh = open(f, 'read') + data += fh.read() + '\n' + fh.close() + + out_file = open(out_file_css, 'w') + out_file.write(data) + out_file.close() + +def _compress(in_files, out_file, in_type='js', verbose=False, + temp_file='.temp'): + + import os + + temp = open(temp_file, 'w') + for f in in_files: + print f + ' | ' + str(int(os.path.getsize('js/'+f)/1024)) + 'k' + + fh = open('js/' + f) + data = fh.read() + '\n' + fh.close() + + temp.write(data) + + #print ' + %s' % f + temp.close() + + out = open(out_file, 'w') + + jsm = JavascriptMinify() + jsm.minify(open(temp_file,'r'), out) + + out.close() + + org_size = os.path.getsize(temp_file) + new_size = os.path.getsize(out_file) + + print '=> %s' % out_file + print 'Original: %.2f kB' % (org_size / 1024.0) + print 'Compressed: %.2f kB' % (new_size / 1024.0) + print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100) + print '' + + os.remove(temp_file) + + +if __name__=='__main__': + import sys + if sys.argv[1]=='main': + _compress(in_files_main, out_file_main) + elif sys.argv[1]=='lite': + _compress(in_files_lite, out_file_lite) + elif sys.argv[1]=='form': + _compress(in_files_form, out_file_form) + elif sys.argv[1]=='report': + _compress(in_files_report, out_file_report) + elif sys.argv[1]=='css': + combine_css() + else: + print 'parameter must be one of main, lite, css, form or report' + diff --git a/css/autosuggest.css b/css/autosuggest.css new file mode 100644 index 0000000000..991221b084 --- /dev/null +++ b/css/autosuggest.css @@ -0,0 +1,91 @@ +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +div.autosuggest +{ + position: absolute; + margin-top: 3px; + border: 1px solid #222; +} + +div.autosuggest ul +{ + list-style: none; + margin: 0px; + padding: 2px; + overflow: hidden; + background-color: #FFF; +} + +div.autosuggest ul li +{ + color: #444; + padding: 0; + margin: 0; + text-align: left; +} + +div.autosuggest ul li a +{ + color: #444; + display: block; + text-decoration: none; + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + +} +div.autosuggest ul li.as_highlight a:hover +{ + background-color: #45A; + color: #FFF; +} + +div.autosuggest ul li a span +{ + display: block; + padding: 3px 6px; + color: #444; + border-bottom:1px solid #DDD; +} + +div.autosuggest ul li a span small +{ + display: block; + font-weight: normal; + color: #444; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: #FFF; +} + +div.autosuggest ul li.as_highlight a span { + color: #FFF; +} + +div.autosuggest ul li.as_highlight a +{ + color: #FFF; + background-color: #45A; + cursor: pointer; +} + +div.autosuggest ul li.as_warning +{ + font-weight: bold; + text-align: center; +} + +div.autosuggest ul em +{ + font-style: normal; + font-weight: bold; +} diff --git a/css/body.css b/css/body.css new file mode 100644 index 0000000000..3fa852c5b6 --- /dev/null +++ b/css/body.css @@ -0,0 +1,108 @@ +html { + margin: 0px; + padding: 0px; +} + +body { + margin: 0px; + padding: 0px; + font-family: Arial, Helvetica, Sans; + font-size: 12px; + color: #000; +} + +input, select, button { font-size: 12px; font-family: Arial, Helvetica, Sans; } + +li { margin: 4px; } + +h1, h2, h3, h4, h5 { + font-family: Tahoma, Sans; + font-weight: normal; +} + +h1 { margin: 8px 0px; padding: 0px; font-size: 27px; } +h2 { margin: 8px 0px; padding: 0px; font-size: 23px; } +h3 { margin: 4px 0px; padding: 0px; font-size: 17px; } +h4 { margin: 2px 0px; padding: 0px; font-size: 13px; } +h5 { margin: 2px 0px; padding: 0px; font-size: 13px; } + +pre { margin: 0px; padding: 0px; } + +button { margin: 2px; margin-left: 0px; } + +select, input, textarea { + border: 1px solid #AAA; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + font-size: 13px + padding: 2px; +} + +textarea { font-family: arial, helvetica, sans serif; height: 120px; width: 90%; overflow-x: auto; font-size: 12px; } + +table { padding: 0px; border-collapse: 'collapse'} + +td { padding:0px; margin: 0px; vertical-align: top; } + +a:active { outline:none; } + +:focus { -moz-outline-style:none; } + +table.simpletable { border-collapse: collapse; margin-bottom: 10px;} +table.simpletable td {border: 1pt solid #000; vertical-align: top; padding: 2px; } + +div.fix_ff_cursor { overflow: auto; } + +/* --- Layout --- */ + +div.comment { color: #444; } + +div#body_div { + position: relative; + display: none; +} + +div.no_script { + display: none; +} + +div.loading_div { + position: absolute; + background-color: #FFFFCC; + z-index: 1999; + right: 5px; + width: 90px; + display: none; + text-align: center; + padding: 2px; + font-size: 12px; + border: 1px solid #FF4; +} + + +div#head_div { background-color: #FFF; } + +#head_banner { background-color: #FFF; } + +.link_type { + padding:2px; + color: #00b; + text-decoration: underline; + cursor: pointer; +} + +.link_type:hover { + color: #fff !important; + background-color: #07b; + text-decoration: none; +} + +div.std-footer { + margin: 13px 0px; + border-top: 1px solid #AAA; + padding: 13px; +} + +div.std-footer-item { + margin: 0px 13px 13px 0px; +} \ No newline at end of file diff --git a/css/bw-icons.css b/css/bw-icons.css new file mode 100644 index 0000000000..4f42de4488 --- /dev/null +++ b/css/bw-icons.css @@ -0,0 +1,250 @@ + +/** general icons **/ + +.wn-icon { background: url('../images/icons/icons.png'); width: 16px; height: 16px; cursor: pointer; } +.ic-2x2_grid { background-position: 0 0; } +.ic-3x3_grid { background-position: 0 -36px; } +.ic-3x3_grid_2 { background-position: 0 -72px; } +.ic-air_signal { background-position: 0 -108px; } +.ic-align_center { background-position: 0 -144px; } +.ic-align_just { background-position: 0 -180px; } +.ic-align_left { background-position: 0 -216px; } +.ic-align_right { background-position: 0 -252px; } +.ic-app_window { background-position: 0 -288px; } +.ic-arrow_bottom { background-position: 0 -324px; } +.ic-arrow_bottom_left { background-position: 0 -360px; } +.ic-arrow_bottom_right { background-position: 0 -396px; } +.ic-arrow_l { background-position: 0 -432px; } +.ic-arrow_left { background-position: 0 -468px; } +.ic-arrow_r { background-position: 0 -504px; } +.ic-arrow_right { background-position: 0 -540px; } +.ic-arrow_top { background-position: 0 -576px; } +.ic-arrow_top_left { background-position: 0 -612px; } +.ic-arrow_top_right { background-position: 0 -648px; } +.ic-arrow_two_head { background-position: 0 -684px; } +.ic-arrow_two_head_2 { background-position: 0 -720px; } +.ic-attention { background-position: 0 -756px; } +.ic-battery { background-position: 0 -792px; } +.ic-bell { background-position: 0 -828px; } +.ic-book { background-position: 0 -864px; } +.ic-bookmark_1 { background-position: 0 -900px; } +.ic-bookmark_2 { background-position: 0 -936px; } +.ic-box { background-position: 0 -972px; } +.ic-br_down { background-position: 0 -1008px; } +.ic-br_next { background-position: 0 -1044px; } +.ic-br_prev { background-position: 0 -1080px; } +.ic-br_up { background-position: 0 -1116px; } +.ic-brackets { background-position: 0 -1152px; } +.ic-browser { background-position: 0 -1188px; } +.ic-brush { background-position: 0 -1224px; } +.ic-bug { background-position: 0 -1260px; } +.ic-burst { background-position: 0 -1296px; } +.ic-calc { background-position: 0 -1332px; } +.ic-calendar_1 { background-position: 0 -1368px; } +.ic-calendar_2 { background-position: 0 -1404px; } +.ic-cancel { background-position: 0 -1440px; } +.ic-case { background-position: 0 -1476px; } +.ic-cc { background-position: 0 -1512px; } +.ic-cert { background-position: 0 -1548px; } +.ic-chart_bar { background-position: 0 -1584px; } +.ic-chart_line { background-position: 0 -1620px; } +.ic-chart_line_2 { background-position: 0 -1656px; } +.ic-chart_pie { background-position: 0 -1692px; } +.ic-checkbox_checked { background-position: 0 -1728px; } +.ic-checkbox_unchecked { background-position: 0 -1764px; } +.ic-checkmark { background-position: 0 -1800px; } +.ic-clip { background-position: 0 -1836px; } +.ic-clipboard_copy { background-position: 0 -1872px; } +.ic-clipboard_cut { background-position: 0 -1908px; } +.ic-clipboard_past { background-position: 0 -1944px; } +.ic-clock { background-position: -36px 0; } +.ic-cloud { background-position: -36px -36px; } +.ic-cloud_rain { background-position: -36px -72px; } +.ic-cog { background-position: -36px -108px; } +.ic-comp { background-position: -36px -144px; } +.ic-compass { background-position: -36px -180px; } +.ic-contact_card { background-position: -36px -216px; } +.ic-cube { background-position: -36px -252px; } +.ic-cur_bp { background-position: -36px -288px; } +.ic-cur_dollar { background-position: -36px -324px; } +.ic-cur_euro { background-position: -36px -360px; } +.ic-cur_yen { background-position: -36px -396px; } +.ic-cursor_H_split { background-position: -36px -432px; } +.ic-cursor_V_split { background-position: -36px -468px; } +.ic-cursor_arrow { background-position: -36px -504px; } +.ic-cursor_drag_arrow { background-position: -36px -540px; } +.ic-cursor_drag_arrow_2 { background-position: -36px -576px; } +.ic-cursor_drag_hand { background-position: -36px -612px; } +.ic-cursor_hand { background-position: -36px -648px; } +.ic-db { background-position: -36px -684px; } +.ic-delete { background-position: -36px -720px; } +.ic-doc_delete { background-position: -36px -756px; } +.ic-doc_edit { background-position: -36px -792px; } +.ic-doc_empty { background-position: -36px -828px; } +.ic-doc_export { background-position: -36px -864px; } +.ic-doc_import { background-position: -36px -900px; } +.ic-doc_lines { background-position: -36px -936px; } +.ic-doc_lines_stright { background-position: -36px -972px; } +.ic-doc_minus { background-position: -36px -1008px; } +.ic-doc_new { background-position: -36px -1044px; } +.ic-doc_plus { background-position: -36px -1080px; } +.ic-document { background-position: -36px -1116px; } +.ic-download { background-position: -36px -1152px; } +.ic-emotion_sad { background-position: -36px -1188px; } +.ic-emotion_smile { background-position: -36px -1224px; } +.ic-expand { background-position: -36px -1260px; } +.ic-eye { background-position: -36px -1296px; } +.ic-eye_inv { background-position: -36px -1332px; } +.ic-facebook { background-position: -36px -1368px; } +.ic-filter { background-position: -36px -1404px; } +.ic-fire { background-position: -36px -1440px; } +.ic-flag { background-position: -36px -1476px; } +.ic-folder { background-position: -36px -1512px; } +.ic-folder_arrow { background-position: -36px -1548px; } +.ic-folder_delete { background-position: -36px -1584px; } +.ic-folder_minus { background-position: -36px -1620px; } +.ic-folder_open { background-position: -36px -1656px; } +.ic-folder_plus { background-position: -36px -1692px; } +.ic-font_bold { background-position: -36px -1728px; } +.ic-font_italic { background-position: -36px -1764px; } +.ic-font_size { background-position: -36px -1800px; } +.ic-font_strokethrough { background-position: -36px -1836px; } +.ic-font_underline { background-position: -36px -1872px; } +.ic-game_pad { background-position: -36px -1908px; } +.ic-globe_1 { background-position: -36px -1944px; } +.ic-globe_2 { background-position: -72px 0; } +.ic-globe_3 { background-position: -72px -36px; } +.ic-google { background-position: -72px -72px; } +.ic-hand_1 { background-position: -72px -108px; } +.ic-hand_2 { background-position: -72px -144px; } +.ic-hand_contra { background-position: -72px -180px; } +.ic-hand_pro { background-position: -72px -216px; } +.ic-headphones { background-position: -72px -252px; } +.ic-heart { background-position: -72px -288px; } +.ic-heart_empty { background-position: -72px -324px; } +.ic-home { background-position: -72px -360px; } +.ic-image_text { background-position: -72px -396px; } +.ic-inbox { background-position: -72px -432px; } +.ic-indent_decrease { background-position: -72px -468px; } +.ic-indent_increase { background-position: -72px -504px; } +.ic-info { background-position: -72px -540px; } +.ic-iphone { background-position: -72px -576px; } +.ic-key { background-position: -72px -612px; } +.ic-layers_1 { background-position: -72px -648px; } +.ic-layers_2 { background-position: -72px -684px; } +.ic-lightbulb { background-position: -72px -720px; } +.ic-lighting { background-position: -72px -756px; } +.ic-link { background-position: -72px -792px; } +.ic-list_bullets { background-position: -72px -828px; } +.ic-list_num { background-position: -72px -864px; } +.ic-magic_wand { background-position: -72px -900px; } +.ic-mail { background-position: -72px -936px; } +.ic-mail_2 { background-position: -72px -972px; } +.ic-mic { background-position: -72px -1008px; } +.ic-monitor { background-position: -72px -1044px; } +.ic-movie { background-position: -72px -1080px; } +.ic-music { background-position: -72px -1116px; } +.ic-net_comp { background-position: -72px -1152px; } +.ic-network { background-position: -72px -1188px; } +.ic-notepad { background-position: -72px -1224px; } +.ic-notepad_2 { background-position: -72px -1260px; } +.ic-on-off { background-position: -72px -1296px; } +.ic-openid { background-position: -72px -1332px; } +.ic-padlock_closed { background-position: -72px -1368px; } +.ic-padlock_open { background-position: -72px -1404px; } +.ic-page_layout { background-position: -72px -1440px; } +.ic-paragraph { background-position: -72px -1476px; } +.ic-pencil { background-position: -72px -1512px; } +.ic-phone { background-position: -72px -1548px; } +.ic-phone_1 { background-position: -72px -1584px; } +.ic-phone_2 { background-position: -72px -1620px; } +.ic-phone_touch { background-position: -72px -1656px; } +.ic-photo { background-position: -72px -1692px; } +.ic-picture { background-position: -72px -1728px; } +.ic-pin { background-position: -72px -1764px; } +.ic-pin_2 { background-position: -72px -1800px; } +.ic-pin_map { background-position: -72px -1836px; } +.ic-pin_map_down { background-position: -72px -1872px; } +.ic-pin_map_left { background-position: -72px -1908px; } +.ic-pin_map_right { background-position: -72px -1944px; } +.ic-pin_map_top { background-position: -108px 0; } +.ic-pin_sq_down { background-position: -108px -36px; } +.ic-pin_sq_left { background-position: -108px -72px; } +.ic-pin_sq_right { background-position: -108px -108px; } +.ic-pin_sq_top { background-position: -108px -144px; } +.ic-playback_ff { background-position: -108px -180px; } +.ic-playback_next { background-position: -108px -216px; } +.ic-playback_pause { background-position: -108px -252px; } +.ic-playback_play { background-position: -108px -288px; } +.ic-playback_prev { background-position: -108px -324px; } +.ic-playback_rec { background-position: -108px -360px; } +.ic-playback_reload { background-position: -108px -396px; } +.ic-playback_rew { background-position: -108px -432px; } +.ic-playback_stop { background-position: -108px -468px; } +.ic-preso { background-position: -108px -504px; } +.ic-print { background-position: -108px -540px; } +.ic-question { background-position: -108px -576px; } +.ic-redo { background-position: -108px -612px; } +.ic-rnd_br_down { background-position: -108px -648px; } +.ic-rnd_br_first { background-position: -108px -684px; } +.ic-rnd_br_last { background-position: -108px -720px; } +.ic-rnd_br_next { background-position: -108px -756px; } +.ic-rnd_br_prev { background-position: -108px -792px; } +.ic-rnd_br_up { background-position: -108px -828px; } +.ic-round { background-position: -108px -864px; } +.ic-round_and_up { background-position: -108px -900px; } +.ic-round_arrow_left { background-position: -108px -936px; } +.ic-round_arrow_right { background-position: -108px -972px; } +.ic-round_checkmark { background-position: -108px -1008px; } +.ic-round_delete { background-position: -108px -1044px; } +.ic-round_minus { background-position: -108px -1080px; } +.ic-round_plus { background-position: -108px -1116px; } +.ic-rss { background-position: -108px -1152px; } +.ic-rss_sq { background-position: -108px -1188px; } +.ic-sand { background-position: -108px -1224px; } +.ic-sat_dish { background-position: -108px -1260px; } +.ic-save { background-position: -108px -1296px; } +.ic-server { background-position: -108px -1332px; } +.ic-share { background-position: -108px -1368px; } +.ic-shop_cart { background-position: -108px -1404px; } +.ic-sound_high { background-position: -108px -1440px; } +.ic-sound_low { background-position: -108px -1476px; } +.ic-sound_mute { background-position: -108px -1512px; } +.ic-spechbubble { background-position: -108px -1548px; } +.ic-spechbubble_2 { background-position: -108px -1584px; } +.ic-spechbubble_sq { background-position: -108px -1620px; } +.ic-spechbubble_sq_line { background-position: -108px -1656px; } +.ic-sq_br_down { background-position: -108px -1692px; } +.ic-sq_br_first { background-position: -108px -1728px; } +.ic-sq_br_last { background-position: -108px -1764px; } +.ic-sq_br_next { background-position: -108px -1800px; } +.ic-sq_br_prev { background-position: -108px -1836px; } +.ic-sq_br_up { background-position: -108px -1872px; } +.ic-sq_down { background-position: -108px -1908px; } +.ic-sq_minus { background-position: -108px -1944px; } +.ic-sq_next { background-position: -144px 0; } +.ic-sq_plus { background-position: -144px -36px; } +.ic-sq_prev { background-position: -144px -72px; } +.ic-sq_up { background-position: -144px -108px; } +.ic-square_shape { background-position: -144px -144px; } +.ic-star { background-position: -144px -180px; } +.ic-star_fav { background-position: -144px -216px; } +.ic-star_fav_empty { background-position: -144px -252px; } +.ic-sun { background-position: -144px -288px; } +.ic-tag { background-position: -144px -324px; } +.ic-tape { background-position: -144px -360px; } +.ic-target { background-position: -144px -396px; } +.ic-text_curstor { background-position: -144px -432px; } +.ic-text_letter_t { background-position: -144px -468px; } +.ic-top_right_expand { background-position: -144px -504px; } +.ic-trash { background-position: -144px -540px; } +.ic-twitter { background-position: -144px -576px; } +.ic-twitter_2 { background-position: -144px -612px; } +.ic-undo { background-position: -144px -648px; } +.ic-user { background-position: -144px -684px; } +.ic-users { background-position: -144px -720px; } +.ic-wrench { background-position: -144px -756px; } +.ic-wrench_plus { background-position: -144px -792px; } +.ic-wrench_plus_2 { background-position: -144px -828px; } +.ic-zoom { background-position: -144px -864px; } + diff --git a/css/calendar.css b/css/calendar.css new file mode 100644 index 0000000000..1637889cfd --- /dev/null +++ b/css/calendar.css @@ -0,0 +1,171 @@ +/**** CALENDAR ****/ + +.caldiv { + position:absolute; + visibility:hidden; + background-color:white; + width: 144px; + z-index: 301; /* always on top(?) */ +} + + + +div.cal_wrapper { } +div.cal_body { + margin: 16px; + background-color: #DDD; + position: relative; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.cal_head { + margin: 16px; + margin-bottom: 0px; +} +div.cal_head div { + font-size: 18px; + color: #666; + padding-top: 8px; +} + +div.cal_view_body { + margin: 16px; +} + +div.cal_view_body_plain { + margin: 16px; +} + +div.cal_month_head { +} + +div.cal_month_body { + border-top: 1px solid #888; +} + +.cal_month_headtable { + /*table-layout:fixed;*/ + width: 100%; +} + +.cal_month_name { + width: 100%; + color: #888; + font-size: 14px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +.cal_month_headtable tr td{ + font-size: 12px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +table.cal_month_table { + border-collapse: collapse; + /*table-layout:fixed;*/ + height: 100%; + width: 100%; +} + +table.cal_month_table td { + width: 14.29%; + height: 20%; + /*overflow:hidden;*/ + padding:0px; +} + +div.cal_month_date { + width:100%; + height:25%; + font-size: 10px; + overflow:hidden; + /*background-color: #EEF;*/ +} + +div.cal_month_date_holiday { + /*background-color: #FFF;*/ +} + +div.cal_month_unit { + width:100%; + height:75%; + overflow:hidden; + cursor:pointer; + /*background-color:#FFF;*/ +} + +div.cal_vu_disabled { + background-color:#FFF; + cursor:default; +} + +table.cal_day_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_day_table td { +} + +div.cal_day_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #AAA; +} + +div.cal_day_unit{ + width:100%; + cursor:pointer; +} + +table.cal_week_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_week_table td { + width: 12.5%; +} + +div.cal_week_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #888; +} + +div.cal_week_unit{ + width: 100%; + cursor:pointer; +} + +div.cal_event { + width: 100%; + height: 12px; + overflow: hidden; + font-size: 11px; + color: #00B; + margin-bottom: 2px; + text-decoration: underline; +} + +div.cal_event_Public { + color: GREEN; +} + +div.cal_event_Private { + color: BLUE; +} + +div.cal_event_hover { + text-decoration: underline; +} diff --git a/css/default.css b/css/default.css new file mode 100644 index 0000000000..1206c8fe72 --- /dev/null +++ b/css/default.css @@ -0,0 +1,1773 @@ +html { + margin: 0px; + padding: 0px; +} + +body { + margin: 0px; + padding: 0px; + font-family: Arial, Helvetica, Sans; + font-size: 12px; + color: #000; +} + +input, select, button { font-size: 12px; font-family: Arial, Helvetica, Sans; } + +li { margin: 4px; } + +h1, h2, h3, h4, h5 { + font-family: Tahoma, Sans; + font-weight: normal; +} + +h1 { margin: 8px 0px; padding: 0px; font-size: 27px; } +h2 { margin: 8px 0px; padding: 0px; font-size: 23px; } +h3 { margin: 4px 0px; padding: 0px; font-size: 17px; } +h4 { margin: 2px 0px; padding: 0px; font-size: 13px; } +h5 { margin: 2px 0px; padding: 0px; font-size: 13px; } + +pre { margin: 0px; padding: 0px; } + +button { margin: 2px; margin-left: 0px; } + +select, input, textarea { + border: 1px solid #AAA; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + font-size: 13px + padding: 2px; +} + +textarea { font-family: arial, helvetica, sans serif; height: 120px; width: 90%; overflow-x: auto; font-size: 12px; } + +table { padding: 0px; border-collapse: 'collapse'} + +td { padding:0px; margin: 0px; vertical-align: top; } + +a:active { outline:none; } + +:focus { -moz-outline-style:none; } + +table.simpletable { border-collapse: collapse; margin-bottom: 10px;} +table.simpletable td {border: 1pt solid #000; vertical-align: top; padding: 2px; } + +div.fix_ff_cursor { overflow: auto; } + +/* --- Layout --- */ + +div.comment { color: #444; } + +div#body_div { + position: relative; + display: none; +} + +div.no_script { + display: none; +} + +div.loading_div { + position: absolute; + background-color: #FFFFCC; + z-index: 1999; + right: 5px; + width: 90px; + display: none; + text-align: center; + padding: 2px; + font-size: 12px; + border: 1px solid #FF4; +} + + +div#head_div { background-color: #FFF; } + +#head_banner { background-color: #FFF; } + +.link_type { + padding:2px; + color: #00b; + text-decoration: underline; + cursor: pointer; +} + +.link_type:hover { + color: #fff !important; + background-color: #07b; + text-decoration: none; +} + +div.std-footer { + margin: 13px 0px; + border-top: 1px solid #AAA; + padding: 13px; +} + +div.std-footer-item { + margin: 0px 13px 13px 0px; +} + +/******** Menus - menu.js ************/ + +ul.menu_toolbar { + z-index: 30; + padding: 0px; + margin: 0px; + margin-top: 1px; +} + +ul.menu_toolbar li { + list-style: none; + margin: 0px; + float: left; +} + +.top_menu { + margin: 0px; + padding: 4px; + cursor: pointer; + color: #FFF; + margin-right: 8px; +} + +.top_menu_mo { + background-color: #000; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.menu_toolbar_dropdown { + position: absolute; + margin-top: 4px; + margin-left: 8px; + width: 140px; + background-color: #FFF; + color: #000; + display: none; + border: 2px solid #333; + z-index: 31; + overflow-y: auto; + overflow-x: hidden; +} + +div.dd_item { + cursor: pointer; + padding: 4px; + background-color: #FFF; +} +div.dd_item_mo { background-color: #FE8; } + +/* FLOATING MESSAGE */ + +.btn-img { cursor: pointer; } + +div.fetching { color: #888; text-align:right; } + +div.notice { + postion: absolute; + background-color: #000; + -moz-border-radius: 5px; -webkit-border-radius: 5px; + opacity: 0.6; + right: 0; + top: 0; + margin-top: 8px; + z-index: -1; + padding: 8px; +} + +/** help **/ + +.info-box { + background-color:#eeeef2; + font-size: 12px; + line-height: 1.6em; + color: #335; + padding: 7px; + margin: 11px 0px; + border: 1px solid #c2c2cc; +} + +.help_box, .help-box { + background-color:#FFC; + font-size: 13px; + line-height: 1.6em; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box { + background-color:#FFC; + font-size: 13px; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box_big { + background-color:#FFC; + color: #864; + padding: 7px; + margin: 7px 0px; + border: 1px solid #EEB; + text-align: center; + font-size: 14px; +} +/* FORMS */ + + +div.frm_print_wrapper { + background-color:#FFF; + border:1px solid #444; + padding: 40px; + + box-shadow:1px 1px 8px #229; + -moz-box-shadow: 1px 1px 8px #229; + -webkit-box-shadow: 1px 1px 8px #229; +} + +div.page_break { + margin: 24px 0px; + border-top: 1px dashed #888; +} + +div.grid_tbarlinks { + border-bottom: 0px; + background-color: #CCC; + padding: 4px 4px 2px 4px; + width: 180px; + float: right; + + -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; +} + + +div.frm_tip_box { + margin: 0px; + padding: 8px; + background-color: #FFC; + display: none; + font-size: 11px; + border: 1px solid #FFB; +} + +div.frm_tip_box table { + border-collapse: collapse; + vertical-align: top; +} + +td.frm_tray_area { + width: 122px; +} + +div.dialog_frm { + position: relative; + margin: 10px; +} + + + +/*------------------*/ + +.top_cell { + height: 50px; +} + +div.attach_area { + padding: 8px; + margin: 8px; + background-color: #EEE; +} + +div.attach_area table { + width: 100%; +} + +.tablabel_normal { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + display: inline; + cursor: pointer; +} + +.tablabel_selected { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + font-weight: bold; + display: inline; + cursor: pointer; + color: #000; +} + +.scrollhead_wrapper { + position: absolute; + z-index: 1; + height: 30px; +} + +.treeimg { + cursor: pointer; + margin-right: 3px; +} + + +.sectionCell { + padding: 5px; + vertical-align: top; +} + +.code_area { + width: 80%; + margin: 8px; + padding: 4px; + background-color: #F8F8F8; + border: 1px solid #CCC; + overflow-x: auto; +} + +.code_text { + width: 100%; + height: 360px; + margin-top: 3px; + font-family: Courier, Fixed; + font-size: 12px; +} + +div.time_field select{ + display: inline; + margin: 2px; + width: 45px; +} + +/* Documents */ + +.frm_field_table { + width: 100%; + border-collapse: collapse; +} + +.datalabelcell { + padding: 2px 0px; + width: 160px; + vertical-align: top; +} +.datainputcell { padding: 2px 0px; } + + +.field_description { + margin: 3px 0px 11px 0px; + color: #888; + font-size: 12px; + font-style: italic; +} + +.field_description_top { + margin-bottom: 3px; +} + +.field_label { + font-size:11px; +} +.input_area input, select, textarea { + font-size: 14px; + padding: 2px; +} + +.input_area input { + width: 80%; + margin: 0px; +} +.input_area select { + width: 80%; +} +.input_area textarea { + width: 90%; +} + +.disp_area { + width: 80%; + padding: 2px 0px; + font-size: 12px; +} +.disp_area_no_val { + height: 14px; +} + +.no_img { + padding: 40px; + width: 100px; + height: 20px; + color: #888; + text-align: center; + border: 1px solid #AAA; +} + +.input-mandatory { + font-size: 14px !important; + font-weight: bold; +} + +.field-to-update { + background-color:#FEE; +} + +/* sidebar */ + +div.sidebar-comment-wrapper input { + width: 50%; +} +div.sidebar-comment-message { + margin-top: 8px; + font-size: 11px; + color: #777; +} + +div.sidebar-comment-text { + font-size: 12px; + font-weight: bold; + margin-top: 8px; + color: #444; +} +div.sidebar-comment-info { + font-size: 10px; + color: #777; +} + + +/* Grid */ + + +/* --- Simple --- */ +.grid_wrapper_simple { + width: 100%; + margin-bottom: 8px; + border: 1px solid #AA9; +} + +.grid_head_wrapper_simple { + padding: 0px; + border-bottom: 2px solid #AAA; +} + +.grid_head_wrapper_simple td { + border-right: 1px solid #AA9; +} + +.grid_head_wrapper_simple td div { + padding: 2px; +} + +.grid_tab_wrapper_simple { +} + +.grid_cell_simple { + padding: 2px; + background-color: #fff; + border-right: 1px solid #AA9; +} + + +/* --- Normal --- */ +.grid_wrapper { + position: relative; + overflow: auto; + border: 1px solid #AAA; + width: 100%; + margin-bottom: 8px; + background-color: #fff; +} + +.grid_tab_wrapper { + position: absolute; + top: 30px; + border-bottom: 1px solid #DDD; +} + +.grid_table, .grid_head_table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +.grid_cell { + border-right: 1px solid #ddd; + padding: 0px; + background-color: #fff; +} + +.grid_head_wrapper { + position: absolute; + z-index: 1; + height: 30px; + padding: 0px; + overflow: hidden; + /*background-color: #fff;*/ +} + +.grid_head_table td { + background-color: #EEE; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + height: 30px; + padding: 0px; +} + +.grid_head_table td div { + color: #222; + font-weight: bold; + overflow: hidden; + padding: 2px 0px; + text-align: center; +} + +.grid_selector { + padding: 1px; + border-right: 1px solid #DDD; + width: 20px; + background-color: #fff; +} + +.grid_cell_div { + padding: 2px; + cursor: pointer; + overflow: hidden; + border: 2px solid #FFF; +} + +.grid_cell_div_selected { + border: 2px solid #88f; +} + +.grid_cell_div input, .grid_cell_div select, .grid_cell_div div input { + margin: 0px; + border: 0px; + width: 100%; + margin: 0px; + } + +.grid_cell_div textarea { + border: 3px solid #abf; + height:200px; + width: 300px; + z-index: 10; + position:absolute; +} + +.gridDivSelected option { border: 0px; } +/* listing 2.0 */ + +div.listing-more { + margin: 7px 0px 17px 0px; + textAlign: center; + display: none; +} + +div.listing-toolbar { + margin: 7px 0px; +} + +/* SRS */ + +table.srs_result_tab { + border: 2px solid #AAA; + border-collapse: collapse; +} + +/* firefox bug fix for disappering borders */ +table.srs_result_tab td, table.srs_result_tab tr, table.srs_result_tab tbody, table.srs_result_tab div { + position: static; +} + +table.srs_result_tab td { + padding: 3px 2px; + position: static; +} + +div.srs_body_area { +} + +div.srs_results_area { +} + +div.srs_filter_wrapper { + border: 1px solid #CCF; + + background-color: #EEF; + margin:0px 0px 8px 0px; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +div.srs_filter_area { + padding: 8px; +} + +div.srs_filter_area td { + vertical-align: middle; +} + + + + + +/* Reports */ + +div.report_grid_area { + position: relative; + padding: 8px; +} + + +div.report_tab { + border: 1px solid #AAA; + position: relative; + overflow: auto; +} + +div.report_no_data { + padding: 8px; + background-color: #EEE; + border: 1px solid #DDD; + position: absolute; + margin-left: 40%; + margin-top: 50px; + display: none; +} + +div.report_htitle { + float: left; + padding: 2px; + font-size: 14px; + font-weight: bold; + margin-left: 4px; + color: #665; + /*font-weight: bold;*/ +} + +div.report_tbar { + /*background: url('../images/ui/blue-back.gif') repeat-x; */ + background-color: #EEF; + border: 1px solid #CCF; + border-bottom: 0px; + height: 28px; +} + +div.report_tbar table{ + width: 100%; +} +div.report_tbar table td { + +} +div.report_tbar table td div { + position: relative; +} +div.report_tbar button, div.report_tbar select, div.report_tbar img { + font-size: 11px; + margin: 0px; +} + +div.report_head_wrapper { + position: absolute; + height: 24px; + top: 0px; + z-index: 1; +} + +div.report_tab_wrapper { + position: absolute; + border-bottom: 1px solid #AAA; + border-top: 1px solid #AAA; +} + +div.report_tab_wrapper table, div.report_head_wrapper table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +div.report_tab_wrapper table td, div.report_head_wrapper table td { + border-left: 1px solid #AAA; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + overflow: hidden; + padding: 0px; +} + +div.report_tab_wrapper table td div, div.report_head_wrapper table td div { + padding: 3px; + overflow: hidden; +} + +.report_head_cell { + background-color: #EEE; + border-bottom: 1px solid #AA9; + text-align: center; + font-weight: bold; +} +.report_head_cell div { + color:#222; + height: 18px; +} + + +/* FINDER */ + +div.finder_wrapper { +} + +div.finder_body_area { + margin: 16px; +} + +div.finder_body { + display: none; +} + +div.finder_advanced_area table { + width: 80%; +} + +div.finder_advanced_area textarea { + width: 80%; +} + +div.finder_filter_area { + position: relative; +} + +div.filter_head { + font-size: 14px; + margin-bottom: 2px; +} +div.filter_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} +table.filter_tab { + width: 96%; + border-collapse: collapse; +} + +table.filter_tab td { + width: 50%; +} + +div.finder_picker_area { + +} +div.builder_field { + margin: 0px; +} +div.builder_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} + +div.builder_field table { + width: 90%; + border-collapse: collapse; +} + +div.builder_label { + height: 20px; +} + +div.builder_head { + font-size: 16px; + font-weight: bold; + color: #AB6; +} + +table.builder_tab { + width: 96%; + border-collapse: collapse; +} + +table.builder_tab td { + width: 33%; + padding: 2px; +} +/**** CALENDAR ****/ + +.caldiv { + position:absolute; + visibility:hidden; + background-color:white; + width: 144px; + z-index: 301; /* always on top(?) */ +} + + + +div.cal_wrapper { } +div.cal_body { + margin: 16px; + background-color: #DDD; + position: relative; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.cal_head { + margin: 16px; + margin-bottom: 0px; +} +div.cal_head div { + font-size: 18px; + color: #666; + padding-top: 8px; +} + +div.cal_view_body { + margin: 16px; +} + +div.cal_view_body_plain { + margin: 16px; +} + +div.cal_month_head { +} + +div.cal_month_body { + border-top: 1px solid #888; +} + +.cal_month_headtable { + /*table-layout:fixed;*/ + width: 100%; +} + +.cal_month_name { + width: 100%; + color: #888; + font-size: 14px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +.cal_month_headtable tr td{ + font-size: 12px; + font-weight: bold; + text-align: center; + padding: 4px; +} + +table.cal_month_table { + border-collapse: collapse; + /*table-layout:fixed;*/ + height: 100%; + width: 100%; +} + +table.cal_month_table td { + width: 14.29%; + height: 20%; + /*overflow:hidden;*/ + padding:0px; +} + +div.cal_month_date { + width:100%; + height:25%; + font-size: 10px; + overflow:hidden; + /*background-color: #EEF;*/ +} + +div.cal_month_date_holiday { + /*background-color: #FFF;*/ +} + +div.cal_month_unit { + width:100%; + height:75%; + overflow:hidden; + cursor:pointer; + /*background-color:#FFF;*/ +} + +div.cal_vu_disabled { + background-color:#FFF; + cursor:default; +} + +table.cal_day_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_day_table td { +} + +div.cal_day_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #AAA; +} + +div.cal_day_unit{ + width:100%; + cursor:pointer; +} + +table.cal_week_table { + border-collapse: collapse; + width: 100%; +} + +table.cal_week_table td { + width: 12.5%; +} + +div.cal_week_body { + width: 100%; + height: 80%; + overflow-y: auto; + overflow-x: hidden; + border-top: 1px solid #888; +} + +div.cal_week_unit{ + width: 100%; + cursor:pointer; +} + +div.cal_event { + width: 100%; + height: 12px; + overflow: hidden; + font-size: 11px; + color: #00B; + margin-bottom: 2px; + text-decoration: underline; +} + +div.cal_event_Public { + color: GREEN; +} + +div.cal_event_Private { + color: BLUE; +} + +div.cal_event_hover { + text-decoration: underline; +} + +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +div.autosuggest +{ + position: absolute; + margin-top: 3px; + border: 1px solid #222; +} + +div.autosuggest ul +{ + list-style: none; + margin: 0px; + padding: 2px; + overflow: hidden; + background-color: #FFF; +} + +div.autosuggest ul li +{ + color: #444; + padding: 0; + margin: 0; + text-align: left; +} + +div.autosuggest ul li a +{ + color: #444; + display: block; + text-decoration: none; + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + +} +div.autosuggest ul li.as_highlight a:hover +{ + background-color: #45A; + color: #FFF; +} + +div.autosuggest ul li a span +{ + display: block; + padding: 3px 6px; + color: #444; + border-bottom:1px solid #DDD; +} + +div.autosuggest ul li a span small +{ + display: block; + font-weight: normal; + color: #444; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: #FFF; +} + +div.autosuggest ul li.as_highlight a span { + color: #FFF; +} + +div.autosuggest ul li.as_highlight a +{ + color: #FFF; + background-color: #45A; + cursor: pointer; +} + +div.autosuggest ul li.as_warning +{ + font-weight: bold; + text-align: center; +} + +div.autosuggest ul em +{ + font-style: normal; + font-weight: bold; +} + +/***** Dialogs *******/ + +div.dialog_wrapper { + position: absolute; + width: 440px; + display: none; + z-index: 90; + background-color: #FFF; + border: 3px solid #222; + box-shadow:1px 1px 5px #777; + -moz-box-shadow: 1px 1px 5px #777; + -webkit-box-shadow: 1px 1px 5px #777; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_head { + height: 22px; + padding: 4px; + background-color: #222; + color: #FFF; +} + +div.dialog_body { + padding: 8px 4px 16px 4px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_back { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 100%; + background-color: #EEE; + opacity: 0.6; + z-index: 50; + text-align: center; +} + +div.dialog_message { + display: none; + position: absolute; + width: 250px; + font-size: 12px; + z-index: 91; + background-color:#FFF; + padding: 12px; + border: 1px solid #444; +} + +div.dialog_row { + padding: 8px 8px 0px 8px; +} + +div.dialog_row table { + width: 100%; +} + +div.dialog_row table td { +} + +div.dialog_row input[type="text"], div.dialog_row input[type="password"], div.dialog_row textarea, div.dialog_row select { + width: 80%; + font-size: 14px; +} + +div.dialog_row table td textarea { + width: 80%; + height: 200px; + font-size: 12px; +} + + +/* Recent */ + +div.recent_starred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star.gif'); +} + +div.recent_unstarred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star_plain.gif'); +} + +div.status_flag { + width: 8px; + height: 8px; + margin: 4px; + font-size: 0px; + background-color: #EEE; +} + + + + + +/* Search */ + +.search_table td { + padding: 2px; +} + + + + +/*** for wn toolbar ***/ +.wntoolbar-icon { background: url('../images/icons/wntoolbar-icons.png'); width: 16px; height: 16px; } +.sprite-home { background-position: 0 0; } +.sprite-new { background-position: 0 -66px; } +.sprite-pages { background-position: 0 -132px; } +.sprite-recent { background-position: 0 -198px; } +.sprite-report { background-position: 0 -264px; } +.sprite-search { background-position: 0 -330px; } +.sprite-tools { background-position: 0 -396px; } + +/******* TABS ********/ + +div.box_label_wrapper { + border-bottom: 6px solid #777; +} + +div.box_label_body { + height: 22px; +} + +ul.box_tabs { + margin: 0px; + padding: 0px; + list-style: none; +} + +ul.box_tabs li { + height: 22px; + float:left; + font-size: 12px; + text-decoration: underline; + + background-color: #DDD; + + margin:0; + margin-left: 4px; + padding:0 0 0 9px; + cursor: pointer; +} + +ul.box_tabs a { + display:block; + padding:3px 15px 3px 6px; + text-decoration:none; +} + +ul.box_tabs li.box_tab_mouseover { + background-color: #BBB; +} + + +ul.box_tabs li.box_tab_selected { +/* background:url("../images/ui/rc/tab-left-CCC.gif") no-repeat left top; + background-color: #ABABAB; */ + + background-color: #777; + + background: -webkit-gradient(linear, left top, left bottom, from(#999), to(#777)); + background: -moz-linear-gradient(top, #999, #777); + + color: #FFF; + font-weight:bold; + +} +ul.box_tabs li.box_tab_selected a { +/* background:url("../images/ui/rc/tab-right-CCC.gif") no-repeat right top; */ +} + +/******* jqPlot ***********/ + +/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ +.jqplot-target { + position: relative; + color: #666666; + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; +/* height: 300px; + width: 400px;*/ +} + +/*rules applied to all axes*/ +.jqplot-axis { + font-size: 0.75em; +} + +.jqplot-xaxis { + margin-top: 10px; +} + +.jqplot-x2axis { + margin-bottom: 10px; +} + +.jqplot-yaxis { + margin-right: 10px; +} + +.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis { + margin-left: 10px; + margin-right: 10px; +} + +/*rules applied to all axis tick divs*/ +.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + position: absolute; +} + + +.jqplot-xaxis-tick { + top: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-top: 10px;*/ + vertical-align: top; +} + +.jqplot-x2axis-tick { + bottom: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-bottom: 10px;*/ + vertical-align: bottom; +} + +.jqplot-yaxis-tick { + right: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-right: 10px;*/ + text-align: right; +} + +.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + left: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-left: 10px;*/ +/* padding-right: 15px;*/ + text-align: left; +} + +.jqplot-xaxis-label { + margin-top: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-x2axis-label { + margin-bottom: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-yaxis-label { + margin-right: 10px; +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label { +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +table.jqplot-table-legend, table.jqplot-cursor-legend { + background-color: rgba(255,255,255,0.6); + border: 1px solid #cccccc; + position: absolute; + font-size: 0.75em; +} + +td.jqplot-table-legend { + vertical-align:middle; +} + +td.jqplot-table-legend > div { + border:1px solid #cccccc; + padding:0.2em; +} + +div.jqplot-table-legend-swatch { + width:0px; + height:0px; + border-top-width: 0.35em; + border-bottom-width: 0.35em; + border-left-width: 0.6em; + border-right-width: 0.6em; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} + +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.2em; +} + +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} + + +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-highlighter-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-point-label { + font-size: 0.75em; +} + +td.jqplot-cursor-legend-swatch { +vertical-align:middle; +text-align:center; +} + +div.jqplot-cursor-legend-swatch { +width:1.2em; +height:0.7em; +} + + +/** general icons **/ + +.wn-icon { background: url('../images/icons/icons.png'); width: 16px; height: 16px; cursor: pointer; } +.ic-2x2_grid { background-position: 0 0; } +.ic-3x3_grid { background-position: 0 -36px; } +.ic-3x3_grid_2 { background-position: 0 -72px; } +.ic-air_signal { background-position: 0 -108px; } +.ic-align_center { background-position: 0 -144px; } +.ic-align_just { background-position: 0 -180px; } +.ic-align_left { background-position: 0 -216px; } +.ic-align_right { background-position: 0 -252px; } +.ic-app_window { background-position: 0 -288px; } +.ic-arrow_bottom { background-position: 0 -324px; } +.ic-arrow_bottom_left { background-position: 0 -360px; } +.ic-arrow_bottom_right { background-position: 0 -396px; } +.ic-arrow_l { background-position: 0 -432px; } +.ic-arrow_left { background-position: 0 -468px; } +.ic-arrow_r { background-position: 0 -504px; } +.ic-arrow_right { background-position: 0 -540px; } +.ic-arrow_top { background-position: 0 -576px; } +.ic-arrow_top_left { background-position: 0 -612px; } +.ic-arrow_top_right { background-position: 0 -648px; } +.ic-arrow_two_head { background-position: 0 -684px; } +.ic-arrow_two_head_2 { background-position: 0 -720px; } +.ic-attention { background-position: 0 -756px; } +.ic-battery { background-position: 0 -792px; } +.ic-bell { background-position: 0 -828px; } +.ic-book { background-position: 0 -864px; } +.ic-bookmark_1 { background-position: 0 -900px; } +.ic-bookmark_2 { background-position: 0 -936px; } +.ic-box { background-position: 0 -972px; } +.ic-br_down { background-position: 0 -1008px; } +.ic-br_next { background-position: 0 -1044px; } +.ic-br_prev { background-position: 0 -1080px; } +.ic-br_up { background-position: 0 -1116px; } +.ic-brackets { background-position: 0 -1152px; } +.ic-browser { background-position: 0 -1188px; } +.ic-brush { background-position: 0 -1224px; } +.ic-bug { background-position: 0 -1260px; } +.ic-burst { background-position: 0 -1296px; } +.ic-calc { background-position: 0 -1332px; } +.ic-calendar_1 { background-position: 0 -1368px; } +.ic-calendar_2 { background-position: 0 -1404px; } +.ic-cancel { background-position: 0 -1440px; } +.ic-case { background-position: 0 -1476px; } +.ic-cc { background-position: 0 -1512px; } +.ic-cert { background-position: 0 -1548px; } +.ic-chart_bar { background-position: 0 -1584px; } +.ic-chart_line { background-position: 0 -1620px; } +.ic-chart_line_2 { background-position: 0 -1656px; } +.ic-chart_pie { background-position: 0 -1692px; } +.ic-checkbox_checked { background-position: 0 -1728px; } +.ic-checkbox_unchecked { background-position: 0 -1764px; } +.ic-checkmark { background-position: 0 -1800px; } +.ic-clip { background-position: 0 -1836px; } +.ic-clipboard_copy { background-position: 0 -1872px; } +.ic-clipboard_cut { background-position: 0 -1908px; } +.ic-clipboard_past { background-position: 0 -1944px; } +.ic-clock { background-position: -36px 0; } +.ic-cloud { background-position: -36px -36px; } +.ic-cloud_rain { background-position: -36px -72px; } +.ic-cog { background-position: -36px -108px; } +.ic-comp { background-position: -36px -144px; } +.ic-compass { background-position: -36px -180px; } +.ic-contact_card { background-position: -36px -216px; } +.ic-cube { background-position: -36px -252px; } +.ic-cur_bp { background-position: -36px -288px; } +.ic-cur_dollar { background-position: -36px -324px; } +.ic-cur_euro { background-position: -36px -360px; } +.ic-cur_yen { background-position: -36px -396px; } +.ic-cursor_H_split { background-position: -36px -432px; } +.ic-cursor_V_split { background-position: -36px -468px; } +.ic-cursor_arrow { background-position: -36px -504px; } +.ic-cursor_drag_arrow { background-position: -36px -540px; } +.ic-cursor_drag_arrow_2 { background-position: -36px -576px; } +.ic-cursor_drag_hand { background-position: -36px -612px; } +.ic-cursor_hand { background-position: -36px -648px; } +.ic-db { background-position: -36px -684px; } +.ic-delete { background-position: -36px -720px; } +.ic-doc_delete { background-position: -36px -756px; } +.ic-doc_edit { background-position: -36px -792px; } +.ic-doc_empty { background-position: -36px -828px; } +.ic-doc_export { background-position: -36px -864px; } +.ic-doc_import { background-position: -36px -900px; } +.ic-doc_lines { background-position: -36px -936px; } +.ic-doc_lines_stright { background-position: -36px -972px; } +.ic-doc_minus { background-position: -36px -1008px; } +.ic-doc_new { background-position: -36px -1044px; } +.ic-doc_plus { background-position: -36px -1080px; } +.ic-document { background-position: -36px -1116px; } +.ic-download { background-position: -36px -1152px; } +.ic-emotion_sad { background-position: -36px -1188px; } +.ic-emotion_smile { background-position: -36px -1224px; } +.ic-expand { background-position: -36px -1260px; } +.ic-eye { background-position: -36px -1296px; } +.ic-eye_inv { background-position: -36px -1332px; } +.ic-facebook { background-position: -36px -1368px; } +.ic-filter { background-position: -36px -1404px; } +.ic-fire { background-position: -36px -1440px; } +.ic-flag { background-position: -36px -1476px; } +.ic-folder { background-position: -36px -1512px; } +.ic-folder_arrow { background-position: -36px -1548px; } +.ic-folder_delete { background-position: -36px -1584px; } +.ic-folder_minus { background-position: -36px -1620px; } +.ic-folder_open { background-position: -36px -1656px; } +.ic-folder_plus { background-position: -36px -1692px; } +.ic-font_bold { background-position: -36px -1728px; } +.ic-font_italic { background-position: -36px -1764px; } +.ic-font_size { background-position: -36px -1800px; } +.ic-font_strokethrough { background-position: -36px -1836px; } +.ic-font_underline { background-position: -36px -1872px; } +.ic-game_pad { background-position: -36px -1908px; } +.ic-globe_1 { background-position: -36px -1944px; } +.ic-globe_2 { background-position: -72px 0; } +.ic-globe_3 { background-position: -72px -36px; } +.ic-google { background-position: -72px -72px; } +.ic-hand_1 { background-position: -72px -108px; } +.ic-hand_2 { background-position: -72px -144px; } +.ic-hand_contra { background-position: -72px -180px; } +.ic-hand_pro { background-position: -72px -216px; } +.ic-headphones { background-position: -72px -252px; } +.ic-heart { background-position: -72px -288px; } +.ic-heart_empty { background-position: -72px -324px; } +.ic-home { background-position: -72px -360px; } +.ic-image_text { background-position: -72px -396px; } +.ic-inbox { background-position: -72px -432px; } +.ic-indent_decrease { background-position: -72px -468px; } +.ic-indent_increase { background-position: -72px -504px; } +.ic-info { background-position: -72px -540px; } +.ic-iphone { background-position: -72px -576px; } +.ic-key { background-position: -72px -612px; } +.ic-layers_1 { background-position: -72px -648px; } +.ic-layers_2 { background-position: -72px -684px; } +.ic-lightbulb { background-position: -72px -720px; } +.ic-lighting { background-position: -72px -756px; } +.ic-link { background-position: -72px -792px; } +.ic-list_bullets { background-position: -72px -828px; } +.ic-list_num { background-position: -72px -864px; } +.ic-magic_wand { background-position: -72px -900px; } +.ic-mail { background-position: -72px -936px; } +.ic-mail_2 { background-position: -72px -972px; } +.ic-mic { background-position: -72px -1008px; } +.ic-monitor { background-position: -72px -1044px; } +.ic-movie { background-position: -72px -1080px; } +.ic-music { background-position: -72px -1116px; } +.ic-net_comp { background-position: -72px -1152px; } +.ic-network { background-position: -72px -1188px; } +.ic-notepad { background-position: -72px -1224px; } +.ic-notepad_2 { background-position: -72px -1260px; } +.ic-on-off { background-position: -72px -1296px; } +.ic-openid { background-position: -72px -1332px; } +.ic-padlock_closed { background-position: -72px -1368px; } +.ic-padlock_open { background-position: -72px -1404px; } +.ic-page_layout { background-position: -72px -1440px; } +.ic-paragraph { background-position: -72px -1476px; } +.ic-pencil { background-position: -72px -1512px; } +.ic-phone { background-position: -72px -1548px; } +.ic-phone_1 { background-position: -72px -1584px; } +.ic-phone_2 { background-position: -72px -1620px; } +.ic-phone_touch { background-position: -72px -1656px; } +.ic-photo { background-position: -72px -1692px; } +.ic-picture { background-position: -72px -1728px; } +.ic-pin { background-position: -72px -1764px; } +.ic-pin_2 { background-position: -72px -1800px; } +.ic-pin_map { background-position: -72px -1836px; } +.ic-pin_map_down { background-position: -72px -1872px; } +.ic-pin_map_left { background-position: -72px -1908px; } +.ic-pin_map_right { background-position: -72px -1944px; } +.ic-pin_map_top { background-position: -108px 0; } +.ic-pin_sq_down { background-position: -108px -36px; } +.ic-pin_sq_left { background-position: -108px -72px; } +.ic-pin_sq_right { background-position: -108px -108px; } +.ic-pin_sq_top { background-position: -108px -144px; } +.ic-playback_ff { background-position: -108px -180px; } +.ic-playback_next { background-position: -108px -216px; } +.ic-playback_pause { background-position: -108px -252px; } +.ic-playback_play { background-position: -108px -288px; } +.ic-playback_prev { background-position: -108px -324px; } +.ic-playback_rec { background-position: -108px -360px; } +.ic-playback_reload { background-position: -108px -396px; } +.ic-playback_rew { background-position: -108px -432px; } +.ic-playback_stop { background-position: -108px -468px; } +.ic-preso { background-position: -108px -504px; } +.ic-print { background-position: -108px -540px; } +.ic-question { background-position: -108px -576px; } +.ic-redo { background-position: -108px -612px; } +.ic-rnd_br_down { background-position: -108px -648px; } +.ic-rnd_br_first { background-position: -108px -684px; } +.ic-rnd_br_last { background-position: -108px -720px; } +.ic-rnd_br_next { background-position: -108px -756px; } +.ic-rnd_br_prev { background-position: -108px -792px; } +.ic-rnd_br_up { background-position: -108px -828px; } +.ic-round { background-position: -108px -864px; } +.ic-round_and_up { background-position: -108px -900px; } +.ic-round_arrow_left { background-position: -108px -936px; } +.ic-round_arrow_right { background-position: -108px -972px; } +.ic-round_checkmark { background-position: -108px -1008px; } +.ic-round_delete { background-position: -108px -1044px; } +.ic-round_minus { background-position: -108px -1080px; } +.ic-round_plus { background-position: -108px -1116px; } +.ic-rss { background-position: -108px -1152px; } +.ic-rss_sq { background-position: -108px -1188px; } +.ic-sand { background-position: -108px -1224px; } +.ic-sat_dish { background-position: -108px -1260px; } +.ic-save { background-position: -108px -1296px; } +.ic-server { background-position: -108px -1332px; } +.ic-share { background-position: -108px -1368px; } +.ic-shop_cart { background-position: -108px -1404px; } +.ic-sound_high { background-position: -108px -1440px; } +.ic-sound_low { background-position: -108px -1476px; } +.ic-sound_mute { background-position: -108px -1512px; } +.ic-spechbubble { background-position: -108px -1548px; } +.ic-spechbubble_2 { background-position: -108px -1584px; } +.ic-spechbubble_sq { background-position: -108px -1620px; } +.ic-spechbubble_sq_line { background-position: -108px -1656px; } +.ic-sq_br_down { background-position: -108px -1692px; } +.ic-sq_br_first { background-position: -108px -1728px; } +.ic-sq_br_last { background-position: -108px -1764px; } +.ic-sq_br_next { background-position: -108px -1800px; } +.ic-sq_br_prev { background-position: -108px -1836px; } +.ic-sq_br_up { background-position: -108px -1872px; } +.ic-sq_down { background-position: -108px -1908px; } +.ic-sq_minus { background-position: -108px -1944px; } +.ic-sq_next { background-position: -144px 0; } +.ic-sq_plus { background-position: -144px -36px; } +.ic-sq_prev { background-position: -144px -72px; } +.ic-sq_up { background-position: -144px -108px; } +.ic-square_shape { background-position: -144px -144px; } +.ic-star { background-position: -144px -180px; } +.ic-star_fav { background-position: -144px -216px; } +.ic-star_fav_empty { background-position: -144px -252px; } +.ic-sun { background-position: -144px -288px; } +.ic-tag { background-position: -144px -324px; } +.ic-tape { background-position: -144px -360px; } +.ic-target { background-position: -144px -396px; } +.ic-text_curstor { background-position: -144px -432px; } +.ic-text_letter_t { background-position: -144px -468px; } +.ic-top_right_expand { background-position: -144px -504px; } +.ic-trash { background-position: -144px -540px; } +.ic-twitter { background-position: -144px -576px; } +.ic-twitter_2 { background-position: -144px -612px; } +.ic-undo { background-position: -144px -648px; } +.ic-user { background-position: -144px -684px; } +.ic-users { background-position: -144px -720px; } +.ic-wrench { background-position: -144px -756px; } +.ic-wrench_plus { background-position: -144px -792px; } +.ic-wrench_plus_2 { background-position: -144px -828px; } +.ic-zoom { background-position: -144px -864px; } + + +div.psidebar-wrapper { + margin: 0px 8px; +} + +div.psidebar-head { + font-size: 14px; + font-weight: bold; + color: #555; + margin-bottom: 12px; +} + +div.psidebar-section { + background-color: #f7f7f5; + border: 2px solid #b2b2b7; + margin-bottom: 11px; +} + +div.psidebar-section-head { + font-weight: bold; + font-size: 13px; + color: #222; + background-color: #d8d8d4; + margin-bottom: 7px; + padding: 3px 11px; +} + +div.psidebar-section-body { + margin: 7px 11px 11px 11px; +} + +div.psidebar-section-item { + margin-bottom: 7px; +} + +.psidebar-section-link { + font-size: 11px; + color: #666; +} + +div.follower-list { + color: #666; + margin-top: 7px; + font-size: 11px; +} +/******** Listing2 ***********/ +table.dcv-tab { + table-layout: fixed; + border-collapse: collapse; +} + +table.dcv-tab td { + border: 1px solid #DDD; +} + +table.dcv-tab td td { + border: 0px solid #BBB; +} + +div.list2-head { + padding: 3px 6px; + font-size: 14px; + color: #555; +} + +div.list2-new { + padding: 4px; +} + +div.list2-message { + padding: 8px; + color: #888; + background-color: #FFD; +} + +div.list2-search { + padding: 4px; +} + +div.list2-list-area { + padding: 4px; +} + +div.list2-item-div { + border-bottom: 1px solid #AAA; + padding: 4px; + cursor: pointer; +} + +span.list2-edit-link { + font-weight: normal; + font-size: 11px; + margin-left: 7px; +} + +div.list2-item-title { + font-weight: bold; +} + +div.list2-item-selected { + background-color: #CCF; +} + +div.list2-item-more-info { + color: #888; + margin-top: 4px; +} diff --git a/css/dialog.css b/css/dialog.css new file mode 100644 index 0000000000..f417994bb4 --- /dev/null +++ b/css/dialog.css @@ -0,0 +1,76 @@ +/***** Dialogs *******/ + +div.dialog_wrapper { + position: absolute; + width: 440px; + display: none; + z-index: 90; + background-color: #FFF; + border: 3px solid #222; + box-shadow:1px 1px 5px #777; + -moz-box-shadow: 1px 1px 5px #777; + -webkit-box-shadow: 1px 1px 5px #777; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_head { + height: 22px; + padding: 4px; + background-color: #222; + color: #FFF; +} + +div.dialog_body { + padding: 8px 4px 16px 4px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.dialog_back { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 100%; + background-color: #EEE; + opacity: 0.6; + z-index: 50; + text-align: center; +} + +div.dialog_message { + display: none; + position: absolute; + width: 250px; + font-size: 12px; + z-index: 91; + background-color:#FFF; + padding: 12px; + border: 1px solid #444; +} + +div.dialog_row { + padding: 8px 8px 0px 8px; +} + +div.dialog_row table { + width: 100%; +} + +div.dialog_row table td { +} + +div.dialog_row input[type="text"], div.dialog_row input[type="password"], div.dialog_row textarea, div.dialog_row select { + width: 80%; + font-size: 14px; +} + +div.dialog_row table td textarea { + width: 80%; + height: 200px; + font-size: 12px; +} diff --git a/css/doc_column_view.css b/css/doc_column_view.css new file mode 100644 index 0000000000..30660dcbed --- /dev/null +++ b/css/doc_column_view.css @@ -0,0 +1,62 @@ +/******** Listing2 ***********/ +table.dcv-tab { + table-layout: fixed; + border-collapse: collapse; +} + +table.dcv-tab td { + border: 1px solid #DDD; +} + +table.dcv-tab td td { + border: 0px solid #BBB; +} + +div.list2-head { + padding: 3px 6px; + font-size: 14px; + color: #555; +} + +div.list2-new { + padding: 4px; +} + +div.list2-message { + padding: 8px; + color: #888; + background-color: #FFD; +} + +div.list2-search { + padding: 4px; +} + +div.list2-list-area { + padding: 4px; +} + +div.list2-item-div { + border-bottom: 1px solid #AAA; + padding: 4px; + cursor: pointer; +} + +span.list2-edit-link { + font-weight: normal; + font-size: 11px; + margin-left: 7px; +} + +div.list2-item-title { + font-weight: bold; +} + +div.list2-item-selected { + background-color: #CCF; +} + +div.list2-item-more-info { + color: #888; + margin-top: 4px; +} \ No newline at end of file diff --git a/css/forms.css b/css/forms.css new file mode 100644 index 0000000000..b99410aee6 --- /dev/null +++ b/css/forms.css @@ -0,0 +1,222 @@ +/* FORMS */ + + +div.frm_print_wrapper { + background-color:#FFF; + border:1px solid #444; + padding: 40px; + + box-shadow:1px 1px 8px #229; + -moz-box-shadow: 1px 1px 8px #229; + -webkit-box-shadow: 1px 1px 8px #229; +} + +div.page_break { + margin: 24px 0px; + border-top: 1px dashed #888; +} + +div.grid_tbarlinks { + border-bottom: 0px; + background-color: #CCC; + padding: 4px 4px 2px 4px; + width: 180px; + float: right; + + -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; +} + + +div.frm_tip_box { + margin: 0px; + padding: 8px; + background-color: #FFC; + display: none; + font-size: 11px; + border: 1px solid #FFB; +} + +div.frm_tip_box table { + border-collapse: collapse; + vertical-align: top; +} + +td.frm_tray_area { + width: 122px; +} + +div.dialog_frm { + position: relative; + margin: 10px; +} + + + +/*------------------*/ + +.top_cell { + height: 50px; +} + +div.attach_area { + padding: 8px; + margin: 8px; + background-color: #EEE; +} + +div.attach_area table { + width: 100%; +} + +.tablabel_normal { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + display: inline; + cursor: pointer; +} + +.tablabel_selected { + margin: 0 4px 0 0; + padding: 3px 5px; + line-height: 1.3em; + font-weight: bold; + display: inline; + cursor: pointer; + color: #000; +} + +.scrollhead_wrapper { + position: absolute; + z-index: 1; + height: 30px; +} + +.treeimg { + cursor: pointer; + margin-right: 3px; +} + + +.sectionCell { + padding: 5px; + vertical-align: top; +} + +.code_area { + width: 80%; + margin: 8px; + padding: 4px; + background-color: #F8F8F8; + border: 1px solid #CCC; + overflow-x: auto; +} + +.code_text { + width: 100%; + height: 360px; + margin-top: 3px; + font-family: Courier, Fixed; + font-size: 12px; +} + +div.time_field select{ + display: inline; + margin: 2px; + width: 45px; +} + +/* Documents */ + +.frm_field_table { + width: 100%; + border-collapse: collapse; +} + +.datalabelcell { + padding: 2px 0px; + width: 160px; + vertical-align: top; +} +.datainputcell { padding: 2px 0px; } + + +.field_description { + margin: 3px 0px 11px 0px; + color: #888; + font-size: 12px; + font-style: italic; +} + +.field_description_top { + margin-bottom: 3px; +} + +.field_label { + font-size:11px; +} +.input_area input, select, textarea { + font-size: 14px; + padding: 2px; +} + +.input_area input { + width: 80%; + margin: 0px; +} +.input_area select { + width: 80%; +} +.input_area textarea { + width: 90%; +} + +.disp_area { + width: 80%; + padding: 2px 0px; + font-size: 12px; +} +.disp_area_no_val { + height: 14px; +} + +.no_img { + padding: 40px; + width: 100px; + height: 20px; + color: #888; + text-align: center; + border: 1px solid #AAA; +} + +.input-mandatory { + font-size: 14px !important; + font-weight: bold; +} + +.field-to-update { + background-color:#FEE; +} + +/* sidebar */ + +div.sidebar-comment-wrapper input { + width: 50%; +} +div.sidebar-comment-message { + margin-top: 8px; + font-size: 11px; + color: #777; +} + +div.sidebar-comment-text { + font-size: 12px; + font-weight: bold; + margin-top: 8px; + color: #444; +} +div.sidebar-comment-info { + font-size: 10px; + color: #777; +} \ No newline at end of file diff --git a/css/grid.css b/css/grid.css new file mode 100644 index 0000000000..a9c5e877c1 --- /dev/null +++ b/css/grid.css @@ -0,0 +1,122 @@ + + +/* Grid */ + + +/* --- Simple --- */ +.grid_wrapper_simple { + width: 100%; + margin-bottom: 8px; + border: 1px solid #AA9; +} + +.grid_head_wrapper_simple { + padding: 0px; + border-bottom: 2px solid #AAA; +} + +.grid_head_wrapper_simple td { + border-right: 1px solid #AA9; +} + +.grid_head_wrapper_simple td div { + padding: 2px; +} + +.grid_tab_wrapper_simple { +} + +.grid_cell_simple { + padding: 2px; + background-color: #fff; + border-right: 1px solid #AA9; +} + + +/* --- Normal --- */ +.grid_wrapper { + position: relative; + overflow: auto; + border: 1px solid #AAA; + width: 100%; + margin-bottom: 8px; + background-color: #fff; +} + +.grid_tab_wrapper { + position: absolute; + top: 30px; + border-bottom: 1px solid #DDD; +} + +.grid_table, .grid_head_table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +.grid_cell { + border-right: 1px solid #ddd; + padding: 0px; + background-color: #fff; +} + +.grid_head_wrapper { + position: absolute; + z-index: 1; + height: 30px; + padding: 0px; + overflow: hidden; + /*background-color: #fff;*/ +} + +.grid_head_table td { + background-color: #EEE; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + height: 30px; + padding: 0px; +} + +.grid_head_table td div { + color: #222; + font-weight: bold; + overflow: hidden; + padding: 2px 0px; + text-align: center; +} + +.grid_selector { + padding: 1px; + border-right: 1px solid #DDD; + width: 20px; + background-color: #fff; +} + +.grid_cell_div { + padding: 2px; + cursor: pointer; + overflow: hidden; + border: 2px solid #FFF; +} + +.grid_cell_div_selected { + border: 2px solid #88f; +} + +.grid_cell_div input, .grid_cell_div select, .grid_cell_div div input { + margin: 0px; + border: 0px; + width: 100%; + margin: 0px; + } + +.grid_cell_div textarea { + border: 3px solid #abf; + height:200px; + width: 300px; + z-index: 10; + position:absolute; +} + +.gridDivSelected option { border: 0px; } \ No newline at end of file diff --git a/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/css/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100755 index 0000000000000000000000000000000000000000..5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FscKIb$B>N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_flat_75_ffffff_40x100.png b/css/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100755 index 0000000000000000000000000000000000000000..ac8b229af950c29356abf64a6c4aa894575445f0 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/css/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100755 index 0000000000000000000000000000000000000000..ad3d6346e00f246102f72f2e026ed0491988b394 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_glass_95_fef1ec_1x400.png b/css/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100755 index 0000000000000000000000000000000000000000..4443fdc1a156babad4336f004eaf5ca5dfa0f9ab GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hIh978O6-<~(*YA|4MzBvER z|7}eQtdCVXoUc2b{PaWeaIKu7gJx>{vDV26o)#~38k_!`W=^oo1w6ixmPC4R1b Tyd6G3lNdZ*{an^LB{Ts5`idse literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_highlight-hard_65_ffffff_1x100.png b/css/images/ui-bg_highlight-hard_65_ffffff_1x100.png new file mode 100755 index 0000000000000000000000000000000000000000..eaa8cfa3cad28d64457a04a651d2fbc1c76a5975 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l!~W|V~E7myQdcdr8o|6==)!< qXYSL~$-RpCgTPeJAif1T+an6}xemLey*LU~&*16m=d#Wzp$P!gcp1b1 literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_highlight-hard_75_dadada_1x100.png b/css/images/ui-bg_highlight-hard_75_dadada_1x100.png new file mode 100755 index 0000000000000000000000000000000000000000..eef96a3ef29b556251e6c97c628cc5936fb4c6f6 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l!m8^V~E7mZ=`+r+DKeP!EHrtDnm{r-UW|uO=Od literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png b/css/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png new file mode 100755 index 0000000000000000000000000000000000000000..31503e6215c8ba914450dd173a0cad541f833d54 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l&YtTV~E7mBvHrY`~HIpLszI$#gPprAQKooUHx3vIVCg!0E#so-2eap literal 0 HcmV?d00001 diff --git a/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100755 index 0000000000000000000000000000000000000000..7c9fa6c6edcfcdd3e5b77e6f547b719e6fc66e30 GIT binary patch literal 101 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
    t&;p)D%&Z%Nw$gSPa!nz8Slh7=ko2am)XARwOWw zpsz0~K!s{(dM$NB=(A=kkp>T(*yU6<_dwIx>cH4+LWl282hXa6-EUq>R3t?G2623< z*RwTN%-fgBmD{fu*ejNn)1@KG?Sg*8z3hYtkQJQjB6 zQ|x>wA=o$=O)+nLmgTXW3_6diA;b4EY{*i*R%6dO2EMg z@6g?M3rpbnfB@hOdUeb96=~I?OIA3@BWAGmTwiQ{x5Cqq<8c10L!P zd@Qk^BseTX%$Q7^s}5n%HB|)gKx}H$d8Sb$bBnq9-AglT2dGR2(+I;_fL|R4p$odJ zllfb0NqI)7=^z~qAm1V{(PkpxXsQ#4*NH9yYZ`Vf@)?#ueGgtCmGGY|9U#v|hRdg- zQ%0#cGIfXCd{Y)JB~qykO;KPvHu|5Ck&(Hn%DF~cct@}j+87xhs2ew;fLm5#2+mb| z8{9e*YI(u|gt|{x1G+U=DA3y)9s2w7@cvQ($ZJIA)x$e~5_3LKFV~ASci8W}jF&VeJoPDUy(BB>ExJpck;%;!`0AAo zAcHgcnT8%OX&UW_n|%{2B|<6Wp2MMGvd5`T2KKv;ltt_~H+w00x6+SlAD`{K4!9zx z*1?EpQ%Lwiik){3n{-+YNrT;fH_niD_Ng9|58@m8RsKFVF!6pk@qxa{BH-&8tsim0 zdAQ(GyC^9ane7_KW*#^vMIoeQdpJqmPp%%px3GIftbwESu#+vPyI*YTuJ6+4`z{s? zpkv~0x4c_PFH`-tqafw5)>4AuQ78SkZ!$8}INLK;Egr;2tS18hEO5=t;QDmZ-qu?I zG+=DN`nR72Xto{{bJp||`k}-2G;5#xg8E~xgz22)^_Z;=K|4@(E&5J)SY2of=olcw z5)@L)_Ntcm!*5nEy0M9v0`S33;pO4TN;>4(Z+19p_0>u#e-vE zXCU(6gAvu~I7Cw(xd%0e59MNLw^U37ZDbsBrj%eDCexw8a3G`nTcXVNL6{B7Hj@i& zbVB{;ApEtHk76q08DJ48dSxd$C(;$K6=FpU<~l9pVoT9arW^Vu{%Bcn4`eIpkOVC| z$)AKYG_`ypM{0@BUb3^9lqi_c?ONH|4UJMJWDowMVjacycX7}9g={O7swOB+{;+?; zjBo!9?+nd)ie#x5IbFW-zBOo0c4q@9wGVt5;pNt`=-~Zgcw#*`m($6ibxtZ`H=e=} zF#GZ~5$%AUn};8U#tRem0J(JTR}d4vR(dgK2ML~lZsPhayJ2h1%sD4FVst| zKF)+@`iNzLRjg4=K8@**0=5cE>%?FDc({I^+g9USk<8$&^qD~@%W0i4b|yMG*p4`N zh}I!ltTRI8Ex$+@V{02Br%xq#O?UlhO{r8WsaZnZCZq0MK9%AXU%MDLT;3=0A9(BV z9VxxxJd7jo$hw3q;3o?yBLmA=azBUrd9>-<_ANs0n3?-Ic*6&ytb@H~?0E(*d>T5n z-HiH2jsDf6uWhID%#n>SzOqrFCPDfUcu5QPd?<(=w6pv1BE#nsxS{n!UnC9qAha1< z;3cpZ9A-e$+Y)%b;w@!!YRA9p%Kf9IHGGg^{+p`mh;q8i7}&e@V3EQaMsItEMS&=X plT@$;k0WcB_jb;cn%_Idz4HO$QU*abf4}+wi?e96N>fbq{{i|W0@(ln literal 0 HcmV?d00001 diff --git a/css/images/ui-icons_2e83ff_256x240.png b/css/images/ui-icons_2e83ff_256x240.png new file mode 100755 index 0000000000000000000000000000000000000000..09d1cdc856c292c4ab6dd818c7543ac0828bd616 GIT binary patch literal 4369 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 literal 0 HcmV?d00001 diff --git a/css/images/ui-icons_454545_256x240.png b/css/images/ui-icons_454545_256x240.png new file mode 100755 index 0000000000000000000000000000000000000000..59bd45b907c4fd965697774ce8c5fc6b2fd9c105 GIT binary patch literal 4369 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 oBo%DI*Kv;w;*%(i9W@f3_WCF#rGn literal 0 HcmV?d00001 diff --git a/css/images/ui-icons_cd0a0a_256x240.png b/css/images/ui-icons_cd0a0a_256x240.png new file mode 100755 index 0000000000000000000000000000000000000000..2ab019b73ec11a485fa09378f3a0e155194f6a5d GIT binary patch literal 4369 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 div { + border:1px solid #cccccc; + padding:0.2em; +} + +div.jqplot-table-legend-swatch { + width:0px; + height:0px; + border-top-width: 0.35em; + border-bottom-width: 0.35em; + border-left-width: 0.6em; + border-right-width: 0.6em; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} + +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.2em; +} + +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} + + +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-highlighter-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-point-label { + font-size: 0.75em; +} + +td.jqplot-cursor-legend-swatch { +vertical-align:middle; +text-align:center; +} + +div.jqplot-cursor-legend-swatch { +width:1.2em; +height:0.7em; +} diff --git a/css/jquery-ui.css b/css/jquery-ui.css new file mode 100755 index 0000000000..c7ab34740c --- /dev/null +++ b/css/jquery-ui.css @@ -0,0 +1,383 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial,sans-serif&fwDefault=normal&fsDefault=1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=04_highlight_hard.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=222&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=04_highlight_hard.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=000&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=000&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Arial,sans-serif; font-size: 1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_highlight-hard_75_e6e6e6_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #222; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #222; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_highlight-hard_75_dadada_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #000; } +.ui-state-hover a, .ui-state-hover a:hover { color: #000; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_highlight-hard_65_ffffff_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #000; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #000; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Button +----------------------------------*/ + +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3em; } +button.ui-button-icons-only { width: 3.2em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.2; } +.ui-button-text-only .ui-button-text { padding: .3em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .3em; text-indent: -9999999px; } +.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .3em 1em .3em 1.8em; } +.ui-button-text-icons .ui-button-text { padding-right: 1.8em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .3em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon .ui-icon-primary, .ui-button-text-icons .ui-icon-primary, .ui-button-icons-only .ui-icon-primary { left: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-button-set { margin-right: 7px; } +.ui-button-set .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ + + +/* Datepicker +----------------------------------*/ +.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +} + +/* There must be a better way to do this - Rushabh */ +#ui-datepicker-div { + z-index: 9999; +} \ No newline at end of file diff --git a/css/listing.css b/css/listing.css new file mode 100644 index 0000000000..9deb7942e9 --- /dev/null +++ b/css/listing.css @@ -0,0 +1,56 @@ +/* listing 2.0 */ + +div.listing-more { + margin: 7px 0px 17px 0px; + textAlign: center; + display: none; +} + +div.listing-toolbar { + margin: 7px 0px; +} + +/* SRS */ + +table.srs_result_tab { + border: 2px solid #AAA; + border-collapse: collapse; +} + +/* firefox bug fix for disappering borders */ +table.srs_result_tab td, table.srs_result_tab tr, table.srs_result_tab tbody, table.srs_result_tab div { + position: static; +} + +table.srs_result_tab td { + padding: 3px 2px; + position: static; +} + +div.srs_body_area { +} + +div.srs_results_area { +} + +div.srs_filter_wrapper { + border: 1px solid #CCF; + + background-color: #EEF; + margin:0px 0px 8px 0px; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +div.srs_filter_area { + padding: 8px; +} + +div.srs_filter_area td { + vertical-align: middle; +} + + + diff --git a/css/menus.css b/css/menus.css new file mode 100644 index 0000000000..646a7d61f3 --- /dev/null +++ b/css/menus.css @@ -0,0 +1,51 @@ + +/******** Menus - menu.js ************/ + +ul.menu_toolbar { + z-index: 30; + padding: 0px; + margin: 0px; + margin-top: 1px; +} + +ul.menu_toolbar li { + list-style: none; + margin: 0px; + float: left; +} + +.top_menu { + margin: 0px; + padding: 4px; + cursor: pointer; + color: #FFF; + margin-right: 8px; +} + +.top_menu_mo { + background-color: #000; + + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.menu_toolbar_dropdown { + position: absolute; + margin-top: 4px; + margin-left: 8px; + width: 140px; + background-color: #FFF; + color: #000; + display: none; + border: 2px solid #333; + z-index: 31; + overflow-y: auto; + overflow-x: hidden; +} + +div.dd_item { + cursor: pointer; + padding: 4px; + background-color: #FFF; +} +div.dd_item_mo { background-color: #FE8; } \ No newline at end of file diff --git a/css/messages.css b/css/messages.css new file mode 100644 index 0000000000..2e1fabe97a --- /dev/null +++ b/css/messages.css @@ -0,0 +1,59 @@ + +/* FLOATING MESSAGE */ + +.btn-img { cursor: pointer; } + +div.fetching { color: #888; text-align:right; } + +div.notice { + postion: absolute; + background-color: #000; + -moz-border-radius: 5px; -webkit-border-radius: 5px; + opacity: 0.6; + right: 0; + top: 0; + margin-top: 8px; + z-index: -1; + padding: 8px; +} + +/** help **/ + +.info-box { + background-color:#eeeef2; + font-size: 12px; + line-height: 1.6em; + color: #335; + padding: 7px; + margin: 11px 0px; + border: 1px solid #c2c2cc; +} + +.help_box, .help-box { + background-color:#FFC; + font-size: 13px; + line-height: 1.6em; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box { + background-color:#FFC; + font-size: 13px; + color: #864; + padding: 7px; + margin: 11px 0px; + border: 1px solid #EEB; +} + +.help_box_big { + background-color:#FFC; + color: #864; + padding: 7px; + margin: 7px 0px; + border: 1px solid #EEB; + text-align: center; + font-size: 14px; +} \ No newline at end of file diff --git a/css/report.css b/css/report.css new file mode 100644 index 0000000000..333dd3bf7c --- /dev/null +++ b/css/report.css @@ -0,0 +1,180 @@ + +/* Reports */ + +div.report_grid_area { + position: relative; + padding: 8px; +} + + +div.report_tab { + border: 1px solid #AAA; + position: relative; + overflow: auto; +} + +div.report_no_data { + padding: 8px; + background-color: #EEE; + border: 1px solid #DDD; + position: absolute; + margin-left: 40%; + margin-top: 50px; + display: none; +} + +div.report_htitle { + float: left; + padding: 2px; + font-size: 14px; + font-weight: bold; + margin-left: 4px; + color: #665; + /*font-weight: bold;*/ +} + +div.report_tbar { + /*background: url('../images/ui/blue-back.gif') repeat-x; */ + background-color: #EEF; + border: 1px solid #CCF; + border-bottom: 0px; + height: 28px; +} + +div.report_tbar table{ + width: 100%; +} +div.report_tbar table td { + +} +div.report_tbar table td div { + position: relative; +} +div.report_tbar button, div.report_tbar select, div.report_tbar img { + font-size: 11px; + margin: 0px; +} + +div.report_head_wrapper { + position: absolute; + height: 24px; + top: 0px; + z-index: 1; +} + +div.report_tab_wrapper { + position: absolute; + border-bottom: 1px solid #AAA; + border-top: 1px solid #AAA; +} + +div.report_tab_wrapper table, div.report_head_wrapper table { + table-layout: fixed; + border-collapse: collapse; + /*width: 100%;*/ +} + +div.report_tab_wrapper table td, div.report_head_wrapper table td { + border-left: 1px solid #AAA; + border-right: 1px solid #AAA; + border-bottom: 1px solid #AAA; + overflow: hidden; + padding: 0px; +} + +div.report_tab_wrapper table td div, div.report_head_wrapper table td div { + padding: 3px; + overflow: hidden; +} + +.report_head_cell { + background-color: #EEE; + border-bottom: 1px solid #AA9; + text-align: center; + font-weight: bold; +} +.report_head_cell div { + color:#222; + height: 18px; +} + + +/* FINDER */ + +div.finder_wrapper { +} + +div.finder_body_area { + margin: 16px; +} + +div.finder_body { + display: none; +} + +div.finder_advanced_area table { + width: 80%; +} + +div.finder_advanced_area textarea { + width: 80%; +} + +div.finder_filter_area { + position: relative; +} + +div.filter_head { + font-size: 14px; + margin-bottom: 2px; +} +div.filter_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} +table.filter_tab { + width: 96%; + border-collapse: collapse; +} + +table.filter_tab td { + width: 50%; +} + +div.finder_picker_area { + +} +div.builder_field { + margin: 0px; +} +div.builder_dt_head { + font-size: 14px; + font-weight: bold; + margin-bottom: 2px; +} + +div.builder_field table { + width: 90%; + border-collapse: collapse; +} + +div.builder_label { + height: 20px; +} + +div.builder_head { + font-size: 16px; + font-weight: bold; + color: #AB6; +} + +table.builder_tab { + width: 96%; + border-collapse: collapse; +} + +table.builder_tab td { + width: 33%; + padding: 2px; +} \ No newline at end of file diff --git a/css/sidebar.css b/css/sidebar.css new file mode 100644 index 0000000000..493935d8f0 --- /dev/null +++ b/css/sidebar.css @@ -0,0 +1,44 @@ +div.psidebar-wrapper { + margin: 0px 8px; +} + +div.psidebar-head { + font-size: 14px; + font-weight: bold; + color: #555; + margin-bottom: 12px; +} + +div.psidebar-section { + background-color: #f7f7f5; + border: 2px solid #b2b2b7; + margin-bottom: 11px; +} + +div.psidebar-section-head { + font-weight: bold; + font-size: 13px; + color: #222; + background-color: #d8d8d4; + margin-bottom: 7px; + padding: 3px 11px; +} + +div.psidebar-section-body { + margin: 7px 11px 11px 11px; +} + +div.psidebar-section-item { + margin-bottom: 7px; +} + +.psidebar-section-link { + font-size: 11px; + color: #666; +} + +div.follower-list { + color: #666; + margin-top: 7px; + font-size: 11px; +} \ No newline at end of file diff --git a/css/tabs.css b/css/tabs.css new file mode 100644 index 0000000000..9ae6da7850 --- /dev/null +++ b/css/tabs.css @@ -0,0 +1,58 @@ + +/******* TABS ********/ + +div.box_label_wrapper { + border-bottom: 6px solid #777; +} + +div.box_label_body { + height: 22px; +} + +ul.box_tabs { + margin: 0px; + padding: 0px; + list-style: none; +} + +ul.box_tabs li { + height: 22px; + float:left; + font-size: 12px; + text-decoration: underline; + + background-color: #DDD; + + margin:0; + margin-left: 4px; + padding:0 0 0 9px; + cursor: pointer; +} + +ul.box_tabs a { + display:block; + padding:3px 15px 3px 6px; + text-decoration:none; +} + +ul.box_tabs li.box_tab_mouseover { + background-color: #BBB; +} + + +ul.box_tabs li.box_tab_selected { +/* background:url("../images/ui/rc/tab-left-CCC.gif") no-repeat left top; + background-color: #ABABAB; */ + + background-color: #777; + + background: -webkit-gradient(linear, left top, left bottom, from(#999), to(#777)); + background: -moz-linear-gradient(top, #999, #777); + + color: #FFF; + font-weight:bold; + +} +ul.box_tabs li.box_tab_selected a { +/* background:url("../images/ui/rc/tab-right-CCC.gif") no-repeat right top; */ +} diff --git a/css/user.css b/css/user.css new file mode 100644 index 0000000000..17d7e1088b --- /dev/null +++ b/css/user.css @@ -0,0 +1 @@ +/* User CSS */ \ No newline at end of file diff --git a/css/wntoolbar.css b/css/wntoolbar.css new file mode 100644 index 0000000000..163943a6d9 --- /dev/null +++ b/css/wntoolbar.css @@ -0,0 +1,47 @@ + +/* Recent */ + +div.recent_starred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star.gif'); +} + +div.recent_unstarred { + width: 16px; + height: 16px; + cursor: pointer; + background: url('../images/ui/star_plain.gif'); +} + +div.status_flag { + width: 8px; + height: 8px; + margin: 4px; + font-size: 0px; + background-color: #EEE; +} + + + + + +/* Search */ + +.search_table td { + padding: 2px; +} + + + + +/*** for wn toolbar ***/ +.wntoolbar-icon { background: url('../images/icons/wntoolbar-icons.png'); width: 16px; height: 16px; } +.sprite-home { background-position: 0 0; } +.sprite-new { background-position: 0 -66px; } +.sprite-pages { background-position: 0 -132px; } +.sprite-recent { background-position: 0 -198px; } +.sprite-report { background-position: 0 -264px; } +.sprite-search { background-position: 0 -330px; } +.sprite-tools { background-position: 0 -396px; } \ No newline at end of file diff --git a/data/Framework.sql b/data/Framework.sql new file mode 100644 index 0000000000..27faa19913 --- /dev/null +++ b/data/Framework.sql @@ -0,0 +1,245 @@ +-- Core Elements to install WNFramework +-- To be called from install.py + + +-- +-- Table structure for table `__DocTypeCache` +-- + +DROP TABLE IF EXISTS `__DocTypeCache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `__DocTypeCache` ( + `name` varchar(120) DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `content` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `__SessionCache` +-- + +DROP TABLE IF EXISTS `__SessionCache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `__SessionCache` ( + `user` varchar(120) DEFAULT NULL, + `country` varchar(120) DEFAULT NULL, + `cache` longtext +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + + +-- +-- Table structure for table `tabDocField` +-- + +DROP TABLE IF EXISTS `tabDocField`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocField` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `fieldname` varchar(180) DEFAULT NULL, + `label` varchar(180) DEFAULT NULL, + `oldfieldname` varchar(180) DEFAULT NULL, + `fieldtype` varchar(180) DEFAULT NULL, + `oldfieldtype` varchar(180) DEFAULT NULL, + `options` text, + `search_index` int(3) DEFAULT NULL, + `hidden` int(3) DEFAULT NULL, + `print_hide` int(3) DEFAULT NULL, + `report_hide` int(3) DEFAULT NULL, + `reqd` int(3) DEFAULT NULL, + `no_copy` int(3) DEFAULT NULL, + `allow_on_submit` int(3) DEFAULT NULL, + `trigger` varchar(180) DEFAULT NULL, + `depends_on` varchar(180) DEFAULT NULL, + `permlevel` int(3) DEFAULT NULL, + `width` varchar(180) DEFAULT NULL, + `default` text, + `description` text, + `colour` varchar(180) DEFAULT NULL, + `icon` varchar(180) DEFAULT NULL, + `in_filter` int(3) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`), + KEY `label` (`label`), + KEY `fieldtype` (`fieldtype`), + KEY `fieldname` (`fieldname`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocFormat` +-- + +DROP TABLE IF EXISTS `tabDocFormat`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocFormat` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `format` varchar(180) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocPerm` +-- + +DROP TABLE IF EXISTS `tabDocPerm`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocPerm` ( + `name` varchar(120) NOT NULL, + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(40) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `permlevel` int(11) DEFAULT NULL, + `role` varchar(180) DEFAULT NULL, + `match` varchar(180) DEFAULT NULL, + `read` int(3) DEFAULT NULL, + `write` int(3) DEFAULT NULL, + `create` int(3) DEFAULT NULL, + `submit` int(3) DEFAULT NULL, + `cancel` int(3) DEFAULT NULL, + `amend` int(3) DEFAULT NULL, + `execute` int(3) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabDocType` +-- + +DROP TABLE IF EXISTS `tabDocType`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabDocType` ( + `name` varchar(180) NOT NULL DEFAULT '', + `creation` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, + `modified_by` varchar(40) DEFAULT NULL, + `owner` varchar(180) DEFAULT NULL, + `docstatus` int(1) DEFAULT '0', + `parent` varchar(120) DEFAULT NULL, + `parentfield` varchar(120) DEFAULT NULL, + `parenttype` varchar(120) DEFAULT NULL, + `idx` int(8) DEFAULT NULL, + `search_fields` varchar(180) DEFAULT NULL, + `issingle` int(1) DEFAULT NULL, + `istable` int(1) DEFAULT NULL, + `version` int(11) DEFAULT NULL, + `module` varchar(180) DEFAULT NULL, + `autoname` varchar(180) DEFAULT NULL, + `name_case` varchar(180) DEFAULT NULL, + `description` text, + `colour` varchar(180) DEFAULT NULL, + `read_only` int(1) DEFAULT NULL, + `in_create` int(1) DEFAULT NULL, + `show_in_menu` int(3) DEFAULT NULL, + `menu_index` int(11) DEFAULT NULL, + `parent_node` varchar(180) DEFAULT NULL, + `smallicon` varchar(180) DEFAULT NULL, + `allow_print` int(1) DEFAULT NULL, + `allow_email` int(1) DEFAULT NULL, + `allow_copy` int(1) DEFAULT NULL, + `allow_rename` int(1) DEFAULT NULL, + `hide_toolbar` int(1) DEFAULT NULL, + `hide_heading` int(1) DEFAULT NULL, + `allow_attach` int(1) DEFAULT NULL, + `use_template` int(1) DEFAULT NULL, + `max_attachments` int(11) DEFAULT NULL, + `section_style` varchar(180) DEFAULT NULL, + `client_script` text, + `client_script_core` text, + `server_code` text, + `server_code_core` text, + `server_code_compiled` text, + `client_string` text, + `server_code_error` varchar(180) DEFAULT NULL, + `print_outline` varchar(180) DEFAULT NULL, + `dt_template` text, + `is_transaction_doc` int(1) DEFAULT NULL, + `change_log` text, + `read_only_onload` int(1) DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `parent` (`parent`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `tabSeries` +-- + +DROP TABLE IF EXISTS `tabSeries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabSeries` ( + `name` varchar(40) DEFAULT NULL, + `current` int(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `tabSessions` +-- + +DROP TABLE IF EXISTS `tabSessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabSessions` ( + `user` varchar(40) DEFAULT NULL, + `sid` varchar(120) DEFAULT NULL, + `sessiondata` longtext, + `ipaddress` varchar(16) DEFAULT NULL, + `lastupdate` datetime DEFAULT NULL, + `status` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `tabSingles` +-- + +DROP TABLE IF EXISTS `tabSingles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tabSingles` ( + `doctype` varchar(40) DEFAULT NULL, + `field` varchar(40) DEFAULT NULL, + `value` text, + KEY `doctype` (`doctype`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + diff --git a/data/GeoIP.dat b/data/GeoIP.dat new file mode 100644 index 0000000000000000000000000000000000000000..7f504a0c5141f13307848f4907e890a59af9c497 GIT binary patch literal 1133002 zcmZUc1=JkH7OlT=?e3ZBo)FxECAb9-5E9%iSbzj~mtY|Y8rmX7`l9JvE_3mD8rbMj2%e@s<1$V1sl|$4)ax+ zze)p|uz8Lxas&{qW3C{HNDzK^r;{!(y;FB+!*LSP%xlR4@n339VjlAPj=} zd%dZR)4;U0c4n_P9qildP4Das#u<$>8P(#Lbe~o^xHwrc~*%LN~O<+e=v1C)& zQj-BTb9S_GbE7J50r&TMGCmfzvTz63+GIQ9HkszOnghL_swiy_QjnR-t$AQSvMv=*IjQP-B?^vxMtEr-jPK1--R5;C18rSQc z45z@&3V5$~cdw^bG#pDffFftYS#SYd2xr4Nj@S;p-nlTm*ET)S?7AV0d9nw;0O58 z!kghyc+C73xYgt~07x>luw@mUo{9*oQCix5gHvh-?zfmAZ&f}gp7K}w>$yhd4jOuAMM=j%Z z6Par25?~(Yn93x|bXqyu<{e{fOpIOQ0OSAs8JJ`09Mf1hZI0PZ)b4aSrqB2cIc7AU z$vAT+pT%TW;~?W~IsRvP4ol`V&Xr@Z$q=LL&z)l)^LdT)8Rs`HU`&0`RUqRFn=E2n z)HpQ9VmTH!U&6S2jwMZ&GA?ag#yHFHXQ>#0>hEdryP1Z85onsx7b+gj-a;%^64RUN~J}Q%Jlw;$JZ(_1(j?GL)XL9Yd zTjm&(#=VXG@!i*4*7nP>zxlXK(qDQ9<~S&m9Bk5G!sBxsn#m{Rm}ovJ zlN^@g@Ek{EqjRL?M`fk5JlXu1Omb|F<1&7HjuXsJG-^YZd#9LxP)T>)Q*)e_>TIhxHr#zdCtvoUXEs-AkXx?(r+Z%J-l;agkZq9K_j;AvHTXWo> z@!L#pH{K!tGx=R6cjve#liaIFX1qTx4>=xJ=I%W*w=U2_59KYxI!;(TionwER|7HB!_>Zw?l!A`_Icw&P3arc)%~e`5DH|(!swOpK z-PkZnQ?}!t5 zGcwPPndXXl*2%N3vnv@_&a+BZx@w-)%vU$AVO%pST`SMp8CQ7MGvCsu2_cYln&)%729~1e!zsbdUF3B@4&jHRJXgnj&L3s|&bBMF@ z>V!Pw^Bn5z1mn?pCgz!x=P+mcL6GL*&K{BHNRy+Cl52TRHb2IAtns+4^mr2~pO{Hb zGC4WVDJG|8^3zOC_so&mGo3xlc((Bz{Z+E^q}N%=1v5r3x%v;Nd)vXfG;|FQkj*QR}~$=P{GVjgmj1C}sSqJWpr* znLN*$KbJ|K&+|gY)$U7qUe5E1CGQ$v%}QU(^Sb#PnPiH|o5r{Dyq(G4F;RryGkIT_ z=L7T4jq>nAlaKOzZ1PDa|1{5M8ShW6FYtrz4;6U<}i`|j3zS~XD%>{$*jgf#@US0oZY1F#+(J_a(1wB zNTxHl$vg$-%_Q>`{(C)=g#`*MX!%0Mg^i0C7d1*}sL5i+#S1Kv$(JbmhCX(!9vafMJ7Pij?efB1x_?S$#}By6yvGJ(+Zq!a)!?TCTgqi zu<)Era#ewI&Ckmu=NGuZ{K8CfQGtuiFEL(fyeuod+~kS^SDO5K{w!m|iJfG>jVDe&tmrP#H*rubaG4 zV2X(%)1SaHsPtBWw+p=EqIU~?Y4V=&ePgOt-~;myjUO35HhyB1&Zk-?8UMV%7a8vl z#8(Brw&WY*x5n=>o$m|$VE&`=C*#jq=`SX~8fEQ|0)NV%G9Q-ttH9p{7AUb`iGK?8 zw9<=gT1=ny=ZdUeOczwXNTJ9g=E@d}OkHFeXG_L%kxG$jky@tHDpJpQ!=z~pii9SS zQBNS#;ON>>q+^MAY?2teMFyBmm6Z-OQN?L9$zYS|icFtLW+*aak(r9jY{?wPS+deu ziww&6Y$mf8|NH!HPG{%JO7##`{tPKHcP5#q$h_wB8RyUB3lv$ToM3*U@g!qEo~IT$t;mZ-UMg~WkuzNMXpu8b zE-7-U$yvs;i=1O}uJJsh+B)Cl0^^0oi;Nc=)rHGUq$@r}%w-vcPlc?Q0Gk%xJ-Nt*0+-q{5@%|zYm^^5F z*!Yl979KHCtoj4-n6r-;d7>{j%D1PAJZ=6=CVAH6Ipg!j7mTv=a*8AIp z<-Zqs%|w#dP2MOnrO2B_-YW8Tk*|t;UF4li=OdGMi@ay@zR=_Yms z7#PD6kx9#_TJ6&RJxj+W63e^B0h!KJB?g*LZJZ{PPh0x$44lD|IgB$JXEM%gR4cQT zm^I^rO3aq=*-iROZ%*^MN(|0QhnUP=Vjh!ujq@4jH_Ec2u~3PHWwXreWfm#1Xo+J= z99v>&iN#8+ZOz4vBaBNJmozSAT-qpW%a{x^E?Z)`Oul@H;pQu368SvRe8o(%Qi+w# zSIH!+nygl0^-Quxi8amFGWI*ZPKk9(tXE?F65}$>4N7d0@eNHz88<4ivB@S`>82$% zGaqf-JdJJFm)OPGy^OmWcQYzt zyPND$V$V#XT6<@FACrAc?3YRQH|cl$fD#90@`FkoY<@_I@g|3sI6NzzU^3A-sg$n1 z!%FELjT|__!Xu4G8ILY8xu5mjv~-Rual9qh8c!&3j>(C}lZ;Y3+2j=Csm9YvoSv1Q zQQ}PVvy5jOHT_gk>0D>eD{;Qb1;z_YTvXy>bLm`B;*yMCTH>;dU+y0D?ObW$RVA*@ zO0O|dm#-^veTf@N+*l$g6PCFt)48X_&E~gcl3Pt~Gu~d}4wE~x(z{CBo$>xy+*{(l z68D#Q!16asyrqVEy$4G?RN`R^AJKX*@l+|jk$kkoV^(;)#1k%+huU2=C{J7dT#4sR zo+T>l{S5er%klg(9%um_>vcy*< zzAmMm`olH%p}1kBRjAwUiZ?kw0a* z#NRsnYcnsWLUpj`h6?4hv-;2{S0?Ww)m2y|ES4#`v|RqL8!D1lRSRon>SY?{3T)Fl zD(&m2iKxu9HYnaI)6RIOOl+PQyP14InW@SQbav`8(`0fvqb|sZ(sX5}&*U?dnbCYE zI=a&QWI0GRKxVuFPCz2AA2c%=Tr5l$qOVo0gfU%)DiWms!D*`N}MA zqITyuS)j~v||m03EIEK_D!#+Nl&&bWN}zgIf7 zJHnE6j3djeXd?MaCMz3PF|Jx>wKA)hStHX~%VbTXg0OZb7hl(WJ>&YBe1kF@W_*;% zMrAh6B%A!ptIf)c&g7ey*}{CwOftq~Y?-Yx$<}4IG2b?mC^9>kA8OpO%uZ!?Hs3eX z*`>^`8Q;xhcjF$$J&k)A_crchl;!vUXOPvon5$zV_ryeu2q_WiBdnvH2xst~R;Uc$x8Xqv~E!=E{s;^{jMT$hzzZ*qf{c_!(%ezUW;l({vN-&W>!^E)!hohEk~?=EvsnS0G;p})c2U*>@_ z4`%wWm3gSl!(|@HB+r(4)cmnb@_3miGXA8=Q)QkudB&&-pbjcM=j`)kUNCvl_>%Eu z<15BjjsL6ldYLyYnPQZkH_ND*&=JH>A@2{Es zw=%zH{Esq!>JgB$e`}L>yZ@BwmCgwHJAdB+T@a_UaQaGm zB%8r}M&nGznT@j;`@NXWe8CC}RhZp;4&$6gc|MoPVB?SqbDPX#oYyFw`Ap`ous|k} zKMR|0V_d|zsBx%qF{A1(USWv}OIBE_!qOGiudqRdWhxA-u#Q8qY=z}2tWsgs3d>g* zUSUPcSEw+;0U2r3b-W)g#Z7Toslv*cyf0a;!s->)a$QN*sH7)>H618r6)sg@+ohVZ z8VIFzE39XU3@W=}g;9?77z;P5uyKV=GKEbmY~~iXG>)#Yd4(-(Uv>Lu6SQQjum#wN_RHd#kgyQ-7@*^6)v>#JuB>G;ocR-S2)ys zp9=e$?3d~9Utyg20mcI}`9T#9&iElF8q*0TXH_`cWMYL$6%I2$yut}4>emq_M;ec+ zaJ0!}<1xl#jnX`>!tojJPskH1oMg$###4-^8c#E-*6Ai^R5;V5U-6s@=Q?|Th4U($ zU*VQa|AGovW&FYl7iIk73YTR3Qj^OnTyAoO@k(QVajD&_D_mpAwMI#&}8}BjRYgDcKvRUy!g$FA-!pl?pEYX8KCJLjg^w$IQlVC*Ugc9wPJfI3hgMJ}{l5M4O8WKq z7nXln;j0Q?SNNuqegiN0w-rWfd)GA3;omyn8-LK{!=I-A=<52=?&k`>RQR>RWxbw~ zzH(Rf-zxlW1zD4wKi%SAMk)MV;hze<3J+LWU-ru%$#YfmRSH##)%0t5*{N13RVi1Q z-CwrLnM#$d{K>i$WVumI{h8L-w4IH)wHu+^8r<+ zGEo=w$^FIp{=dpJ)iemwQAIU3o$X9tWrivmoU`K$QinoL=RODhpLvxXPZ@ z|L$^&n5i}`xB~6G@q174y$sw z`4O4q$SMlHl$DM)nQT0!%CRQLWu?cPoKWRNlaq`m8&5IH!l_kG%eX$~KeNhN&c0aZ z>}vW;4e2~rn%9YjhGu{4IJy%z`#zoq@t~Kdj7jCF>W0fZ@xv9#{Rqn6yK$Tmn+*;+% zDtBp#^?J8i;f^Y|OW)r1&8F{vtK3uNJ}ca7Wno`Ot&hnull330^0?&>Re9KsJ>n{l zs;+;zAmztgUE~S5q;JAqz2DF?Ri3T#Zk6|}^PKUOD$kp|U{fy|RqLfHFPry2J$<#x zYgJyiWQtKyeZ%d__?wyJttxMuzmrKm?)Bamukvw~Pb~bv*f;xOm5-d2+cNm6afF9V z+0V3LS|WeGu#;a_`Krp-=HFBaYJ@eut@2%!?=6((KUIFH@?({sGRf~IKO29k@@ppl z%|!mI)*n^=%;bMn`TJi*J#+n_OKQ0q`5J{9#Ts=>BrMga)Tq`dTcWN>s3cO$bo#9{ zYBc{}ov6kvnNG{3U87SYHcx6yYtpSTpvF|@QyT{w`>jl4-fv>M8q+&FLyeg-of&KC z43YB8CVdZQtue?7v(*?lmItWjgl8td2CpvGD*U9a}v5AxS` zb{*roMorEOebw8r#wZ7HOUpN^v007LH8!rXNsUeIhWgl_%tCp%d5tY<=~@;S%01y2 zR~Oeh-MYp$HFl`6qlMdMMcbKdZ?9xZnmbvtyK(0lyJ#RB(p|GEyJcjL8he`WRb%ge zS=h&1dyA~e&;4rbZ#D68CI=X`Zya3XkQ&F=IKh(fH4d+FggbbsB@=2)^w3Ol_Auj2 zHY;mKI(uA=qiP&oL;g>;L|s0{L^{XXnw$}r{KOh3)wtEAC)YTo#?>{hsc~wJ(=5EK z#_2VruSi}}M96*yl^l`}_IjHLh@0 zGwMo{tK62HR0prEah-)X)(EoxUSHz|>!?b99^O>rW~<#|R9!isbX$$vYur)e&Kh?) zfD+za;~uL$(~pVfn2CBSYijiV8V_hW_j*bX)_5r651Txq6{P3?#>b408=o*fX?)7~ zv{6RX=(Cw)&)0aN#)~yxQo!q6Tj%8(uV|yIQ>gQ5Ej{=Cr^W|0UNe8amY#dxsHJDx zDOy~5_)|+ys&CbpRX;SV@lK6*Es;=~@6~wUSsfrB@b5!Ew4JYP=Oc3+Uq7z#iLL2a z`)Q5OWZ$*EFn(!Nbu}TIU)T7?)xWKw-;MrO<2#e@ZS4np@?(vkYW%GA?%%7biC=2` zsy^B)wIcU^SFg4C*Z5Nr)~9+}AoaArQvTa5{!>H#_iE_GEB#zOZC$0yl6GH`Vx3Z* za-B+@)#|KXr&_00XO22^)~VNN)S0f%^mUr9JFw1t5Y!3lM0HyAG=S<kO(hyDQFCPsdBObZ@18DH=NP3+JjcxXuD~7PL#MJH-C0`*XXYdFsq-3-c+fj_4_n zf9k97DlJrJi8@QxS-8&e4%Z^}H1dnq8CqvCS6sZ#9=)FK(G+=AU&;#0)>+P_OV?SZ z&aiswn`Vx>JU}P^I>YO%TxXR!E7a4GUD3T8QAYzRBO`57AzH~UNurxF)s>M|>!?K$ zHMd5cHKkc+&pK<>S-Z|yS*x>7optMMQD@6K>t!+A)csw*&IWZhtTW14g==Fwu#p>* zCkomo4w0Ihzt`K$y%=rW+&YT0ipIFQhUPSTvb9^;#kh@eTjO?hws&3G+@a2nb#_wd zJo$IdCSghEd_~6kyBT-S9MI(4tIpnaPOo!DoqbeV=a4$%>+EN<`y1tkTv8fW=YTo~ zYHq+mbq+RBr!?_&<1FE!wm-SfF?A-?nOJ91ox^P8=sJhj(;GwCIkL_X9w6s+GqzkO3*&a?4z>YQu;HQ%JErq8c)f!(;!_AjcVsD9}pMdMOizDg_0{#)?d$i7D+AH)P)}el) z&XaYXvSX4wZB2Db>-U*D&(?X)JBh|f)t|5Pf}7B;qA=>}@RF_qbzaf_uRTqFaG;T% z8D6XNdOam?)ai*>IHk^;b>7nU;-cS;?-<{$^Io0z>-?wAS9QLw^Ff^t>wH${^Ew~Z z`MAy}bv|_yLv%Zw{mOfIuXkauH_SiE{z9V+Us`97CZvDL{Y{;3>-<#b=Q`ij`M%B% zb$+a)AA0ZPUvu{@=-bFgZ1$Hrzt;K9UQO~(!r%4pzV*9ub>|Pu|E%+uMnpS*9sM}{ zAGfHil5}+Qo@=C`n5sd(L7_phL8(FLAV{Iypx&U-pkhfilh+!lDJdv58|hEoMS@1! z&>jB$dt}X)vE884Aa0N}=r$N&HT6irk$%-U!F|*Rnb+z0PlIV(aoPrRG?=r&bPc9& zFhheG8_edSnHtR8V3r26y7ejg?p+Tedc8r7^jND931xh!wo2=d(k`w2-(0TF-C%Ho zAy$@}Jdto7m(FXP&p5wP)>OJsgM}NsIe@nYut zuu+4J8?51?bsB8#*}kT;YZ=!zO1^G`^*rM1H`vg^4IBi8OVePKi{y{Ea1$$xZm_9| zgqxX2d2>0*0jS8AH&oMu*k=`Jj`!D(V<`?`+ zBIS#my|}?8CYKs7GxncZU15G@gR2@`ZLV6kHn_(8+6LE|TyMOk!3`!i8gDY*Z0t|4 zK9_~vE8OmA-=U@5;4X6o|NaJdo8M!+Hvslm$)er@oZg|9StN1H~2SDk&W z!Rrm)XfUe5Kz;VvV2b7H*PEVfB5zxwSto_}8ocl9cftlAn19ybLlY@~(%>WWj~nS9 zJdxx99saXY2|sV}g|lBa_`1P2=3h0^6Qh*BHQCHUNiNh|wgx{m_|bA@e{S%T)`eai zc;%|fFZNvI_XdAxuWqI@N1A_XS8q~i@>e50C(D_?wQo1*X+7f?X)cu6T)4?1=8NhQpq<}*m~nCA z62>Ksvapo)fAeLGy5p8`*{pOqljWNX&m=1}8DT!ss4JB8S8k@)+)a$DG+DLDYE3GB zIkG{M)tju*WKH?62mVdgX|h%`-AHv_l4M=W`&`-enylYUZ_~tOQ@Ei=e3YwfWaW*U z=?#d~HqE@+%w%+v&6{k|WXmRFn(Sxc*i2^^ldX(f8@Fk)ZC1LS$@WclFxk<#lW}L` z|3-6HXLoC|yNSBLhsmBz_G+?slYKI|#zm$3I@_bg+%=ke~4$k-?CgY8V zHkn{D(KyN2H+w{rBb|LKOj|js$^Bs()uWqCZgNbMW1DOeuxY?|dh^@l%qC|wS+>_Z zzL`o+XmVnclgv+Ua!Qj^o1EY4y`y!l7ks_mK6OX z@1|?C{<4rxeNFCcq7L5W-pQ;wc#Ki@@71Df@^q7D6ul-7GyAIK=LY)AOZK^MDtxh5|+c||*alNXx2*yJVc z2JW3aR0IZ_OJ5yVFJ85`uQhqkU65Qon$qOWCVw~ir^#Dd4o$vq@5nFVYV()> z&dRdpKu>mpbQ@VPAQzAim_A^JfI>hqAPQ&&lmf~D^?*h|MN>|v^nhBB+L3VuTy}QL zMxhxH1cU(!vizLNZ7ImoX$N!yrV1Ds5C1EvX>Hek8{ z1xms>J$2Q)b9H)mY-bFZDPXRE!2vS|%n~qrz#IXy1`Glri}p}n$&)#Q zbY`jxDtgcIApvs-%oi|!z&ru-1}NqlM@2@BN=+*z9R*zr94`4Ip-LBWcHw|U0u~Jz z8n9Tv;sHxozMHGBZ)F8s5tC%;fMo*K4OlNgSuOct0m}v~7qEQ5$^om`vEjy%0V@QI zu%;p)Z`GF-16FdWmWhHaPgYfk0@esvGhlTWX_`rGyp~(9x0Z$@U>(af7HU+cG$#*t zoYxQ7AYj9QQF6njQV`iFVB;X2$=WWYsR+n_1#q)~(E+zBL;;%zY+WufPTDVr!ZScjM2}1RNM}P{1Jyi@lXxP97Yj z+pLJj_t1a|0TVSn9DzvzhXouHaI8Aw$$vz^kpWs+a^t9gqdmtayOp_ZM5qa~xHkWQ z;{z@TxG>;^fD;4GR4}cnAv?*9o*ZzBA`@_0!07>JxR2_H7CyEk$CTBO^}8uNJK&sv za|6zkDK8%lpN2+pQxN2sI(3ozenY^;0ha_^8gN;_RRLEATpn;mz?DI|$7jJL#`jy%7j;btw?}?-+-579Fz|BFrXWkNUs|QgVopjVMd3#%cmhjTL z<5n00?g_a!8-|-XHLBz$XC@IQwA0&wBo2d{}fwLD-vQN-TF5^EJ#F|Qg)selow+dGvgC%g7Y(9pYAzK+N+IQtN|??u zO&FoNplNx&_XG`eJ){v5g|tGNAwftOrgo&D{>sDETtx@wc9?E=oiII?NG|)QdRy*> z3X2zdW(=7rWZIDFLZ%OyAxt;z!@O;Z$e<#ixXG)TLuLt? zRTUi{2^ALkJSb$gFufkBYidzlm@{Oqkij8C?2?2sb-Qh9zmmxChRNIYJKFz4RtnRtRXc;MsgD|_ zRYFz`SuJGskTpWq3ekB+Cna6!)>PIzxq2!;6_#~F)(ctR&M1HyP{|b{U5vy>g=`eE zd&nLk8;5KXvQ5agA)AJ57P4i?n2^ySn}_KYe2XyMx3%`QlgNUmnSwJmWUDaUYPJs3 zbArY~r6MX4ZWpqB$W9?UhwNYlY3}I$O0(aoU39Ki%)|7gC*NdWJ=J7Z*wxCOA$x@! z8**I8-XZ&h92{~;$i5-_g^UY1AWS!?{XG@6*D1DYR~F>efguNl>Geo~-Ow(L4>>es zV#p-*E=Uiq8|Xq{$K=dm3U$cQA(KOn2stuL&jv?nPI|00DEFGkn$j^IR*i_96doUP zLdc~dmxY`da#F}yA!mo29CAv?=^$WJA8S=P?fEb>`P^6`596LN0I zg&`N&hx0UiAs1-Qdtz(gG!R;nT5%U^m3aaz?z5AsYg+E6zyGO03Ar)krjRQYoRDim zuJt$$2-5X?wLG-v*SU%7Lv9Gs43UMU?buwtJlz~}ixficRKRr=2)Qlfc55mcTHWh8 zEDG{n+7o=Wy*o^=s_L5Jrl7r+_3=K>WUc52LLLlxDCFUg*R}3+iyiW4$g?5Og*>Lg z^`rYILmoGO!a6cF+IOr^Is0^&J~?^Di$xaR)|3B`mqT6&dBF-V8dda?ji~yon%jP9 ztJ~q%T&n8xz#Ez76yM^#X`3o~TN{)*67sHQe#rYF>n5z1@Sl(mv>PNWlJH^3N1Bi= z#<%!5LopC&{4&wtGS3F(>W6@!c@=AlxFh?yg1akh_=U*N~rdeAC2lpbwPsF?t3q~vy zF<->|uCjpj_10iq_Nqb^7mipYV$q19^4W3;WmDGf_lu7U_2+yemWZ%#Mf{8L?u-fjaFQSBh9!rRIH< zno3uTSpEN%%b&F(^fE<#T-#%}j&a?H^-R`}*w{oCHi+0T&Z0+jXL~I)|!hMWf^sf015j#d45-~nvr-+>+ z_Kw&mVwZ?rBX*D2BT8Rv?G~jk$mGCHw!f#R!CuCW+f}U8!F?n4Q$QjPir7D5T*Lu( zTcz?!Z_3o2yNw4s&eGA}SXQY*bZEqch~pxTkC+%SDdNb8qaqHAI6UGA4U_&#xsIlu zORAzF(_}b0VsgYW5yyIl6#XZo6{VVPC~Q`mCq$eWacabA5hq2Q9C1p798i%~qTbd? zUyjM(=@Dl{oGGt7tSZv1ki2UD)%p@T>PMUx@pi;J5$8u-5OH_JJ(^MSFyi)zJ0dQQ zxI_z0FFqnJ)z0H46ral?E|0h(;>w6yJ!Dr!T%8e(;D5XeT@!Jwh1VIcH{M{pQ9}@M zbCf>*Qo1EV7DW2i`qecF)tx)t$Gf8RHK;-%<1hDm8oqlY?u&RV;_-<4BOZu&B;rv| ztp}s@FIsDrX|NuOc-ToHQdR@BgO`NiZLWTkILy!9`IcO%}@oQ(J?;(av~ z@o~f_5g$Z+sCA*wK0P1$JFT4G(awJw@tJo1h%ch_#hez421QM)7sGTmb~nF{_$K1V zh@T?9jrcC&`-mSRH1QNwO$qH$r`Qwe@1m2xOnGu@2C7JH{TlIG#P1P*Xz8_Bqs5;Q ze`&LAF`&iY5&!4{)S}*^7wLn3iY-bla;`&DUCZKZE` zH5P;HiFBmgXwhuZZqaEGv7En2Pgil7nKCZO(5aW^%%s-hJgx6&(M(n_xjW8It@ znySUX7R$C+uEo?XrfD%pi#c0N+hV#F)3=zR#Ut)x-@O@I>5e1|symY!)m?y5WR@1Q znh!G0W}H1MmCx#qHix-d47QOW_I9xrbGMkM#k>x}qOJ69biNkzw^*RXf-M%YWFe!9 z7Pgv*l5ENik)i+6(a0{|Vu@BdQI|9>Wn9|0Op9TybdOb>`_o`~1*FAFEmm%^LW>bC zMz&bdG4Dr7Ayt~(>rHh0HDvV&&4E=~={#Sx#cHi|J!(2B>}$4ItHri0wrjC=i*;IT z(qhvV>$X_0#Re@lY^C2Gtna=r;%l_xIjY4*t@OKvja%uAl0>Obv^+O!F}lT=7Gqm% zuAb@=&|*uu>h5c9C=MEHIWtDrh!$J7*hUese0$sZq0d|F&|;q!`?lCoVQjH`i#=NG z++vp&ySCWPUdfK?s>>R2#ZXxd_ns{jy1iQL-9j@;X1B@Om8<);*uTYrEe>iiu9cp$ zhHI=nQd@emrH29SPLBMX-iKA|&=wQ43KH@O6I)Db@j=XoF^9D{yu~vuo^5eNiz8c{ z(&E$>N3}S*#qljpXfe6PF)fa5ahy7pIjprQ&$URk1T@4awm3<1Qv1K#RiM-zMOD!d zKdr^-EiP$ssUv@e=DD`<7H8U^x_p*b%GoW>X>qRkd0Ngo;j}p4+08wC(!8+6MV9D_ zsq7uT@Lks8@)l3Ec-j;1iWXlxl6seSWs9p?T;1ZD7T318tHs?duJfX}#i-z1-{OXh z-)M4^@n)l4Hq2a`e4A>U zT04zrq0JB<55s|ZXpD@byhz(F?HHvj z&2BqA08ia!L2ZNPQyB;L(Z{W6+DzMKx;E3dnbDdvi0Ihw*UGBiC$cb0n_1f&)aKwe zgWAm2X2muuwYfr?ZRTq;f15el%-Loke{4Kgo5AX7oBj2N0(AIqryn8DZB%yNHalA` zTtMx%S*p#_s@qP#a$mH~P%A8KT*N5(Vr@Rv+HbRfHh*&oB~e<^S;?1aGfd9tgm1NF z+ia|dKW&yXk%F>H!=07dh<5rIWTa79@s-=G(q^kRTen%Y&1!8nXtQCP)!VGmX5BVN zYyWREQnhsKcg3~(M)WUW+UY&7&DDB4eZRSBJN?jN6LTp@ zqO_T_k}GY|PQTh6(`HK(Nt9I@>+G2tdKquCdz(Gl>DQ9mwb`-FPHnbtbETG{QF8H} z+v#VtO1oOPi&5F#+UV#mBHXi`KK|XO&At}yW!&2+`F`#6A;7pc2WVK$C6q+zK+TF? z?;~@OL)wgQbAv{+&7o~3sGD-H&BQj7+8o>FIL&H30%~()o1@wst`_yuOuzrNTwLks zcKY?>ss!@{DwVEs! zp4H~;HkT@lZO&=a)>EuD7g*t3<9SBOFVt+;lb<$6XvvsMD2dV~&Psl{7D79{Q@hq` zS8BHCH@|JJGLeF^O4m3mwd>mGUjBNcvf?+jxw*}AZJuv)OPgEU+^-0?xvkCZZSK*u z(G^ERA3yGL#XF6X+}%!3CL%(md!4<{s9F!Ud8p0fZJucJux7RP{C4_L`XlC2kVNS* zXC+s9vdziD(T9r^lTg9<-OhuZC-5ijy7$LOPiP5yx!)GHY(bx*L$VS zt8HG>_U`9J6${0uwAowVQR|t18wuYuO7gZg0n3H&Y4dOMQJas|i#8uE8wQG51N+|M8n{TDoNv}uWwfSC4yThmsKeYK# zbGXB79e!%_bDO9`tHUpCer;3iQ0nkoo8Q~~)27$vk9PXu`d``*^a+r;3`(N(x3iKf z>Hl)+x|#2gGm%7DrGm4Qec&v2sCB4!sC3fX@TyTo;*Aa;>O`$=-@>L**|3v-uPY*K zcj$DOuEX>l;tu<0x9>2O6%u3DDEYt+$LTNsyYEw*ODKubw9cvvN;7o)!N1jJG|pty z*v-;O$7oigvf{IMn4`n64$F3!v%_2+7U-~Ghru0&beOl3j>z1dbg-1>aYYTNhED^k zG@t6~F{4qM3w2ny!{Qy5=&(p99k`(#KG7AyTndsXE#|D`N=tTlP7hIK*+dd$m6mZ< z%VD_=%Xe6@ipVN(rRhkZM2CWQ_= zcG#)I<{h@^uyu!RI&9fV4+&!xOkD`fWkeFCt(=uyY190|1V+il_voYtY^A*{+|#J+-ktOzgNSgy4*PeQ&|zYSah>#b^*{}T z6%H^44G!+4pEHf`q+j(PVlFjFln!-P@<|;I>+raCc&i=WNzbuIb~wUB3d$-S<*d{u zchZ+KgZ)7JxDLm6xU$1l9Zu+QVu!OkoYUc?4kvdwqr+R;PCHDklaCJnu6U|Z+0#4x zVYyK0OlQwBs@Az3&Xb27F6nT->}%)maF1eWE(J-HE^=0KrAs?}p`Eb9WhRm+t8|64 zbzK5FT+`up1xE{98)=6dwS+rd*WvmOH+0e;f+-F6hqxj)cUaSpFK+Fmw-~n=CAqDW zp5DLpY5dL(cXhb8!+o9fp~2mq^loJp-=^K8$>V$8`#U_);lU0MDKfs<)D6)Dr-#+L zm$|Yck9K%WW6|M>4*z)GKH1?Zt&|QQba=YMGaX**@Op=5wSu(gcX&}N%lvtxW~1av zFKNTnw%_4p6G@a+devDu_C|*(+FLrjV?Qs`=HE%5+q`9$l$Ag4cG9;1T95B{();fB zjFRZXQ5pPD9%@!}_`bu(+8Gq*4qtZoRCcsQ>!fE-w)d^;=N&{O{7M6=*S_kA-U4U| zSWS48LfT2cI*|N_4nKDIU6Y~1oBGob+W9;D+TrI;`ZskY5h@LF`c0c#*1M|q{|)ivH$9%$8c7MoFr1dJ8GJ zuo2UYSwzHj~rj40S3TirL`j{DF^hNZDm>J_V+W*mm{g|0zW{#O9X4W{}KL^F>F;WJ_ zi#i3x>0x_zqsSq8BNj7P%;1=d(e%nr`V=8k>Ob$*N4HRcG*cZ=CQ zX5X0oV)lsH(}TE=M%>>;%l=+5d%L21P*zJ=xWCm7h&j-jvGJ&F%x4Z#T*hd zKIYJv2`<&FmcmxvzGOlE2oHBaFXPdN>c z)cRe%CQe`0h+iLbL(F|K_s85AbCZqSWxQG5+TmMbZdC_c+!k|t%pGxhf1zGzi3!yO zVZS>vcz4V_F^B8_Ke}lZsnG{w9*lV^=INM+VjlJ?cs%Bj%;(2q9@T@mtV;j(SfhT2x1#iFr2WWjU{tRm}4->YC=^3o$QhA?xA4M%>dwo+xgrE25stz1L!1m;IRc z+^JLa{#W~6ohkO=O-)hV2pHcszGGB%$u&~%YbTK%dw9PuloEav^Ks0NF+at867y-y zmoZ<(d=~S$9xduEK#Z=H1MSk~zO3A#{WInp$-TH_WNO=&{5!?p4u3Dl?3Er}%7LF_ zeu?=b=Fga4V}6VIJx-r_s_xx>UaI9Fu4|UU{#Ts-+g&}gmE`X@eem*+v1gR$lFOe$ zLNOsqXeE>q$_e#^Mv~U5Bvcb>NqPW~SN%;)M7L%NS~DR?2orQ&&{Wh7<3lfL9w#ITUA5wiNZvRgNzV^*W2%IK2_i~Un@p21ZNhX3(EAz{aa!x9cp*ePM>g#8lsPuL}4*MvP1_Ds@cI6Pvvgx!<$5s>EduRbsBm9Tfh zJ_-A3PWl6t(B~O>rLJ|ncE%+fkZ?%C_=E$K^a1!m2?u)yYJ1$$w6M|`dC;)ppNKxzl+}^@27W^I{7D@k#KIpc?oAGoRx5P!Z~uu zZ}t!NZaL96<62o-R_7;NpwUmbC`ljt==!CZpqZwmy+R|R<#}nsWeN8t+?Q~9!W9X( zB;1;Cr3O9Wx`gW!u1>fn;o2m9Msb^`jYjP;Zy?|5&;BRem~d0V&6=6L-osv2nmJnI zFMIoaRVV+1+ci1~_h?RPqe!?bNspSE7)8(g4}CJ!!1c$gKNj~VJdp5c!ea>!COo8> zlkiCL-!c04i1Z`;c)}AJ#Du4_Xz$hH$t1m9QW&2}csAj=gy$2+`9aWuzF(f;$1Ib* z9qEiXnceL~prX;+X@U}O-x4a}3Pi>(>bxM2e z2)zPGcwfsc;Uj(jqdDw<68(W!rG{Q=np)Bn`B;OlqoxPtvxLtRzD)Qk;R`QwMSEJm zZ6*Ar z_$xBj`7=Sv8cOMCqma%&3B4r!|LgKubtTlw>X*s~@hKX(E~PG;ciEy#xl5&+_I<%F z)h@LzQ*{~GrQW5{rPC$0DOqlI3A%*c^sYf!O_Hda?vpK}NV}Wvaw58DCSAH+26WTS zLCaQ6FXmcWdQ*3qrpt6)rtdOsH|?ojaH~{0+7f5zGGjO0=oaXrg&=D)+5XI3v_NJt z&T1UgWwvg5p`5+T99`z@rtc!v++5vs+f9xbO&i%6ZO5cDNPB6QF~c_-@m&tpOo-Bl5(jrV#HE^hQqY>6&_x4%l$)E_MaK`V zsY#lmx)CrQZal(xq)`<$C$*U$qiA$Ft;^|Mj_Y!KmlM03)J;#GCv?--&3eS4$jIi& zT~6tyZ{APUobiQ5gQzRQa9{Dy=>8wF&H`#~s_oiWaSF7h^vQTeGCsv!3lv)1r8vdi z-QC?OQrz9$rMOFRcPmz$e`kkuJ@5amm9^JC_qpw8GMP+DgJ%lo*Zk4xmXkIVYvA=4_(c?5T|=03Uw)W=nQT-_Ic zSdh1|UT*4AWp$Ts`}c9Zn%u`jTIqe<*vD;s+}_7cecbHXd#lGq`A^jOrH`h5`EJjH zwg2~VXCL?Uac>{GHeOA8pvF%5cn6U4g>)yXkNf+0KvQl=dh@Rqc(so=`gpT1ej4XBkJ0PaSL-yCzbmCa z-qM8BgCB$AQIk+7Xm$R(>WV%-@8gR;-tXgsK0fK=(>^}bNa^_>ZAzNS>AF(_GLgC5 zY64uQXN0sueM|hyKECSXTWyAYe64*+k2TK3H=cOvlgE5j@VzJM4}DB>Ps)|fAj!Dv z)b?{9zi2lOm@(kjJ|_3+0W}5${HD?GD>NB2+<)n;*T+A7{OdWd`6h=$ zJv0iZxumqG3Ya=znt*A8c*Q9(Jz*jz@}TuTUBL7~{PnK9$wc!>pUh6cAfI>X!$LqVARkZ& z;#ISUpZwIQ6@&Oi6D2te;{8)yp^j3L>%0_G0l&Y3-6j(|CxZPHkcqrxecE*o?Sp>EN{P?geF zr|ERCK)`|liv}#FehXMQU=f>7RF}G=)H*p4E*`K%z;Xf02aE_OW2G8! zaKI)3n+EI}uv-vcJ&q0Hd9s;%SUc+G0b2xY8L(Br&K7PRu#LJUV8?)MwX}nHR&1}X z^L6;PZm+nyRF^~Q?VV)h)2_A%wR#sj(Wyt%X7_*tgZQ?C_J=(J_6*o7VDEr^0`^xQ zYTFOkFNi+~>zQZSj&V1tOSOp|psd^>DoTDxz@Y(W2b>ddSis={Cj^`ra74h70mlR! z8^n8>9>zN=;AnNS7mGGk5lw^R0*=>+>l3T5Og8sb`bhyN2b`h|gLvU6XZ4Jhvoz<_ zQ=kE-2l4)_6vDwMJjh`~-~gOui=IT1VGH zlOG-W1aV`)O#wGsQ==oH&V!m%ilxbLTfprBPX6^Kf51H+ zG7adxLHq=x3@7?@xvbCZ4|sBFElc5HDFi$g@VNGW^|_arZVszCimR^HQ;s_8Jz)LOE_}kBK z)h=DL1@ZT%-v|5`G2_oNHH8Wtcki-`k|8$;8P>uISTc;KPgtnsVj0 zJ-3vS8z@vVvh8H(+H=pT4$m-qhB-2EU+E=U3Nfb|n_=z@^JL=pxy_ehUT3wQ-*ctG zlFs~@ctkGu4@neap$toASSrK985VJ0E$R>ow^-VW#no8z5t;Z^drD6cm(DOU!|EB< zaObPrWwK0$WiyP*FxmsLN`_T4ESF(sUH4!SLo+0 zCBF(!%1U@m_2EF)%dl34wLOCB^L4B#g>{|M7^4!9zJ4#WK_))KZkS;s4WIe(o;I6g z*fhgfOO7;dW|Z>gN+ZLT8Md-ypA7pd=M39q*w&IAGwfutopF2P4w?U6{jsx)yJgtj zWS0!Pnj|lF*uz{=_A=Sis24Ttoyw)QU&;^3uz$)A$Z%kWgEAbfiJ_|wzcNB7{XSDhU7g{Y3>Rh?pW&hm7h8B~ zhD$sLG;Q=IJ&l@%__7R_yY`98?hN;2xH-cuo`hPzw`RC46Td@V9^~qF+3JHphC4IdrA6(>3A8ANX!G~VQa*au zT(ant-u)RK$nc;RyJKl-KkDQk_6mK(80Zynu6^7&=*4u3HNjOcIM1gv@$?qB49{eE zHp6pP){0Zm=bfk0&^z!|e9<11g95#h;Z+y4B3{ezy7j-c_OBe?b8W%t)OFuw_}&}W4;g;3&ZM-%f6VZcUCI1s=daHH)eBY(J>$!ZzFOtb(U$e@pw&}Wd{3ETc*o0 zeKsCwarx1qp&XcHCY#TkC6gtaWtJ?1vhfZxILmCV(u5h3jor>_S3|Q5aNCDv(R=^; ztfRpStRv-I7I{|mf^*0lmDq9_idk0FZf29v-pb~cY&_8N7Gct zZI+hR1OF=<8#??OXe`2-KZ{7pU7mcEOTd>$A{Ijbua zeL=N4%Z6DNvMZS{oMjPfE}D(cr;BA-++>L?qq8h$J|fGKCQBKYHcEM9mSs}DY?e_e zSD@unzIK)s%va2^lF7=(HL|Q?vZ`@4WzLv>V-VN5tvTiCLlV!b>udiWY7kMpQkmW)b$GfPw zI(=N6<&rFyT7G4gtFl~Xe!20AR9~7`+v*xiRFt_SBG+fRAEVpI3Jb{HM?S~zS^mf}U5@E<{OS2dE?yLWnT!0L<)4)QYcfEae~zhgOl{3+jM7x?wC0K0 z3^``Z#V3)WIR@t9g)qp)nR3jWV-`y!lsD-J2j>`Kg;{gxkWjV4*>Via(U&90kzJkrTsFk8a@oW>->d2-B~W8oZ&g?ca~+SJbd-rkJQ=?Aa`BSUm`bkk z+AzmPIkwEPm2`4!l4H{xW1YFIG_vw6!_9JRo?{Dhnafrvx!i7@W1Ae?Ypb_UdEVA! zJEOu$ZO0rtI(C%6UnudJ%Lw?iy>|<ZViN+!qk>OkGz$#J7oo!%$Vn{wQm<2F~_Y};FmbLfE<{hgKv z_jY^J^}wAu?sDzjIiAk(jQKq|?zO}FjQ1NKFscI|Gvo7oa37^-=}j zpU?5D`cU@<#dXb}<0lhIRMa6d*$N_mGDjUXNEj8=2<8o-&G!%XQn*GJS9mq!}SPIo>}q? za_ww+hUFQYXGosyi1la9Gc+IH)t5IZOQNGMPmm|$Kq_YQ8Vsp8eBp|tt`D`+O8g~Kpo?}Tzv81qYo<;I3YPBVds#+|M+P=6^MI9qtwWLvr zjm*bil#CY9&7XXHvwB%~ulj9NK7KG*1G-$EPF+bFJ$-lZT;V|>V zjVj9gs60pKxw_0XWsb?mYxC4Rr{y`;qjOw7{-RU&`H#W_o?@bB zX5>&`OrM_Tj67$0l*i|}D9>5uXB*EkY66^VGR}CO@%%g&q_r33P_`Sg8d9KJ)FVHA(WuB|@yp!i$wI$CrYG9s+@?4wex;%G!8f%$cpXa7L zH@kR4o*PrSzEx4}EiT@w_2r_3x8=D#&mEqMQb^=?S?%sT_vE=Z&wY6waKGLEzusgn zef8(Vc^=90Y@X-xJeuk}ndh;TKW_4b8t%9XG$GGZY3vTEO#{v5+Qd&^fuKOfl6--J zNwz>P)sfGld03!app?p$p*&RVQz5F3Rda1*p7?JTXcaiAz{v&L1v&-RD6pp0x&`Je zFjs+I>T`I3+0ExjC5ke4fq4onQDB6H^A=dJz(NJ)D=@z$3mBDW5>dFYC5skVq+iuy z1r~QvK9#U=$pT9iSgyeG1(sGrTsykJG6j}3A658otxa(*L-~)31y(GuYJt_PxssY( zU=?%K%DL1MP4U$&PlT#ntH9a?_AIcMlPSOV7&tC7ucx4#sxMguwgoC zQ@kmMP10`P)Lku~iSx}1Y*Ap_0^1eXG7Y+QfvwySsU`VuleTO70y`AgwZLu#b}X<{ zft?HN(ytZL*OB-a*}cFX|C^7hbnIPVA6p$!VBZ4!6*#EC!ItdrSO=OPklKz+GdaZa z!;FU-Ri)!_b9p|pz)=N`E^v$`#~Y6|9+!Gcdgg=zC#KyZiJY8L;M4-o6nM74X$4L% za8rSsZF@$63k!@daAtwC3Y=}>xdq0VoMS(Vex8fx7r4Mg5*R!teF8Kom9xm`mfd?&rC|#{mc(lM{1tt`Ds=(s~ zo^bw88fB`iVbR;Q0a{7x=_(UnuZef!7PXSm349!^^IErNFBua+P?K z`5Oh^D)6@DZx)#NzY6aZc)!301>P<2o~x8ea>({WOFnWGIh0&N9iJBX$yJ{f_`JXu z1->lsU4icld{yA<0^bz))>eth6kBzgBtN+GCl&ZH)sceSCbc3z7x=~ge=RWC%2WLO zQQ*%4cNV#;$X^Bi)>czw=_3CW_*YwQkxWq!)-a&R%tdA?#%`xF&QN6PBGZ^pTa4Q> zeUa&k|7}@PlSIdiR#0(Zk(ta#rmY_2;;cmmn+!=cWhMQgF3whDSdqTsfBiqjHd~}# zq+y+0k$jOtkz$cjk*aeDi;(kNFtB$tPgMV2YDe~|-hA{!N1y~r9x)+(~L)z)&c#d=0*PEnT0 z#zi(MvZ*l@q#`GqA6Mjfcj*Z(p6H&DvLc@1v`_ut z38|_xikw;GvLcrkIjhLoMJ_Bd-sa~N8CT@IBIml8v{X5qZzmU67^Nd3`9(!8vGC%4 zQ7-Lgdqt5eUA*3SRgtTUT$3tXYjT}Y-jcM1Hx#+C$W29VPJ3QKrEp7;TT_V|cw3R% zi`-#J(&56pi`-LW))GTY+*{oL1kGK%{|ktba>!T3~KmDE04LFBEyj{6(Y8UrKWpe>t^%wa9B8tkjw|(q*Oohypp${+zRFMYmv!CW+*XZiQkI+uHCy7 z_t+mr{?u+?x&mFFZ$5miYtO^InsF_(P064Tr56t#gR zX0l|6apn?(>_^J8*h(J62lwN0HCu^cCFUtHZ;3t|7E6>&f)be$*%Gyo_lGaIZDi#_|YpsOYzn> zcR$S}lle-_Ut&~=(XLvc#0ZlGODt4kVe`dPt3^x}EwNZCkrTyTBF%Hj5=*&iX-P^f zW1i>;mvu4nl3%XG@+HQRxGi4i8V^Bq~uGiT4FUTui~_)G%X>C!!@n2R*ALK z=|=?P zRouVC0VQq=xjp2-5(ky|vcy*<4lZ#>i5pAYRN~MQhm|jjjxBM7i$@xd zDsglgcS@||Ty;{3<4qLq1d|huO5o%Yrbw%?m$=gWg0wd-FL7as@g**@{4%4wU2JlRyFBp=+uEg_p_)>`% zOr-N-zxk%35=;EQQsUKq(O)m|hP}OM{Gi0d5^t4wyTm&s-YfBb8uwjWB_pMj&xWq?ug zBt0pM3#SPg6f!tu+K}l&rVp7RWTudrtv_SP!0^9@C~jgd53}?WsyHNM){tyS&hnul z!$SH(X0wwiv4Sx6kO|`)QAXH+hN7>L@11#5K<3WGGwWcMo7~N z^M|xT+U9eGbV9lz!$W3w+{Cb#x|$-)vPj6HA&Z49?o^W~!YN0jw?L=eB`zmRhpZT~l7u14*w3;dqeGSp8RepEldP6k z(GnTPtv0S4vP#IhA!9;T4Oz{tSleo=8`lb1!(>gPz5tS~9O`W?>!e+w;(D$XS-)RD zY>@JeLpBLHGUTX`O+&_p>>jd*O*S)bAF_GK79m@PY-P!|AzPY0GwLC+rZi zW5`Y+JBRFM{awA$y1H6S8l}{vij1?3bEIO;$-u4|Mdz zR>Ffl{Cbs9>ZBix4cxzr2a#6^| zA(w<)YRMJG%R(;y-^QvTSN3y$b;va#*IIHz$c-V_g&u;v{zMpreB9YAM!%T$047DycqIQ$U7nLhP)i| zO2``_Z-%@Y@>?`+sM`NYA48Z1q9NhbHf*I!UV1`N*~+pN4!E zGAZQ8kk3QD2>C{ve8`s}Uxj>~swIX=m&)q9knipDhcvw??FZFL`6nCx8uD|grmnoJhl?h!;oKHbT*HLlRf1%B1FH<*Zlxdb}nYYVy(w25D>6IDowB=BTTqQV% zYv(L8SDCrZ=e62A=1FuZ&zE{zu*^bbwk)%i6&5bDyhxcv$}C!Du`-L7Sy~=kyM$dW zWj?~VWST?L1a;jqmM>Rk*)pR%Qc2b5|J7X4YGaHmNv+H(WmYY-wk4~TS-s4f=E`}E zG~2}0T9zkVwd<5wH+4QzzXB_>ewhu*Y*=P&na!-ck#Q5_#;LbWZ6y;q(XqK}w=gC` z;nrogDRZtHvTd2|${bbZXzOfWX3sKvmD!=pj%9YTaF;T>n(SEqk zI>(rwTISd?$C)2r=7cgQroC}enUl>=Nv)D_@+NXxnbR#lqs&=l&MtGNi;9vch@8_; zGS2+GGUu1Mpv;9XUQuRznTyI?T;>u>k`Tg6%Uo9Gatq~96G;vwPY&@b%UtE!M1F0V z>&m?2F1^0Y4P|aAb8DF!Em_C!G`p$H&6?hRxr81O(L)HgmASpl%N9z0N16M}JmBJ; z#=FYgoz~uCa&MXYOg_|O9@E6$9xU@rs`HS^!^TI9j~X8{K5l%X%#$Xvolxefls|2< zxgV2ww#;)bKA+aUQ07JRmyCn`o3dBTUp2mFe7(#YCU2H`+eA?&mU+v3{q()l%KY6j z@0EF9z2slC>DO=~AC&pf67i2rKGst}spM0W&y1fNzbNyi$ydg&jk49_4d0ddUV~EM z`U*dknN()U3QJY^F&St*F;d|tb+2yzYu(928`NNaEi<{yZ{_%z5Go9)#N>Au|1kb( z{Hx60CjS`!HA++SWU2~NSLmw{RG6m1w3YZhKeJZir%I-)FwjJ5(^r_mRWnxNA7JWx zYT-<-6`#2hKfW@HaZrW9mJdnLzttUDVK$o&GuHj{PX)?U$X4i7=vK&8$XBRT;y=q! z^nwE^w0P0HWDF~mO_YE}y-wkxzM@rsZ{wK`;?_wosQ z6^1*>*(=ObVcrUJRG72ETorcrn*e1vx1A_qna@{Yeis+D)dJ=VRah|fpF~->!XlOU ze_IqH3A&hzi&t2p68}h3@2_~zKSW(Y7yp%bG_O>rX~9-lroyu3%Q?iT3ZpCWs?ifc zT7&Yxe1#P%tXN?sbwY*h6}rMI6*jA|x%#%kYBt=&xO#;#71pb;MujyitYx8`sE5}! zU&pwv^Vc=75?)_z^lLY?32fldQr^&N8yPpQpehMBb#bgw64`EHF0xgHEzR`|9~I`7RZ9t#CwzBP;A?$-x>Fz5l^{j|zJ_;k{hk zx5C~g`xvFBi2FI*{+1kIJg~w+&Roq;df*Vt53O*Rz3JT!GCbTu{TlZulhfs=!qF9u zsc>wC<0_nDWoaH?;lv6jRXD+#k|d2i*{Q0iA8zZ1{A%W@6;7+fFQ%BHb7qCJE1Xl| zEZb^)mkv0$!nid0c@@r2`30$eZ4{a?7pDF%lDxttZq%izPBMrJdU-0j!bFm*Os=kQ zjb?@3|F2oY1>;X@$UDip8u(EySJJ< zD%@G&F3%GwKV))ug?m!Ty%p|D`TZ3hFn`dP{593X=8vR0k5+gr<&T>@VU+TO3Qtvd zS}Qc*vTD4dpQ-R{h36_fuNhut%_=Wcc(FpJO18>N6<)6JRfVrByi(y+H{qiSubI46 z;q3~qS9rq>eAC^i0g~H^mZ-;qMCnX#cM;slsnI`BB@x$*&cDHu=S&aBJ*CA z;r;TFL>}g>GLN0iRb_5_PLfp9=B+Yc>R*~V7StN4vTT)6RTi$YNR_3ljI6R~mBp;N zWR=AoZiy-*ERj_bDCq(5rBb;N!_vaD7zSut&k^jCIU zL{@Xv>Zz+K`L9)F?J7r9IZ{x{j2QjRQEGVO}%kIl><{Nr7b6ixOlknP~%}nRV4~C zJgUmkRnDw(R+VF1tEv-Bj;(T>{Y!GZ`$SPrta6fTPd1)jz9utXIMv3 z&UVks{K6{dSm)d-<6L`QmGi4yV6H$@5|g=(@l`Ie{>5pOOO%PZyvg(B)%Xe3D=fLP z%2idau5wM4*DblW%5_!lt#V(L>r<fTuHs&aRgds1a3phHzM6uH03167{a=3M2$Di2k8+L{knd8EqYRi1FHN2@$mjZKn6 zX~=`jpR6(=l_$cdToixCex5Zx*Dv~u+Wf8aT9udW{8iV=uo4#2ciuo>!k#`PAd}uko`gUsd_K%I7Xh z;fpF?rd-}6`KHQ`mVBGazpL_n%6~AKWYn1cRORO?zofOlRrxjLleHH7Y327Se^~fu zmA}$jU0W*F-!A@R99045JfOx@HKwjHjf>OQ;+LgJS;w?Brn697({F~9&sbxi`An%q zxy_RDK{W=ae27Vs*lgw{<1k~NF)(I~*&4Z8Jm`6&NTEj2RmuEUCSi@TB^6`UD0!_$ zl=6D*zusuoXxF$l;<|`VExyv;rN*vy-mTHAF}%j?HRh253jpUZ?hVk z*Vv}UwyxU3xRr5BqcpcRnPmO#YHaV~&NX&0*~z$Lg8h0-32ddWeQWGqi_e%RMKSJC zW66l6%=fIZSB<@E>{Dak8V}WYxW;}p_OEeejjJ@1YaCeP!Wz1^Kd8pRHIA=wLXAUe z9BQE)9#-S~xCNF^zRo?LR}gy`{#j zHEyeMdyPA5+?DFwVUqNW8Y0ak);)H0Z;ktE+;9G%@d1ZUnxEh!mb_5o#Tt*+c&x_b zmdNKbHJ+&PWQ_@y$p2GmIN3h!^hBPuXX!szYrt?`*_KQ?}n zCLkT9^m&@_7iq&2`PVhRvHs*5-`4o9#*a0Avd;H4eyB02Uo0h{a5DT^Yox}nsm~-0 z)#?yW@Q)gQ*2qTWBL1rJxAy9YnIitF@vk=dh-o9eE`b3NQ$k*BJW<<+5C}PqlB8ru0O45y(Jz|cC zUc_)~CTh}|Gh(iYxg+LrhLZR9ko3%a5%WhZ5V2sy;x=C>V&RBI-I>x~B(+TTVCE86o)5i3WmVlF?cJNl{- ztEKrQZC}I1HI4GQcEman>qd-;ILO}Ci&)=e--rz&HjLOIV#kP$A~ufL%7&XnY#On7 z#1<}&jo8dYA#@~tm9%urG?0W_M{EOi3-@zzf8zlW2fAA%m-)dFheRA|^CKgUia0Fd@Q5S+Pn4rA zIX2=rnWy0t`uKhMael-F5f@rb&i}toR+NjRZ2e1|$)ypOMO3l8ZG#c-Mcfu~d&C_PcWN4I8__EqBkqov z5b;#RJrVatJQDF}#C;L>M?4tuki$LD4`uam#1x5&O6;+S$0MGIcrqfX?XM#R=|3Iu zOvH;3FGV~X@m$375ij)9ms+AJTe*EX;+2S3BVMyk5_bwFnr}qB88I>9t%$d6CEKJb z!FQahgqQfWgh%)XeIM$_zuIG4{N3W?h)*KcYO;2dPa{54Pu97y&gT(dXf@T@u+Ene zUq$gfx0&mFtu?D3_D1{^@r`;_?|*X-f2W>wi0>nQNckj_{dDJFovFL-bw=n?O52Fj z_%&j3#BUn4h(D}Aoj*;a{FjN+7XLen<^M$dYhm&`#{u=YQB&1p&r{c#rp~l=rmHif z<wAR9bo0N?pgM!=al7WLGk={Sb!M$I)RJtSTs{6+F4V2~09|^dTa?@~=~znMQmj*|6Pin*Y$s9^ub5YDu1^ON*6TFt%u#2~I!)I~ z-mTLzZ`+9?cG6fq+YUF*p6bibT;|eLl)264QH%5k@zzZ8l-dGymaa3>!Uc^B)mhkN z5#yqD7OS(k`I5#ZQqLnysVb=Gi(qv|YIXZbp#`{}G;!&U37R%gZ3 z+e%4`>a1eTq&MVq%CTmhwXD2;J${FwnzptzMb@dauB*mavflskuu+|j>s+DS^!u+m zo7OqC&S`bV*4eBczx;m}n;)sKfa}cW?=`llvt>PgiSAZ)wl>+O&h{qT8n-h_VLN@7 zl=2--cB-?piM~3K!mjoBcg?%i*C zoL-M#$Gwm4|I|6N9$z1xRp;zF=a^q?Jl8nRc%Jcm;|0bKb*HG#_&OJ<=e^O%t;R*J zF0sO;buKfx+^9UIcBR*{*6&p&SJ%15fB!E-v%_fqt2b03HnRf26xrD+bw;g&OLSRt@Bu&$32nsA3*ojxxdZ>E-Kpx`%SQi z%pb1vh$rx)>B3Bw!xMF0P>2EX(tEPbggQ^vdD?-VH$G$YXX`v?lAR{*WZ6nz4S%uD zOLbnhrsS{JdByxy<7>u5Q?(**)|pu6tvYYl*{Q+K4c@8quC}8F#Rl)yd0(@o&R=yt zsPkbxK0*9w{78Fyov-SAT<4QIpIZ2tHvc+nhOwFskuU1;e^`qPzpnF5o$svqZ9P7> zNt?lk5EEDw*g=6n?MshodCLB-Y<`{;}q; z2LINf!Hf+CHW<)gss__Gn644`+tdxFY5bR-3=>;nlG609njuw~slm(*hBTP9@n6of zG~yfvH5hDfNmeo+Y7-S_OEncsnthTt$hbCVlycTiRGYVxBzmbq*kHv5D>W!Ls5Drh z!GaB{4QdU#4SJ3EF90H&v>VhLG#WJRvt@^ho&=Rc9UTiL5g*=Qt_E{AnBDqwG?>#w zCQ3s(^Q0-wXZgHo>ts8>t3(!RuyBJV8!Tm=MH(!wD)U7fEM_t#fe|jszYK*-ySQwF zQ6?iBEaMPK^wABLbHA;S_MWVkPveTmY7JItuzrIL8m!u2wFYDCO0}z-tkqx*nVU;L z@w|3}b?j%|)N_*3da13{Hf*p_gRL5D-C*Men>5(0!RA)j)Ht@EPlemU#VymZlLraq zR&C#=!FCO{ch$E2^53DsjHMqUOZVh&CaC(C?8tlz4ry>`gJT;U*WfTso(4xWI5O>rq<>_4lwC>x z=my8QHkmV$9B+pwH8{D!3FapnWu>VoJf*>DmYkZ(Wu-$^XEr#i!Q~CEXmECea~x&7 z)y{2jUW4-+jB_#R4Vhff;KH4 zH@Km}wW->5CP|P&_K#|%c}Igg8@$rsRqg)`?r!jKgGUUhA#2OB(Ol7xP=!D9`cYVfp$k2iSIE^gBNG`WeIQ8vN4W*EHg! z20z;NC+qxd&(f4<;bd=pe>C{B!EaVjtA96<|G#Ybw{;Q|38kQ`1zj@?XvVMFo~jvN z*y{u&iK?bzh8mNZ|=xU`aQvgZ(z z$JLf;#t&M^i9QUDZn9!C{@A!&ljWQ7-$v*`pcR_&<)04q_Daq8%6#P}t29})8GnBK zSU(@rx4=zScc-o45Nn!GmA-{(ohIuxiCWZKjB(dp)#U0X>zS|LWP>IfHrc4jg-ymc z+1O6DZnBNZCdN&hj5XQJsDw8+*}}M`aVw*GVB03!nV->Q`zAXyIljpWO?GUuQ#~`!_kj4U}ZpCc8D+y~!R;_OXsyy=RlX&G$0?G%)TB*-C%kCMxb{lq3-z z*yJ$R9@OMulS5KNnH*|0SsiZS5lxOXIjYIgCP`w6t79!W&X`C}Y;sbQ(=E}^NcrTH zpVH)1O%J{QGnGhLhji3eXEr&@9ir8Dc9V0=B|oEZ;V^q)$J zte&;`OHE#G@?4YWo4nv!G6t@(-JQ)Z}Axc~1N%I?CbGCZ9F=yvY|<_{t7d`(-o!V*)9BZArqv zGykQ@uT8#h@_j* z=m-b57}8HTt9jB)Iq7Q=q>_vS6^+>zxfc1$2Sfd=yLnnr zuG&d+Mw@?&EnM8P#daoJ8RcQ?7TcI_n@VK9ead%ev17_7=|!6MrfqYV7Q43Ct;O!H z-P5>-QMG!AaWC_|jY>d)_G__!ixXR%)Z%~^2evq}#Zj&J-qArV4ry^{i-TR1iN1GhiLYl{zA8V9tqI`Ud6MRTPLLDc&C~``RQ(K(Y;`CJE4EvFOVlI=j zTb$G4niki#IJd>P78kYROPcdqoUf_XitiD{n|~|b|1WIC=LKB}B#)4(N>6shX9SyE zV!YINS&Pd}RC|TVmBy=DTx}vhs=BVl^(`LI>eIAoabt_STHM{@ChZJ*yuZbrEpFD5 z%yUbNTU%`H_cz|w;&$`xT$C`8C&hbQl}O~|-WK=SoA~`EQhTVy!z~_b@py|zENtr) za1JCj9V$N2;>i}zy0+ujB+76?i>Ex+PaCEAOzQKw7SE^rg%&Sr20Fc$EPOew(hPaE z#cM5IZ}CQpA6xOh@uu-hmI60O7X7ao7j~0KX z^7(X|uEoDCuIO@Q7upPHvtyT?x=ht(>Na0>_`1V1ZKiF<9r9&|>Do-+=G6|bb(o>e zjBOennjHqVnW@bUZEkEcbDLS(@z%Okn?Y>`x0%1q0&Rx0nYB%;P206Y+vM96+RWBw zm?eE}GA4mh9(0i-%(lr{k`#;Pl{QtAQkyWkv2=V zS<1?bwpqL#>nvtW^p`LnVTB}I()Oh-AK7M^G^=I%SuJP%^^ME7S)t8}ZB}ZtMw>OI zX8Ec{d0QoI$ZBm?@0YEr)@rl1)y5dtF|M2HCz%M>vs?*p&}PFn8@1WE&E^(vVjOFf z=BEApZ&wa6 zZO&;kuFZMraG&ccrJ>sMExf=ei4Mh*e0-aW9Q|S`+u&6IrK#c-ZLVx{Ra$$k z$<@Yd>_KYR+5h#%#KTQ(Zf;ZV#2#*GbF1}p9d2uLdz<&$e9-2OHg~pp+f{e9xx3Bt zZC+?|Pn&z&JksV-SKZggRq{WynPiD_n9`yonV;KCZu484U#uYIUrki|dz(Mn{N3gs2l~_UztY;I zhyQIuhXEa?>ip+9@vmg$L5GUdYV+?ftP^KAy*B?2vve5LVMfn~nJkyLfiB8q=2ViH z5AHD3RYN+=+WD^!RQ*6gsBB^`%Ys6)3yufy;Tv!~t^WsVMWSz*q8natf`o(}U`GQV-Yezgmv z4O}oK3wKzg!=fD)>##zH6+0~M(4*2oOLQ2~VaX0l*^lCmw8GM<+ht6aO^ZoyjP9^p zhvnT5k|ez(vXX7py(^nYvPy?lZM#~B)zhGBSdtj7-C>;$7j?L}!@3>DblAVc0Ug$} z&Q2Y6?y!D`4P4x?!&W96b=cV6HtDcwhq0;W&0M>Ahb_|Fwls-T@+VD^tu5K6!?qo^ zv*Gqr($?irhaFu^8YNVp?9yQ`TdBCKO?Kv8 z(>txhsV+((>5bDnoMFkC#-x|d?r@GBo@?Rx9maJy&k`vlwik4`Fm)x#__X#Cbxw!J zIy~OtGAlgL;lU12Pa@>n*&o!%gnz8=Sea zRUh7LNs_sON^+Z(@91!Qnt*DPRtWFvaJS{syeG}}K0A@*epkuQL#~oUCJ$RECy$ss znkqlh;mHoqcX+}1NO^*-p6c+liEMQ|x}jBH=q7-Zg(OmAr5AfwmEwOXnj?J~n=0{M7ha zhtEx#*>i54LzVGm3ho7`CbqbJ)UjE$q@3w~eXLCLO|N$?t$1QPcb9p(%xhti zRU%Kk&2Pg6T$`k^u=)DNMY=57Ww9=cyC_4Yu|${UyR6V=@a=m`zxPcWmv}7aW#>T|6=H%EeTUtkaGbN*&_Ey-!DB)IJwpM!j z{H_YZpXKv^4fmANszx z{>XLjF8g%jHKMO(_U*D?ms7f&+Ks<$*}uyHS_LrCf2n+6H@@R{P?v)>`uYi2mt##1 zH6GUGaOZhMm!mEDWFSX&Im%rB6)TftQn~nX=EoaPFrH{U$*6~3PSz6e-+Y|rhWz5p zb+hsGE@yN(v&&gsw0g)T2z z_=@qRRP*I7lLp3m+GVnK>>kthV$Z*6eAC+ByZn*zKXn!`|2viF{P?dqHXLA_$~d(# zNp-p&)Av}d$Lc+1u)NZv+GEBZ1AENWW9A;idi3>}#kGTb3^5sGRED#f4DB&nFV0`9 zMtSO4IB|stdSrSOdK7zPd*piLtrqL}E7U|ySn3h>DBGKy$TrC^!CH@~$D%zJ>rwB~ z=rLE1xqCEww0iV<4DZqI(dp6c#fHfjtV-j*dqt0X zkNJBnkfth$bdppT>alQ-HHQ5+qZUzgpKurNu|$v2J(lY+qQ{awM)p|74rRMkkEPA^ z^q2INn1ph>Y>!cv%X!l3<$J8qV%odaQz+|m?#aol5-s!_t>PzW|nW7){Zqv6r}wB zsJagD9jpI+E6VmYlggfb-@W%xLMmiLWUqu$%9fRkD0^fjvO_3D$sQ$y%%Yu!c1rl) z&;2-l{@3+f_jRB9e9q^5&Unr<-{>20Wz!!%M9N9N)MDdUBsaxo?sV{`FhE=HRUXDN;dahz;k650-JoREu`CEAu; zHYespA{x`QbSp`2rpC=H_BvF6Prd*E;E1 zk&6W)uM4SgwO=T{Nce_uv2aPQ^{d9E^0`b3SHI;PBb{Tg>`ER5acF4pAY ztz4{?vcc%+Ll|D^?`6( zF1F`lhxpE1?9K&m;P2ur!Zpuq8cXfV#r|A;m5Z-)@nJ4L%EcGlp)}PG?IQeT}Go)J?2EEk`PpB0`n zdQJ|$)Tq&hhtzMxf6N8FarnN?#dlK3zt6>a@gIbj3tD6SQ!aj%@de?Zx%fqd#eWs~ zEf>Fw{2{d8-v3MdZy_x&iu{v{e?=}C{Xdb*xmXA*9ypN4VV#xn(JKEV>?Q|paahyf zW(V>*tXGS9rj*ZNEjuLakXs$d??3?u3OZ22fszgsa-gsS#T>|SpojxS9k@~oqhP(3 zz;iRcQNYu@;tuO9f+C$z=h&5UptJ+GIZ)PNHJMpuL|6qM=P^m~cGgnNdJfA{cRFwv zlW`P^qr3wZ9C+1_*?v@XpppaUy!gV4$_`X<-~}&6c~RA2eYT>r16>@b=0J4^YB*5S zfsPJza-fz2cRSF+fvA>fR>3CcI^b}?>98VqIpA@?>wsIyw8Hj@-|Ijf2mImz2Z9cS z#N!Sm90)rQF{Pr?V`y6wm}2=^oBwnk{V|Xd}XzQ>7T%8Q$K34&p8J0gy?0J1d=IjeA!Ix;gNQ2NOMb+=1>6 zJnz9!51!zBbHL?-+l8JE^kS$^c$|2Wm2w6;@R|d?9eCP-eh&0^;28({IIOdJ?p)8Z zx3z~>DTL?5`wDppU>gi@;AK|oz(5BEIWX9PA)Fy>IBTb8KJyh06*4(Ygx<(UI55)a zw(_EqFF7#UfidD^9T@ljZEVZ&5+^85x|*n{rZ_Owfl1<%g*3L~pXR`9<7c`9GaQ)d zz$_`R3fUa`v7OJ6GS}G8-b3 z&)94h*&?LR_eHjvB#pN#+JjPdIIz=!T@LJa;6o`i*yF%H!}prHsP8wuP5zMs2ORj= zDP!|!iUeh~lBD9pX!z%LH`>%b+6zdG=@ z$Zrn(?!X`7e>(7&T1}sJgf_Wo{QP5j;6Eu>jeeP{w76Z0Q9&)rBczkOPULgqHYdtT zxy6YhP84|ov7x-9ZuZoL?x4ZmlGAl%Nsu|Qqknv4l65J#d*ztbtP*#akmpSjAc!e%i_6C zIF0TQp&yrsJy>2Rd`>KMVv!SmCjw6N;sWJF(20-}O`T}ww07jM6Imx}ldEjhiI@{{ z@uU+eClbavE9I6}G9$b`g4FMEqP`RNJ8`cQb(DLbu$~ijMQC%q_Zmof$cctdJYaGk zbY9zA8yV$ck;ZDZ-AhfRu-@iQJmSRTYC;PqS~}5LS&s@IbE1t%D`9IPOSN^Pof93E zY%lB}w4K`#5<8iG?xI{OT}8SXmA-KJUaxCth%3s1w7S7;Zd_5V0FV9OcA|QpO5L z3&)rUZExcwUiUmf$tg~}EW)~85t-=3Bqt`DvUapnotWmtbQ#QcVvZ9toS3QPEGJ$S zx!$X+Vy=|=M3H$yyK3SBCtklnVZk??SnR|PPWaFr9QMeG>f5?_0R^0pK2IPty{Tbc)m3X`S*sOH@QDK@v{?Goq!7$R6AFdf1UWniC<;&oA6KJ?@s(7Vn_Rz6Ms8# z(J23z*4dpvn@djor`*fN=86an^0;u53l&_}B1X%bT`1&2VHfhckk4fu>27f$zY7Ii zxK&Bp=k=Z}D3Qq`E);d4j0?9(Dds|P7fOidxc;}=mvo_&3#E;6-4ETCm2o*2?hv_M zNP{~??sB2L>)Og@x7v=Rq6?K=sLU*xu&JO{1Th;%u%2`nu51g_m3y??QhU2DmWNg%?~H=)xcs8Ro)Zk>`a&gm#T=#ZZ$RE;2%B2gck{ zE{v7(qHweeV??|cVPw1#22{mx(f?cYOxDTTv+778%o;EAuct^Wu{*GXYeas zc+-W=E^KjOm2BQ}VXX_R#n+fpG+yVzdKWghu+fFLrL*`uCN^@`vPt^8CfBZl`g<!K5^lQ3ujgKs0+tjI3vy)KXu`R3n!I4ZtA6eO3G=YT#xWG>7N_@ zobmI83tx)cmR}qF8yCKH;X5V2cj3IzX~w3pqMuy&*@gdHxXkt6g+QY`qV8AtNJUAXANKQ8=hN?j7UUdt61uDWoG8@IZxO5w)MB6);239q*?uN(QK z*mdQ1qktPZZWMQ;p!6cbLT(hk!HmU=x>3x1ZI8CSm5>2zEagT?@$0pec3PFIylpFQj zs4wHR8@1iIM?53U-ca^lDfhWiN5pPU-5dD*;;f~S8x7oez>Nppc*u>0H`v%Q5bcIE zR@TF&mS%1=ccX(F9o=}ujTUaSH9lLq(aMe1Zan(`y*=he8!5KK>;2QtjrOK2L+vEq z%_yDS=;B6KCGCa~A6K%w(Du{Qjb3gXcHQ&U40mIou^-~bAo0OMyT<2D?ocC+Fv=)5MvA{6w8MVU zjnQt5abv6-3Cfx(eA$gx+?eRbBqb-iF-3#{*fH2RO(H!^7nz|kqUTrL znC-?|H`ci^$BnseEOBG0Z05PKz>U}4m~WRg9$0Fj;cvLHNSvY_=VCMZ%cQRsE_Y*v z$VxZfbYqpVVLWyz;u;yeCA7u$ZoKWrPB(VB@s1lC+<4!Ot!`|T&AV=Fc4L#VXOS)9 z?+LH>6`TKolHna}$7U5eWORBv z;>J<#=^nT}IOfKuZj|xhHV=-waf0@4{O-m{H%__nwHx2KaoUYDD*lD=GdIqPd@i&{ zkTssWq2In#)>k(u-@0+$jUS|cC;Z;T_M;m=N%_T%pG7VR?OwX>|5xMf4>$gFBd-Vf zJow9vzumav##J{is?@)3TyoD|k@RgIdO>l1Nn#DjTJW=UN-9c~D(q4Pi|oBe(sq_PeFzdf@QD zshF8%=XyNwdeF{;_8#~=@Ox0-gZn)Qco6g;;X%@akc!h!)Pt~iM0nkQOv$+E+mr`s z59&zF2wAqaNY=!Bj|cZkv7Hd_Q?jlH^+c}6-@tb%xYkr91QbdxN=7bM|$vr2cyKtno=)%Fj{D*bo)-%%?9?bM$j|Y1_ znB~E%9=zqjS`TJ>Fvo+X9xU@%W^;wFc`#3e%6#^%e&s~Iz=PMNFEqJ}MBWfC_E;AV zON{+;i7SOGg!Zqc=;uu(S9!2ngvuHbRfH`cpbxg<>P^I*RRUwiP4ihroA zL&A?dIN-s@(izf05!=II@lQNB;=xfa{vMq6;EV^Ka`9K$6N;8qu%KP#jp3nSEf(C_24@X3VKnHh714&J$P3GWRTS}Fn}N4ui@i35kS> zUPQf!srI-R2^rfxW(Ss(WlES9vTAy$E&hNP_lVpptfS)h3F`{$3F`~*7d8;mIsH87 z#Y0{+^rDf9w-z?`qNNCHdDx34UNrThnHS9^a#egpqy;CZK5|||?@N#3zraXuCA7a- z{+KxZj3|Y6;@!M>+>7=`?;z6Ai%v%AEYd~T)qCxW+})MzA$&q;cM(1J^rDv+PkQl` z7rnjc>qS2qJS}|Y2ID@OQO|nuoJ5Wtd!WA;1C$&h94H(t9AxH+UDxwo43$32i{W03 z5NFo)NJdJrdX*p3;QK#bjP_!T7h}EnP+8-=c*%>sUhMN?JSXbatLwesiyRX;|M?SO zFJAFtq8F27{Dv2ky_n*~t6t3ZVk#GZujQF<;!PKsA!H9wnd!COV4r0SXl7f^@nWtQ z^SqcZpNnMh+6`t4SkQ}wMzOsG^(&0UUM%rqsj^mj@unBc#Fq={f5i=@R(bK3s#vW^ z=x2=x&FF2d7we2M6&^s}_Tn8cHh8hoi%nka@LESzZtr^WzTulWx~o^B(})0-WA!;w&=|$2KkZK z`sN9@173XW#X&C)NjYis!(MzMenfawc+BK}Dso(S!V7*VgRV{~d0Kcz_?hr?;aMTy zmZ9aBUVP=n&pur6;cG9x@#3@(XMFh9i|;rkeAXMw->aE_c=4ymdEpOU{3yaE{3PS4bx3N>y?1@Q_)y%35}s6{+k)6(u>fs`^k(ygEMtB*Hi7 zXj9XNT1wt6^!kwNgG1cugIk1VE|EKP;4wZ#_XcqDz>_crI?qQY>Q6JK> zi5bh3NL-i@CWU!bd;ySAlCH8oJgT>4?v+wk$cbG?WR?4zR3MTzH|7X4-fg! z)`xaJH1wg74=s&lW0B@QJS@`0=uJhMakv!>eLmvD!eVH_-d2B7dDMqiGHWe-%!f9< z|Gh!YwzT)5gAY&p@Qe=~edy%Fld|mWLl=>rK6Le=n|OE55D|7DowI7<6GD<6BAkuA zj6#E_4DaoO-F1DW^bB5;l%n+eZyCJiDcvXt+f%+UJ=L$I|=W`GBVSx{?OIa#h=))T# zi-gy`Emm@g&-&^qMQ+Qa*mbS+VXF@x`0%C=t9)4P!x|qp%it{^){1QMVV%f&AKo@2 zLO<_F+#qCB8%3zIi{2II)U|8eqU3wR_kFOd-lpUpA!p!rA9jed$W9-28NU05$Z59U z=m&lH(1(wFIA9dJyFOO3vha`(hebXS9uXcD9`oT-k>kRXKAaG-_kvU6999PNnGc`) z&`-a&I_twZAAa&#?@SitKmYpBlP`a=_q6VP<+F}WU;C`%!Z$*aZ+-aA@b5*=3x5#) zD720{1+5n{f8mbC<^k@w_^Cihd+I|sCfS3x?0HETmSYUq*qK?=?;zT zKQj1Nc*%$VL|FW?$Q9vLA0VI9^Z0R-I6Ia}Zh8I4=f^F6+-hucMDhy@2n+gA$mACG zqln=}MT+^a{SdFX(MyPw^rMtfO8Zep-2N5D?S7O~vX$@-KRkYT{kYSQyZk6`O4Sgl zAgt&|C8Jjssp3afk!r%~CYOiHnugc%<8H%qMI1t>&?R*H!6n-64WA$NB{J#vBj88S zkC2q4A1RSA(bz;qVt&MplHgG4sGXK_k1!+53Tq3iYH02iuOnoQ_leXM))VqzeZLH?;2RVwI7f9(Z-Lq zehlzqpbXmi@uWz5KRSqX^rO2e+exIeA6-Pc8oisy<3f8seZr3(Cby?ZFX2r&cuJ(V zA5V)s<41oHhSW#oS>bbj^fh`v#%$I%o~#a%{(>K)L24A1X3TINXmBA|r*I zFsz8%i+;T9$14&?3&#k@3dadw5{~y{f(T35lV_rmll_=v^dVXdr}#0|DAW9yZukt5 znSRU?*{T5M_%YXyoFIw^G0%_re(VZhcL1+(iu&mx-x`ˢ+=DP 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%0AwoYZL{^6IyO}|6N?8@cTgHY_?}qSR2pdD##EEHY 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

    wZPIp^lKYX(kL-S= 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 {8ET!0$-!cBJr4mgZOp@F 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�~$K)*6>U$GceXa=Q^uaM9Dn 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�^PYuUsD3rsq>< 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

    _;) zVkj3w`4}q2P&tM(WA2PsA?6-F*y35Slk*@^cJt9z)X@nkfhadbQ`uk(`dL zVrb25W4JhmHZin~;er_2%l*6<&Nr5fN#k}Zk}y<<7%r3| zb>eg!Wr#NvV`CU6WxUZjAT+x^hDkBp5yO-iZiwN=7;ZJK+!VvjG2HTh$HD9GWCgh` zhTBCbdI{ed!(B1Vh~eHCrmAYXqOtbw7^X>K@?Ma8RAd!1xi5y9vb;Zr2h7;A%IoPY zV>u^=xiMs7$j0zc4D+O0G0czQVR3&9k0{O)F+3T=qcJQntL8BoEL1J;-#%^~mnC{5`DzTW z#qfFzZ^-2X;hQnM9m6}~ZwdLP#JeJ%7o)uwbHAVYK4%r)^VjPcAIjh(AzN7rDqY z#_+k}9M4T=jck#)O+{w-rN~xwlV;3zdki}yGBFmvj$u~}-^TD=47=q^v%Sjv8{r<~ zyH7>ddMlCmz3hLG{-dd7qX%L*7{iem{)pj_+z-o=&HWt1FS4W=i(GzH)o(HUZge(r zG=^g_REVQu9Dl~}R}BBfa3Y4|G5j6Fzosqb@Q>m%&Z(??ag>UqY}}pC5l3l}GI4i4 z_g0xl$j^wQT-=@T%g1r13|PhDSrR?YAeG{%ry!N%s1irjII6`_GmctuRF@@PY8V%W z^&D%*Q74YNM)yRo*Y)FQAiZH6jpJw%N255-mO=w>Va#)+G!r%zGKd$UMI0@u#L*>= zR&lhBqeC1Qsta^%6GvMmd|n*wMA(b-O#~WT5J!6zsWV_lukTVi8J%riEMFRQHl%AD z-QpOmVt3)CLdNVN(o;y6%i`!2NAEcLC^#GH8%Mu5u8d=#Z2HG>c^m`8*%l41Fd342 z${^O7fL_O`4~b)F99KynA(yMg=`~DbxN*5Aj%(xYJ*$x>2lDHrFxr?n#>O!(j`?wn zi(`BoGvc^6jtOy0RMZHIBQ*r`Cw)h-lGgssx zAwx03!*RspNJx1kjz{BI5XWP2ER4gJ_;?&os2AZlo{Xa;4ogMm>GjdCVjzC<+k?S4 zLQ)vt%Qj-{y<#+um?C=-l5wQscsh<}B&OrY#o>r&gjtObjk)CGSQN)%1uSsaYQXJ1qe9V};?~c&_46K#Dh9 zjJ7t8Po%69eroJLB9+oMCME6${puSMf|C zZ&p-HxHlzgt5`{##mXX8gjEx$CQ{wh))1*Ftd)Rw&w-KaC`esly#(ruG!U}3VFHcB z&lWZ|dJ~g*vjmza(6LUbkqMleK#K&rB+xa1mI?Rm);0j~VK!2JpE>&JG&J*9botDeV#1ZJu@E8$Lz{NyjYHe1`noCM~I zJd{9CWS($-0uPHklE4!p+;|>MV1eO}C9u%&$3^(M$de)^M)!*Z60k%L*K+T{atS36 zmJ$*2B$;9~ftdD%cml%e5KEqM5!c@MCl~{s^Obd zz0|Q9K7Jed2=63Ub!{k~k#rwZPE6wZq&t(8OQL+zZS>3}&Pt*}5*3qZk#r9+m4qZ` zCsA3vN)lB?stIcgs|#x+Q8Vd&tcmuur0|ehCyBb^)axZtU%WvQ4Mk{4y^-PGr=A-p z(Znd{B+=CHW=S*`Ki4Sy``wmFv`V6N5^W^*Pok~JMZ)uh=O@ul8AxR8P;;JOBmNF)ZVItQgajnSkBu0pMD`I5Qy#yE~ zg>kOqR%hN%8*NtBSW`PrWV~=f66JK-Fe&MNH=DD;X_`ONom&EHXCe3``7Bpyp*VGi8@f#rKkUUq$Mk&4)>Rr0r)}67DZO zzj9}TkEJY6Vnq@w#aAVr6!iK@#r?tqNgNcRen^DpHsrq~aoFg;a(_(XcNLG2 zY;z5`{E@^_iQd0Y{>jNaiQ~qrRLY&M|4!l`qx>uKpYTKyJ{jsM$yVQ4DfgosjZ!!}g$gNDOu4&fr4(w2kXII|BCMK1HIeG3wstLFO~Y%YP}}f2 zDby9OC#;`BgA^K?TAtN-4<9+naQ!w;p-Bqoq|h{lK`Hz%g=Q%M|?e1%YEch&n$&rDfAZa zlR{tiH|0*ne21iKTVMIcZj${~J7KkNfXEd>2D~zbfhqTWA=g8;ZC*1;J2r6M+)pI zuNTK&r!YhI(^8n8!adqaso!;pYeVwMk1pPy!UHmUQaCe( zIVsFdVU~&yD!tj_t-84O4~frD;bD<^9HO&*+#McC;n5Txm$*RqSPBbMc&WDgPEo+` zu9R0oEfq*`b4jKC$PTCPDpHf1rH zLMnx}Y4_ARokAvs4Jm9)A)7)jg%?tIQCo`Y;SGsza+~4Q zp|m+NZ>8{U7vIEMZZF>D{vw-|!uM17kh^4C-v^$fHrkI;SeC-aDJ)lyR&Xn==?+4! zxw~4O<-X{0->MW=r?4i4wJEGi;nNg8;W*UxP4Ky`@Tkp|!bU$+*!9A$wcV=roqeCD zuqlP#QusZE@tu8}Q}{ZCU9$Nig)J$3nZni-wxzHmg`JG7t!TRpydCN*aW>(-Dok;= zl%G=A&p9N8Ju2=^;ky*RPhlTNKwA+L@TLno{-B-cNABiIj8$H6zOQ>Ag@cN4NO(Af zpHujS)0c*nmR`HRnr-Gt3V(2>O`~QSM^iYKf-j9yY5Xbozf<^!TMp0OQ#h_hIhZrX zmHIb@|75@~dYurtb-6o4e65{`G)kv&RvH!3D3eCnG|H#lS@aBHIiZ&c=XS0^@-x%m z*2`N)71O9BgKBA17O9d()wH_{dzo`c`EF#(mhO&RJq?~#aad}l-LJYePNNB3(x@ZH zx@j~>qal6MsGoNCH6Di87F*>0(rCG_Q5t8b-OCN0gLwmZP8v;R*(!}@3UY25Ez)Q% z&Wjzoa~=-Vbbol*QX(B&i?k8){ZH;?=cRFe8tu}!AdM@fw@;%(8hyks6ms*vB#n+~ zbV}nQDHjX9ZnB}yDst29l15kYZfW#PYGNtH2SA;x#C=r#sCpUpn(^GcbwRlfoTj%<9}%kPGe*m*QGHejiG6bkUcH0 zQoF;_xY{TT!qFJ6B4^!eM6T5u@zNWW#%PJ-(-@P+Sn+Xba9i?bV;+ebuX5KZ-*K9t z+KFjgpLX9^<1epoRPi??X*NMi~IB<Bwb}K8QCn zjXBb13HedM2h*4>?itJ#e@HkljrnOjEY1iE(s+b>mI6M?JwoI$)h-lzRZpf-l7`I= z^2|T&9=N&uQL|J)+!6+bAz@e;QG~I-x)X0SjTqM;fB%)nHqQBJB+^KxkxC<-#*3=T zq>&YQA&s0!F^xrOIO2I>LC84X3HD-+a~jX3@s#wZh0mO3vqb!P;ZmdXbe#)>a3Og~ z`pap&BJye)uch&N+P%2o@@{dKRc`G&|jDOHR zMdNQwR(sOeYxq8qZ`1frZ-Pn8?l*#}ZlveRn z-@OqamXTgIg$ydnrfLS2GN_zEmD3F9LQ9$vtI5nO))c2+TclRT z9UT5{t4;=WrPRx~TNe%LXWYH1fy9OxG!kJDFHYkOnq+WJ22C?~E9)K~2CXw_lfeLXoM-+SoR>l83@%ae{0uJ0puKpzjQi_X zE*(_7FoTX6_ZO_*LSK?js=6qHi=(RF2gX=T6OUfi6 zZSG(+@f(FVWpJ}1+>*hq8BCT)cXs49@!L&&DqN-P$pTWZ!Jd(i!8O&7VS<)H#!3<_A$eauw%3xjwbJYaf^75IlS}zTD z4b)&u8#l21`snUbGi7crk<5B)*iv%kt%bv-TBWUw=X?=$#;^S|^x!mrKn z?ox5L@EakU*ek-$?#tj?aYp{m)c%;kPZ=CAx|h;^1!NZv8vT%2UxzdJHG>=VEXrry3GL4ed|8yr;x9!zF8rI5zsSEC{FlKA ztr51!g)Uq?ezKTF=`6}*QC0!Z5PGS4c&3!f!n3ldkVVBTDrNuwSHiqF#44xxR?nhF z77ep#B(Y`|wX&#fyy|38SG=B4n3dODec3ktC2p2Y~$uA65T!(`)SeoYqFW-&I4aaoMa;<_wG zo7z!^oZ5NE7-hU6*NaRLPBh~-iOor2N^FIAa~8K`@k$o2W^rp4le36r5zpebEN;(Y zK^Bi?afe)HWN~j6Q^fBS-j&5vk-M{)E;23ap1pWuevcH76YtAnb{2E8xIc>rvY4sb zSy?=2a`Q&%l>OW+=4bJ677v*?^Ni&qQcl@FYKjZ9csz@cv429u5|xN@Gho>8NEUV$Q5C(0Xq?C*nZ+~4CY43e@N^cLEV5bTvT(8}oaUGp=ddt>*CPA4 zD2v5eJf*6qjWKI!_G}iQBC-pit04j1I`eik2a2FSVV?!zoT;+&Sn?^!I%;^Qp7&SF;<%d=RK z#l|c?=jP2%fM&5yWK|Zc)x;X^<5hfXg*5m?wY&l)|1^uwvL}CWvp$OrvS$?+wzw&a z%~@=dJ&Rwcc54<}viMS*VW|^6`|Vlm$YQ4n@|9`GtKFT&H(C6U#gAF+QPsCue3!-E zEcTgbOo_%^NWMQ!{3(n5S^O&HfbbXL!7L7$e*LVN&E$JnwO%w&Ig-U6SyaiPY7R%U zIK~M-2juW4r~NGc)gaLRcozRC&fjKO=+1oDO)mdsaUu&}&K+kjEUQZAP)16H9LnZ! zM$R42vvMdWkzVDEJ^7icr8_wzRLr4L4wbcjsm#{zdA;D(a;Poi>ZZ1a;?xw@%DL;5 z4b{n^u8ChShx*dJ_zmPpvqm|bokQasn&fbv#B*|JnnP=G25FW<3uD||(asgJs-5)TEDQtpEuN->kz;A?>$-BEoAFcvDLhY+0`{mF-hs$#qki&O5e4oP=)N^glcn%|!4@a135V>4y#$i+r zqjQ*)!wor%$ziPAC+09tWP*Z>H@)zD8RUA^lCUE;=5Q15_88^n9BvV(Fvl0!6ySPpmQaF_Haa+sRK-8npz!@L}(F^5GtELQDPIXrFjX3Bx7dgQqrmgKNhW>lWf;RVBAR9i3Q@Ul^8 zKu52quSr~;!^%-xt0oWDth>AcqfCBEC(lY@Hy_xUshPk0i2VQFvZdi%1A#I z_6!xvIVdkPwna165-T{U?4XK+iViBtjN{;Szp9GW9n^48?X;?zj(b?CCB=)wB1v5b z^>yaGrzu4jMQ(*Fg&h4IMOc(8R$xayi>UV-Y6cITE=vWo{0dn}!&WVlzcRAA+B@jrpq+yY)KiL{8Sz2~9UXUyCTCc$j~6@W>|nTq5e_bK(8WP7 z2fZD1bUFx8_gB}ig%9oB@PLIGimzk9MIOywOpo2jU`Z?(D;0jgI{&EKcG;ZWx zwr(8Ndd2@a80_FG2Uj~7BFmwt*BUPx4?C?F*EqP=!SxO%IT$Ig(GJEqxX!^S72Q_U z-?0wHIT-I?f<}hAx3G5N{~fCv)b6bgCOf#%!A%ZsHU_ttE_l7T&B5&s?r<>0r0R_- zlk|eKIMu=34&Hb0frDudraM^VV6lUH9L#VKa9}yO*TH=b<~w-U!Tk;%a4_4!90xNU z%yRIcNtn^Rb{U_1u7ig(6!U~$qn-ir5eJVtc-+Ag4i?DZF$W73%8SDc>B8kn2PF>t zCdlcvjKd}9AnqXHAmkvdo<-a*ki&<@TT%%L-Zng3w^mzdE3D|a(q`vbQRK69{M{9^~p z9jtJ$(!nYRYaM(deYJeom`|?k%qe6Czjg4dgWnu{Cxh=D{2=n9 zg98o@@+jb7|Nl+nkb|Ec{NmuS@?}$4w?Q z`_n}JTjN7_rsM_r&#dKAd7KdUd8eIf2;wv@op+~blCpXCF&uBgpOHtoJj&`#I7U~z*T1$~u!qzftBW#<;c_Mu7aK38Wsd#~~y^xt)n0K!TI4phnq;I+J zqC5uCIFF0-=$v<7eY_-(-g);qW)~Hybj_oi;oU`g2z%ynsnIXXqnG$IwS08xqX>P4 z{e%qIU*vM(0O1vRTq!b8NSj}qxsS^S=kbA}4as9@9#`dYbskUW@k}1W@)(}Sqj@aI zV?-X;xdb$Lt>8I{NAJjUeRcP;9cabM5lGB%HKsvR%nUp0C9 z#5}H-!Xm#zb%XegdECV3zv8!<+FSCtReZA0d!z4m@jHyo6p=f*VJQCHD&C*R19?m{ zHq-OC$M6{<_vUe*NJo7Uai;iO;Vj{ULS{HyWRB2l;-Ng|ncDdx4+|g3gBP=Oc`T2G zdBpQb*d>$|4@nRk?8RZp`mxWxj zuNwWeJo+~|x%S_X_+}n&ncBDWct`wQ;d@4ZKY#Ld5xM`B$MHP=$m3|K!cs=3W9b6Qs93guaz;NxgmJvK&Qy_2oKz@-ITRzT|l z+Q^_AlPuso@s0(YFVbGvPRKkj5MhSo9SXQm#ab$MD&Qg|c5wk+ybPI%2<>U(^{ZC6|E(3@V^^0ew`}S9rOwUjhA33o@X9E2Lj3k)y%LZ0moDIIe*41&k6OE#xtG zOu;?+j}`K0IH7=v1>DXd)f&8BX15kFiLHy@SisE%_Y06r@+K**>iceyJ6#xRvP6>G zxPqiOHGOv!Fhwz`-&w$2r`g{vGrl!6t>C^pG`)a(L}nE5Mpqw|dqvpX15AuhZwpvZ zz{~<>X#}W0Sio#m%_(3mH`lK2&&`&!^*vO;yaMJcp8`+*3wT(Z1}qZk`&a=B3kYdc zALmBS6MNY_QNWWbmK5MGARz92G2SYmlYD7RLXmO8X1zqTnz((&3Wyi*RsnApkWkEg z0fhpR1*8f{7u?gET)}-GZzS*k6p)q8!`*yb9O7OT_|~sFr+D0gDTGs^I>l z;^_jODd1W0LR;TzEzcQC7MB+Ad;u>M@L~buI=OkiRKUvxyeXSk3V4-cE6#I_*9v%@ z+bYjh_)id>d|W(2FTNQ&pD(Z}t2MHJw}AHwcwhV@?!pCpAkJ6CKIA;0G5J`^Bz`HB zM*;2#-F?fXujJ;$kH4vQwXjVWH@CNSL|#|Grv>a=)MdZr@wu)>s`t|~Li0>47Uxfae%@wd)$`8VCgp9mL zWUp|a@LS<`!tXh}I(_<4#h--x3pgNhQ23khknm^WF9jSH`Bix82>!c@M+*2ugsmSH zIVR-Sr;l^rtm@+k|ErDd?*jhOezdoid(`75_g?`gv@y)Q#QmukiYQ&g!6FV7QKpEp zMRYFWk|OxOS{pjK`^XtZlqQcmI zMfWP8tFW7p#qJ_KgguM6RAk6Xcl>)5(YuH~Mf5G=ks=-~qF)jHiR5G1$}&DY}ye%`*F3yt;^CMNBT@wjzeh<~rdBV}FgvwZf4a zb9#*`VziVoMcgDZwuo^>_b4!4c!O|45fh8<>_q+gA|}a_2M9*EvFM&AQRmNISiD(P zw+L?)djGIu_QSK6%D!jYs{-&5_T<$62z9R0IKBI_xMZA9j~DTT zlqZFeB1%O3MFfhl#2NGdarGTwQxk2p`3@*ZM>>KaRf;00AVq0n0~J(M6dQI?1iOM= z#4ch75%t?_HoMur$$r0zm0m;y5wU<^1r@M?3Ube!5H9yVPoDFfdFP#X`eZVhOrB+q zDltP&K320)(I(~m#^-qnUl6`1d`U=OK06aT`qqZ70 zOIFQ~Qu|4`S-3?Q&hvk*#MVmqF$6Je(~WFbC3b6|*j|a>B;nodcacAYe^%nJO6;gK z|2p4Ui9LXBs`y%3WvzqDu&iE92!HL7&^qzF^0A=92P^n7~01$BUm|Sh!~EHnenYh3_T?|N={06wr#H%j+Qe#4wrbW zbb80oCx+wX)i;KIvAyTwG9v2i!{cKZ9K(VMM!v%$ z-&0~ZHHOhKoJ+45hD%{&3?m{FnS1n^LfWT%lyuHwB6;|a_&LI`G|r3R z{20c>aDjw=OEX5%Lg*W|^NZy5lvvL zUJM@U(CfAsZja%i7^cQ>M+|qyFeQe&W4KG!s5UvacO{dYA06Bi!@V&)5W|B~xKF-( z`F_93it`+vXHHEfg9T;2|BYc<439_F9*N=67#>rO7&}jrp)v_?Nl(P^q}1qauM|EV z!}J)QVdIS9jmW~YF}xhZ%ov`F;rWV?T#MdMH6Bk;Q5s$@Si-(#{Bu|LA!ek675l@&FW`tqW&Be?Y&Ajq4 z6vT^>q!h!3>J>9LSCrNAzf$X}ikWXfSd#yX;msJ{is9`T=5l@>!$+)ZKBvSmFNXQz z@5b<+$ooS2ejxH8`(pz$?OYJa7saqpe9{0TUmVGo#IQ8t%VM~=!uYO`jV)%x=z&0}+KK^XvU}&R( zjZHCp8#B)!-^K7-48MziAHxr|lygyq3V+1#XUt45YuWfKh8-~+U>oPo82*j{Hh7Z2KQa6p0}n3d zz_lxe-7)Nm!Lsom8^7)jb2?cw>Q!{zY|&X^o78UIWhDJ8U}}Bq8Ul zAp91ola0=jA8wrS7_GTNmNO+SCt_-mJxn#kxA>Jmh+l8UzE^#VM z7Gdn|6w;{^%Hn<#}Z%K4IQ)(pc? zGbNd2;}sDKXN$ZloD;?VhK))agVGqBM$Cq7;)FzyOnJCHdfpC z)J9;VtO0PI4K{`<+uSSywh9|>sxiMM{6P4&aITGaL|CNn+ITPG@7sG%68=yUj;L(6 z^KC4!vCzgM8_R5S$iQM7OKfmldVtIRHU_fdc>2wDixM`%<bYO{9_v{BmRkv zRpLBMfNK9Nw^|Lfc%xsV;qEgVYi)dPW1WpJZ2V&5SINJ$@x91bLJo{ybM&*Z!3LlD zzhS9LzA^IMWbb`vM9uFcEb3tsKT}?6R>B7X^Kf8ufzOStIqw~c=!4-M`XM||%p&3|(45n6FnL~?%MNek8F ztRBY!A_oeu?QFabilbH>U&irO9JS-96G!(rj)KYm9$I&2; zhH)GmH@BFM!bWj4j-yE&P33GGM>CO@LaH^7qeaAD?P?toN2@qmN0LM1=1GTYyxK@O zZoYMxNV`aGF)EHRaaB~q<&aF40T%^x5qI#jwx~6A%#2RxNASned%PVyW_Ygj(a2f_r-C)G#`lc zX>eb>Q{#A8nv9Frv^buK<4LygI388?QIj?wQ{Eqs>h7sHo{r;%I9`lndK}Nh@tnM< zIU|l|#ls{~5=QrY6#GkYye$5D95dsX6~~-7UQ=9Dennohg|zT$6pCKFLYr?y$zX!* zIO1{qFOE0kaN~%mR>$$F@)gzs@v}JA%IkBPUAJHDe<2BVzK&yk92?`< z6vu`*{^(-X*f~4mONwve=7k8)#^LfiCq?`TJI@sQK8_#a=$yde3H%txPaFvoXq3R_ zIJU&`H_gWJa~!|0Q|#eyajjo9B5|1Q&Ix%O+u~*xw_W%rMjg4i1*Ek%OiV znu#}d&}2VN>Nj`LVm}FkQ`pKuYYBTeIMhKK2b~;rcF*)}pqGQACG4ZPj&X3TgWgftFrEA2I!>DV z@;<=9@ea;*aE`*B;9#(WA>soa3=#>;iZKp#Fx!{9h@P9XF3?^V3ar$M&B?!XGLiqEw9UD^IY-s9Gvf9jDrgtT;$;5DC~s_ zGFEM4Z!BE@cW|jB`(mdT`8WrcDp^Z;8h2=Ik?@y6AqqqaEF6C9o+BW0S9+E;QP=i z4(@jFetT=OoX|Y{9=1Sk{&a9}B%~&F==-39hot|gbf&Uj@U^e_!w#m2Ff8>c5AiYS zJRX_)hVy?(raK^iTKupRtY;j|aPX{y=N!D`;AIETJ9xpti&CI9K0AaMKEKS2 zu7jT(Y-TArc-O&a4%SNNJqJr2EMu8F_<${($I&=gz|1KADniQrJ-VorCWkGlygpKREbNUgW&CIQW^J zD}e(N_{G7m4*qhm!@*YRaEH=w4z`JJ7t%6?zdPV|rav6~8L5Txo$P21{&TR$!9NcE zbwFi$@!I8Jcce@qgNJe}VOltZ6$$fbK(A^EV?We6Fo7EKt(!niky;5b*zBq{c_c-0Hd@Km15NVk(vwb>SC(QCM|3~~ej~Gp00*6Y@{}bk(+g5m30_{X7X`euch<6m}By>Al zT@vWZoF>qh2~MDU0=*OHlfV(Q*?`AeSv?cxUVNnVdkBwW@^~ayp`us9EUg^PAnX)E zl4BDXy~!fst)CAO+=NM;ehKtXU;qOq%scewT2;(lXVqM8jx0W}WyNb9tecOs1|={! zflUc~o4^o8lt40pR01a^Ff4&73EZ8)NeP^sz?}))l`y;Jo?UL8k}xk9PEFvn1coOt zB7qAN7^}iRU3g9cXNa6BWbKShU{u7<5;;3zo?GcPTF!HY=Lydj(rb*!1wuYiUX;Ma z30#@LRS8_8B4R0xOW;!R%Y<#T@JspSa$dng=DdiFHi2srxPc{{z_kf{-o&hGeu?zxl}k?FpCmvG}-2o;Jo?P+5{f1Z_VRfKpmeq&2HJz`y>LSU-$e3_?7U4ZDtwo~_w2t(oSeiDocuEv3H;7MjFW%%W%dHS zIcm7aEUs=z;Ad6VFKXex3bzW`LAHtf*x3vtF^>ER{F%Vc1pZFouLO2*gluf}sc#*u zgU%Lm6^>7=32=mIokR!z1z2g@mB8)<{!3s_0uQ;E>cVnS;o>|O=evN5YA!mt=$<4nqNa<3T-0(=+eID8S1+=7Q7t6v46xH#5DcNa&v=;@-DG>>%A!^KgN9a>=6eR#Bs z&`C*{@!l?ubJ15}`$WF|T=aJ_z{T;(Y*;u9650vNWRQ!&E{3}p;bMr3p)O8#afi`ROjsaB;Sab6lLM#E)`umWz>50`|ooreU;<(89S= zriIYX7#A0~xK+Lvx)|$XoQum{TqFs@UMh02i%TL2170Q`Ch`gwSIT*Vi>q8*?czEY z<6T@6>0cWuhmkVW^-;Nn7A8pHMx}hBaFUCgT-+@AEs}(qw7@Lf=Hhl2cgXi{7x%ch z)5TpbCQC9!NKGa_#Cv7oeisk8xNkpSDm?iArsQE4(_E}^@tKQ9Ts-O`@1md}kGXi! z#Y-+8ckzUaCtW<{;u#k+Ts$p>>HAscdlMRe*2Qx!o_Fy=)VkP=DG&1!;>#{(x^P@1 zm`E3|xOm;g8!l!mVRKx(=Hk`;Ebkw-(nZXL?IJE^mJIDvfrJ>AHluT0WMqLnsg$Ht zAfAi#e(A}&$SF7jhGB~?N-h?;SnR@g5lHz%7iAY!F5Y%A*Tw%L%Wt`OQ#>s5ec61+ z#d|K^ck!-#>!=Iw)A>L`rgol-`Qi(N3!@SX?JRMz)Wu49EfanuTrQ+etF{#@Tznk0 z?a=-w@?Axt2xIwFgaZhRXswISUF>%8A9L;E3m02l{OsaO7hg&3JEDvAE;h-zLHLb} zjUu!brY$7jMnXEjckzRZA0_$8#b%MPNzgac|HZ|xF8*}!my4|~wz>FSYP7lC#c$$a zErfabLy|D;4i`I>(|=w39fkU5KLrNawV!hj2md7MBvChsiX@OUjj%=%)kMe-5UDO? z*aIU%UNebfiH=FMOQO9b-2F~D-^+JOqH_{Q zCDBuIKGYn?Q=OCOl0?@ex+TpdjhaU!(OnAR6D1`_%Go2i_r#uFNgORcIEiDDI934% zB+*->Uvls9M}3kwP67K0!({Z2V&NwI&HHm3SJd(s|NeoZo;v_CfVnh=BWy9zsHgeNW(mcGJk<`myA=d^+ii~0+ zBgxq!=dh0SG2OXIoR`G;N%M4bp^`^3M$QY82zRKCmHZ+hUy(2iAAe+Bn#2Q1Jeb5~ zNwZITT++OuyPO4;#4oif$gfP|swA#X;u?8PN#a^&Jc(Q6WTwU^F-hffz3>L%1mTU5 z&O|x+&~%f?%|eEyK-B>s#Ct@^}(M z)|-c^L7Yx^t6t|k?Pfy~RB$|3?=3zz>&nD3?h5ji#m&Ef-GwUmf7m|1}i7%4) zGKrUxcsYsB*~pXTAJ8+C*xuNRB{56+Wr4q7??g-eoH8gZ&EPvRpvR|wZ6@p0t4GKo(jzAA~;5&u+#VLuaD%O0xe z81;a*6%RMH{+VyhnrD5*fhdXfNo+{MZ)x%0XWYE{V;8gXf8j!Fetqkqe%7WWzD=Tb z3UyNWE{X4xuu`Z<;fEx4&9nYWqQ}41kL=+5KvE^MS-3^WQvF%vmn42oVrvrH*Z|nI zBj4YW_+30KbLxL~O2wa&kkGk9mRadLllWWB;Gd{f{L2JHe7DGd!aW=?^%IuATbR}| ze3gY1s-?`RSUrUUQf5FnFol{a93);t*tx#h3{Wd&o)D?PCq!c16zZi=KZOPGE_IbEM-^C=*O^HS#bXS~i&VNArI zIKdj5!bK_ElESSiT&xDb@qgJf=2ht>DbtuQWsRpWPWG{@%E@n^NjVVl&d{X3llgQ0N9zV{8$6to=;=#d#6kbaqBj@Yv zQzOHMAnKalv3~||6k-A zq)-;G5{7ZTnZjFgzAb!5ICr1IKEjoAaVGTxmR<_;QkXBvqDa0Vg@xiw7}XYwFNu5^ z-SUX96Zt5G6(S#}uu|j`;itk?!qriZ)}-*6Bx_UnT!c~3W|)gFB>7VKmGJ8n){AUN zVWSB3zY$@OO_792{hnPcggewo6Fg-$W??J%vBmC5KzQ=;Za6ymq9pGljp!|IzrvQ1ty*lGnw* zX<{~c{+Gg@6f6%@xSz)}Ltme^R)q*WR1>K#oWo}U4+loPhKHISPMd5|PGrDZ@~Z8j zj!0c0<@G$&7jFz^RaJ+$y}k%x;twDfR@hXEdr_t45i zYY$yKboFo@M}7}&Jhb)Ddxdomw_g8aPSiilGrvV^%2gl_?LG5?k5>l|9mP9&=uA@* z9v=D9+08?D4@Y|F;h9(Db_cWX{Rq!g%`$GIYHxAL{jd$zQ674F<`Icy*vrGwo*BW8 z@o+5DAl^^dM@X;ZJoFX6vx#{%-(UO>1wX;VKo2K*IN8G>4}(1n^>8AyR^Q_OTmFJ= zh-dD(=0|(It#dA}SnznoFwab_Ik!B;!>KHM55qn4Dugpnrny10iV;eD=saD)&+u@j zXYL~-J)A2tN_dv=Y$1Km5gF})%e-`+7s=1}Fec&`h+ODltVp=E>=F-`dN?4B1Jk(7 z!#EFthceUY;R+8odYI^8{X(lteT#pTyVAo|9y;(XfM@Rh*9fl_(s`Z8c$Rr2xxvGP zh*vw=n&jao4@t&S-@4f|12vO+kB3{BY!A12xZT5D9wvKcki5ggot_!P*LJhGb1Wp} zQ#{-)g?$n#-|OK%5BGa`z{7M8&v|b8Ci&XFb>+;vSwOuVcNk!Ft`p zwOs%A@PdaIJut{i9%g%ZRiR$?%$P7!I7|47aQd0n99B?Ei`Q!&DtcMl_Uz%`i~5bM zctdHc|GQP`Atr-AI3^{IhlB@rsWoqkc~#1Ex*k^Y(Qd2RKuU1Xb(QB#3wp!0VPWlRQZ_D>Igv1NKZ z0K8&1JH>93$ekYkR;Yi3{|a{rLxum;@b(C;v}uGDLK0@MS{l{U;3S_NjmY7sMjAEK z=#|FNX&jVBtu)%EaabDX_NmA=wQ8rq9|P4%qi!1Y(x#6$OQU%j^~LFIAkr|6gVSgv z-Z+gWBK#Q*6?ip`oGsF5nKrHEP$B<|cSsto(&h(wtCd)rqLyBIv4q*8m0ksOPigmBu7Y-%14Uy zNaHAxo{@Y&pNeDBI5v$wX>qs-kz=yvwWE*z~ONDzPyQtiEZieaW=^erfbin^9tb z@Oa?~LJ9|_F+?NDkTiy-aZ(;9=W${h!&nGe9FoOJX`IYqHiH@&oRY?=X_V8bVy@E| zp2pNP9;R{=YXs{ejq}L)@Iq6Z{|nDdW2DF^A?0VKaklt5!qGy$7N^(wX^cr@LK-)w z%{}OXw3!26lE#HB{4_3N3G>7MI_9O}#c2??bH6bs|GWjHF;2?Y2rn02A*6*X)3{3f zY9YVNqmb9NX*^EDNC2cMY6Eot1E#-y~lr{5$bxmoo^a$6d=i$BO3 zm+zgb;_&|wtkApUoSeoK5lZeBxhIW#BguVf+@Hn+Y4E34v>CPpYCaUTifL?GO|4C> zDlTbkJ(9+w3iw#syu!<-@pu|fr14}LPf4Ch<7t)ZoHSlbV|p6Tq%k9nXVaL?tCRIy z8qcTkavC$G{{joMf%T%i7%3~_C2QX6vs>RZnW9`+a(@}JZG~6_j;#BseoJyM)yL3`5Eh7xb#4xovWiu~iehX<7#Y;k8 z7zlgpGK2R2(s+}NpAxqG4Hh4N-b!OZ8#6AwoyOd>nasSC#=B{}m&W^Ptd`^h;bP&3 z!g<2^!Ue*G!bQU0Yng?YCE_GY(^!_q@-#k5V?`RDNdB>qH>Q>1lIB$!BSdXl!gU3v{kaqj$54Y8h0|n0eF}X?)54&QE~T_*!Ir8b7D;OBx$E zl1Q>q_=9kh@LS<`!tc`d8p`3_4`Y7)w(PGH95=!5K8l zpm7FcS6YWir%47)MX19GZL zZ3g$BW)?TvWz4fodtq;G!QEta%%D>SoijK*gX1$eA%iX%bj_H(CC6k;XX%zf_Y96u zT#V>Q89yq6o*DE|VkqQOTQ3DUTE3KUZwbTF$gvsp&Y1DGPX_%m=C@YIWzbiILSB^g zk3tQ|fIr$}a0Vm}%wUkb24^rtHDaYn^H~|3oxwR7jLzWP44#z2c^RCa!POaDlff8C z#%6F)1{XwjF3jv*C%jmaDt>Ul!Wm+ta-!3OL?-aQ! zgUL$al#E$XzgxJcjdhQF!;fX|&)@+$pAbHn!J{G%38xAl&S07djWD7|#2L$DB9uHH zNysUGDubsbnV!LnNaq=)gbL4Q@SKFt3ukBWLIy92za*R`d^v+T%dD9hGh+$2bH5_a z1>0BYmBDLLqwnkNxq53PV^;cx@v3yr%@JR-%qDWWE$Qt3NQE&!fjGswot-R>m-N~Z-iwwS$oW{SB z{?{3-&tL<`H>Gx?^!FuzQ8O(28b8hcK7$`P`eku&7C&b26GzUhsnE?CY~nEv8T^sK zmJEJYrTmh?uNiC==h(h2gY6moCMU;ahT>#^W5Q6aTGRPw2LGu^kpCsJL%1`8zeWCG zgBRJA!EO<1a(criM6xFXD~k%H=Kvvu)r8fBRAbvaFyb|`s2TBtL^x%toi%sHI$1OJ z@~WFfJ@NX&29cc0=8dvwoHd&#uhZO{JH(nq)|zI~EaJ_xXd%v93=_~Qi`H4x$fIT+ zhi1_xi>e&{mqXhu4$C5!Lq3OgS+viZvlF}I&_OW{%wkX$9kb|^Mdz$}yk#PLXK}cA z7h%^dx`}ib_RQi4kt2l+(j$wbBHm=UdC2XR#nD+DBO%`b9V@~=meQ*a%OQ)tDh0Y5iJvJvNysQp&f=6TPR-&p zNlq6I7mkQ@_*8yI#N&NT!bWB>N|Li8`Po^V6Y#`W9`nn>ED@86BhLiBCvbZ{HUbV0d zvw4tQ6ZwwM;(GBLg*ON%M84q@`ot_IMG`iKo3glB&Rc}Hs;QEDp3mZiEbhzV{wyBP;t44~Abd272eWu6Yi8PEkf~WbEU#&b>yiCp zq`}8j8jPC!$t<4EV!D){QoPKGGM*8HmPX&?}vv?^==gV2l%wmpWq1P-~ zo1Migl7#w{zp5t0B7JSY^i*aM%VMsAFgCF> zB%4Jciz541WG%0h)2oz)pT(P!2U(OA@PG2HigFRwU1<3&X}&ErM#RLwBmQm{?`83R z79V7>Ad7`rd?@+6EauA^mG{3EWwAIaJz5T*u5BERexYHJqTve+&OjqFSFA6fj#(K3hT zIsBEyjx6ft%spji7Jp}PkoZ4Y{F?=Gs3zyGEdG<7-TPVFlZ7Q;TCNZYlS-_f!vQ%Q zm@_?{PF^*nP;);?n4VfW)Q-Z|iG1tjP+!6ZIW)?d`$EG==U@?rZ7k9xho%ZeoiO$m zk!HIbTIO&_4y__d8E!p4*XD3t z4wEDqPt0MW`0P#A4LMB6nbpXBlbjoKW>ue(WgCqBn{r_CZqDHr7KKtvA)~%6hs#@9 z)j9s>aEHqF&K&N_VX|tRMe+P4d*?j&FiAPg&f(P@?#to+9G=f%-d|=~^?(9CmBWJ~ z59Kg5hlg{RmcwH?Jf6cNIrI4TXwKXkNO(jKi-`OQwQ%PB$s86=G37>X7XM{uy6~AC zX5{d!I2YlcQ>0X5a0X#6UXYO&g)a$T7S0sT622m&6jtcm2Gu`lS5AL^`=@M~7O$d|&egnWLd0cRt}cn=g|jtB{qqLfv9HlyREbGXxG^~FORcng!#>zGnz&VNzN7F=}+9P$7RwB^0+XMm-2Wy558m{ zn+G3uZqJ+Z$}Y;|;yf-N`@7=TFA9Ts`0u`&WXbD z!s~@Mo2Lpc=1d@|Y3%J}dHE9?wUT7xH*9;#`WKna3=4s}>dKH?>ATRk4Z35B4?X_G%t; z@|e$F#_pEK>&$E(ALj7}yA}V&o<})v-bz&F5zE6?vBdL8<>BSwL?xCGafM0Yd@lP( zzS%r7;^795oOoVXh;)h~r96BQ-qDyg4j@%|EZS_w|0=!+$eT^GZwlWMzMaQhk#~gj zeK(Ky#NQX*+p>bfdF=AXT8*1p{9Ool7{0-M(KMUK&OH9kV=*(!t&(isE39wUT1)a+ z%5vZgA&=#Gd?damkI(X0A^x$D3M=#YB#%{jtd@kQ+fm5t(>y}HHY)#(EJN{id3+(| zFZ1|DYG38?wIu8F*dW51)4wVmcz@pd3=}0_j&MunjiA`F^``V#JsZM z5|H>7A>W@;!XUro&F%$Wzlv2iW=UKedom;?p1#@2x zR~Ii3zodXm3%F2xtneb?#X{bgs2u8F7D>hxaJl#uLcac>&8rKzrhq#nxwe4o3Yb*D zO$CgXgl~IqEZ}tq5X;CVJtVZq1LRpowq+eXfQiG0=j_PqFgkaXK_qm-{GYC z&I0Z#U~<9i3Y${E-39REb8-f3tjP%t-diva7rgE(;Qoj|P{4!Y4+*CV9~Mp%QlA^c zIL1C&z+)=m$AzrECq$ks;3<)(h0}!>>6GthmGVUeEH2==0-k3bHLwbt{HqzfSinmK zysZ4rDd4pNW{S@ez9O70d{wx&iL&JvP%faVfJ!xByMVYztYDtsS^iD|2}z0txCJB& z$P|z*ASEFcJQ-wPNJoUiTog;8fV?!Rz)1IXjZy)=}NdZd>SXMN>W?5wIa~1XS0zOhX zv#wW&d|bfF0zN5Vm7HrL-_-?t8gXtf`7GjVMYyYET>)Pd@MQsCv0jRpS;W@`tS{i0 zB91MZN#+JtTmjn(_=XLvU?iJ_KNj$<$ag}@zZdzTfGHcz9)q6>*j&IC34e)nerCD# zG`_rk<#5r!@a-H-3OJ;QRvc2Kxx0Y>3izXdKMVM)fE^P4Q@~DsNcT63B}nCkv;36 zB5Di<06_A(V&QiMI2m2Bk5Ct7j3>BrHy^CX%WqeXi-GV zq8WT>p}CZ4lbjc0Bxk_ZMI5RayA;u;h_*#^l9OJC716$k4n?$!l0+dxbu1z*hj8@h z9O)k(sdX))TM^xhIHHJN5*}GZ4-rOvR1rNR&a{Quq@2c&jx6^sqE8Xm7I9q>#}(06 z`j-{akApvRRKyuY3@GCGB2EcS6)~`gAw>*Teg_pXSaRBA$uJfs_{1WH6>(A#C(DcR z?#l(6G&wa-E#kByhD%{YWPuODhbnnz7BRAj3yQd~h*3qHRmA8b&Sk+$^Bf^F66PhW z<@1U-U-GcDnVvDKh)`#25tqpKq9QJ4X{$+unwLr*rk^;jh|7z(Lc%MHxLV{YVVH|+ z#KYz^zKH9Km{P>uMcg3yO~MJn8;h7IGD*nU(H0&R!p%QL+)~7?Mch`zUGloUh&x2? zWWm-q`C>tZDQ6-l%PVx=Q^dVRJY2-IBJPv?fg&Chxxcu#$2}w`BMLJ(RnF>PS3FY0 zqeVYFo)mw)h{B8t26;-(r-gKeLfV;8#Ir@bDEV_mJTLMBgLgDJ;>B7B zD}wx`C?&Isctx7;6frxpnJ?niBIXqFS`n{Hm=?ZKL_(yph?t07M7#*6XigUoV+pH( z=oXPIA|*9X$V7%0H8YZAg>>d33xy(z5|)HjLSGnAM}&36qW+)wn?<}O@^%q(MZzKt z>*C!a-YepL$>$fbK;(lWJ``cR^EfoAJui$Ti`ZH;elC_|iEwG;%lF;OSti;n{ZSDs ziukyQl|_6~#4nPs5^gHu+agvM@o5ojiug>zFN#x$+ZHwwRue7_R; zx`_268-(8!u~CHk2`|!``FC>uSj0EFV}4&WI}Cr2FkB-0Nqln=TSOSe&qahU`hS&V zYb4($vYl-}??eA6;?E+^DPeR8e-*K#h}I<>TEfmErZ%$bm&`!Q+v49WJst#6#J@%C z65q{nzJ!`3{8z*tN%+~CRYFAxD498A^^%!cRTF1eo)mO|BnJxlZ7g*Tl70S(hMKiX zs9i!G2Iq!<$?KL(`E#2ACE+)%=X3v$gbhnLSUQb_jZ0`!LemnOmCW6wg|K;PZyyZX zNlR%SB5WlL$Kf_5v@PM75{@mIhyBA!=vFdo8tqDEvjMO6C3Fz)DC`u;JC|^H#Jh-e z74nsR_mWv9;B|z^k-{D&92LoXme5Q5=t%PJNUJxqz^}$iW**W)52-b&=O8mC_1S#OhHbHB+NdqQzSf9!qXI%nj=(4 ztd!GBI79qQ;mAlns)Vy5ezwT07S_2XoL53nLb+tVfH=Q|i%Ymf4PZ|SE_|be$`WEF*d@3nBuj|Pf>T0*jrM9&Vxe(zl2DS8PRP?Gvp+K<%nIqu ziR6Wa5{e?F$k!LCcCb~&Ucjp7RuJFp#9&wAaP(#gZ$SFRKi;Mt}0=*V*He?y~5aEBl%}aJk!tMpO>(% zgi{%ouYl$IrSPi~_#qGHKeWGrQJ3&LB_(WR_bK7W5`Ll)9$aQw-)fZju7vMP_(2_( z&%(SouV#$wJDX+j7o}uN2|vq8v&_q{tiI0HR%LdZGPu2j-)LMb4AkM#+<$WLFJU(a z^AdKH%yj*YMpn31xwC}7OZZ1Z)&d9Ze@oaU`!q|*9z{xdH6NC53a3Iy0)OwExw?-7 zd~-WE&_^x#lGpH2Q$q5CeB7gnR&7aGCJbKJM?D{Wxx+!YzK;ez8u~cc$2&gW_0h;j zV;?X3nCYX5kETAZ_Hm7mWe^wHBtFCT~aXyv1wkM_QK!P;7QsBb>S z;>Ry-e6;nkoo9r!&gn7t|NH3Z<8U8cd~}lhvME+)ANMY?NO~M2{HBBYNBcO&#~g0m^l_|@-ah*K7~rFikK=sw_0doIw8r4n z=S31;w069Y6QcCc$%~qUd<>Rwh>xK@PV}*;j>U{z^{q9gok;_8da`fs>7#s{<>M3| zr%L}cA0sIDFLgW*MmkX-A7%f)y2xKj~b=VQE&>wVndV}g&HeB3OvH~N_9W0H>@OHD~G z7n0OiX5HfBRv)+dxLqlskd|3WVVQ?1xy#37722_1D>00V_?VB!ea!IjtdA#rJn3V)k7s;5uV(X(0rik586bBy`S_jxBtV`~Mk= zd-8p}%0?*RYr;2#ud^Q8S^T7{(nrk4k~$_X_Kt7sno5lOaC{`B>H5g|$ook8Ncr%5 zq*?wgtqhx=K8~h7Ydk9LR+4izhf#d&Vx66uRHh~|+@$fPkpa2~I3fVY8Md6BORVX2tsVi63UJX9t7m{-f$5d^>9f8c)FX}! z&^y4x8!&AH`UE&Gz^?V!y&io7^b6pwKyn582N)3G=J~i~K8_D?LV#)S;*obTFu2Z7Y zCk(M_vEGMSa{|03uh#>77vTELrtsZDvL+y&I>SKzMlnH5MZJBCjk}(SR7!5oJ)iZwLHMm z0L$c@HrQ%Da&IYpBng*dsPl1P{>iv9iina`@?9o&L8 z=@?@RIZ0ZU@xoXmX)Q^+NPcJ;ZN%F~lEXwwU+lHev5Zb-Gh#efM&~jPFXPNevr8GL zi+2@vE2DcEN0f178G{%~oxO)h-!hJhBt1oX36C!07?ERzy@d?er;Ovo!vTSkescB~ z4iFwMJV7{6DWuw9Ifn>`3Qy!Mpp28msc=deCyR%J(y3*fRyG6O@G?e3I&_Bdo)P7g z$|K7dRmNG7RLF5{dsMn{tK%Q#p3JlPpD)r`7h%DAA63(FW=#(ibnUk0an7nN~C z857F5xQt5_6G9|pm z%l`GUP*3xO8_T#w&WUAAD&wa8Y~Cz6(?bilmT_Adx0i888I#MHQpTNS+!aMc%T!~G zq4M2j+*8KA`}xu@xN_lATu`(W)!V_gYRmRh0 zJgJO?z6>>;J*bQs(xGr)dPp`5w8m9f&$D@#@nRV-NoT(B6j14mN zaT%YLv9^qra(+_ADv{M3bIMr50cxhP&(-WX&8@CcIee~;@MRh6%J_n2o9`_j>QMQs zGQO6PtF?3En=&?*@vS;CeK*OAi4T=YsP;n{KbG-R8JjiMQ5fcHOBp|xv5Qqu#xG_3 zTE;&LzO{^PWo$3ww=%lTGPeu{;U}EGm+^-bb_)M2qt-=9SIIs#0s?e|sHL6gv3iYeZ*vNU* zK~*M6b*fOS3bm`u7)$3n4Gq?>%XrhOsbSX0Wr29A1Sk3fNUhIgNZL%STk<$SU-x!ckS|S%qFzW{jl*k=M~xIHn4H ztI)4%Z>u;~Wzt(_nUOwn9w!Wgumnuus3?xF!YNfawF)OxVPF*oRbjAFI7GqO{CFRv zGV?N2@)L!_{ts1O0!KsjzJEQEJtEOgdnzey(qfl=CzR|(sAS(|DN86SMP&;iTj<_9 zGk3ppcN8ijzDZI480JSOKRWx-kL}>c6Ml5@ zqp#d{^`o0=(Zdf`|4Bcd@}s*SMu&5K`n2bt(eepMPg(U6GKSuM^bvncL(Z-KvwrmV zW3V67O8W+I;Q7G;KxO)82MzRNkW8q|W9ehQ=lys=k{A6L;>SxGGwubIt3%u2evI&A zydM)Zz()EpMu9PFlx#-}c?mRD)uDWxBy2-A%S7?X!b!rH*$(xc0N9&T{FusUf4v_YB-!Z4Ca?9F#V|gR ze6w(iaI5fBA$0e&o3RtBBA1_*|qQ+$P-a#|{yx{YNgX0aOTpmjOR1 z>zE(MMSk|g@9Q?hK$t0CxqjfWQ0- z;DG>Y25`5M_elBP0BVUmq5*uL=b>^d--7|v4xp}-9}1vO0FR2()x!Zi;&GPZ9+W>u zx%`mV3!uJqC}FapJU0?H4xmW@j|b2+fKGvPcPPyQXd~WS*us;y44{?ATZ^!EZAIF7 z^7bMfgdNr691ooXctVmc0rcds6z>{9w*a0D;3*}a7E-ypHy(OO;?A$$UhXp@eFEq! z((eMDXT|#q>1Tjf`k(*?tFm_m@q7R;(0>5o0A37Wh~&WlUJ78S_=*6AiHr+id;r76 zM+ip>M+rv@#|T;0SZ{1kkYsWIQ$!{PFiGTPp?l7nDn3^@P56rNRUyaf^Z;fAFjL7{ z0n8S8E#N$<;Yo@(M-mcVNWUJy8%oX#V2Q~50NxDXtpNJ)mok#PExtfV|L+7~Rq-)* zVE~H)cu$@`kS2xi2Qa;bvkS3U68BntsW@$y1+ZM49zK*qDz6M+RRAA(IvYh+2e8JI ztPSAf0M-StUXl$$_k>HIEMk)+p9nV#w+NZLRpiqE`~d{S-P1a=3?)rZ(_$$loz)-` zK$OA&zExH%fbAl2VM3S;z!pgbkP}G@X`TrnD}H`0$}3qAZsTCCe{Rj$5x{2wd@lLU z0CtJc1Fxue2k-@ZgkOG;a9_ZA4dyH19^qc$*FxSV><{1@X*Ox@I}pG@aqcp4Ta^xZ z9FpYbAifLWZ~)&2a3p|AL0lfh56bcdQ6z|?0sI)iPXQbY;P(Lj2;jJKPX_Qy06zzC zLP@qcXBP2SC4UpT^>usv&j3zIcs793BL8TR|E2l$_XYEgv7ONn`d9d0;N0Gh>kUB^ z4Wf7uC3GUbD2QS~TpR>fDz{!#3+P&|WDuo-C@;0r!m`3LLMl`9k|4?jVd#z^_m1P? z(jY2Gp`!4zAUO76$7xkl{BGer zLDUN3-XQJ^;=$m#b@+af2ZGLd(_IEhYD?%Q>jd#|5RU}$Xb@dI&yR8EKZyED))m?% zd=0$ZHX;p!Xyi#6i!=%1agnB;yqQSzAX)^`QoL0V?%gHp(pnPtwxVs&*`H}ANqb?3 zAUcY45_T5S>WLuSJzMgw60$~51<^f-fgubE;prfH1Topd6bn6r=oQ58bRIKc zAc%Kl)i;R2T+GG$1@Vl?v%>zu0YaAYoX9}oAmRR@PKUlAKA-UfF(inWf*8tjgP0=u zupq{Y3>Q*=gvdzYDBC6_H6GW=TxpDq_5N~+7^F)~SrpQ~ux4m30kM9PtFo+;0Q4ouQ zcrS>LmHWQ%L*WO)#X`ovL}aOOnQ*z#?fn(vD}z`iLj8|KRtwh%*9tjk*NLnbZU|yy z5Szre2xjiRSaBV;7aLl@95js(b;w34I|B657!vD)<87_*BiJ_YLr(s&aHJkPw}$(1_Q5c zc1*UEbFQ&@6@9aTTMXQ9-~j`-8o15Cod#;ioE=?V|J@VO!(9gMF;L4u zO#^ouFdF&3=UYSG4&l89?vw50x;{P!9H1+W2MyFV(8xez0}mOfW8g6Zb*1*OfkzBH zYJlfZe%RUFh+_b}IIL%&zJUe?8XDlIu(`3|*4q8bmfK2A3_Nb2nSthpa~Iasz@U=O zwI8o(YiO7S)JiQ39B=NsvZ1fFfi?!7G4QN`wg%c6=x*R?1MLlTFz|$dE(SUp=%m;> z3wfc)OGH+j2P@mvKsN(V8hDD0Ho@s5UM%tYhq>Hm;FbbO4+A|7^p!c2y$tj=(1&9N z&LbptI_ExjIat|#ER;|EbmQ6IzyJdi3`{ieoPmJ`h8TE>H8L=m#d*6T&l`Bbz>9Lu z(>kC2Z`E&zc-b@5z%T=&4UAFla04R@jAUy!^VQ|H4;zZ#`QeAbD>_N?u?EH&7;iY| z>$atx?*x|XT!b^lZU0FIUN$h@RLXs}y&DG5M;J?mfax1G5b5 zHSjeDo`Km0J~iMsFvq}L10NVzEale?ylLPq18*of&%k^U_ws;|ylr5CfrSPZN&b$3 zcSYE$Zjh|?d+bnN_Iq;94tJ<5F|gFYY6EKwEHkj&z$#DYLjx-etW@%RS@cQ%k%Vjz zmcG`&#|AbU*koXxf%VGTpuSk559HFsolTz@*lb{nfvuWo?yZgM&~-%~Fc375H&Bot z!$90X!hmVOaw9PiHW1N}poge|qi4^?)YMFp^I$tC4cG>9GD#Uo8^{>QvKe(1+H{g{ z0zXamgl`33ZQ_V!M{D$MGqByjP6NASxWmBbBAln6aU$!7$^G?=c(>$V82FM6TgA6m z1CK59m4Q7PD(72xpMm`bP8m3D;2Q%64E$u^n1O@zVBoNU?+tt_Z-)$gC&FH1QxMs4 z^mD|(53HtvAK4E3eC11km#kE9n~q&Ta@@er27WQ{tAP`8Lg7ixcPcQjgB^Xp8Tj46 z9|rz3P?=-3#JMN(?o#O%_m_dcxt<&FnfS-R83X?s_>ZGeYiVz_9iM|6>D~ujZ{h|Mx0<-k#Em9yGI5Ivq7@%S@j2AZ zG-P|~;LTcf6SteV!_(oi`2=@ksyeUra&f!ML`@UTOf)xfw~2d9JZ7S~fu?dh%|)a-1ctBG#x3lm+Gd;SFUq=~0YboczYRs%~p7k;d7 zPZPaNj4?6RL~j#)O!PM~z(il^KP&9V9u#p042$Ez+r8&Z3^Xy!^E`-cW#R=T2MgJ% zFPa!);w2M9IikD=g8Wwtz5~qvzn~wU>xXlwm>6kdl!?(Y+{2Gs>V@R+~Kj*#4;&=WMa9A4^6Bvv66$lP7!yh znONVqN(y7&_i;0}2j^FP-)a+UBy=wu*xKt%tT$npFimVQu~E63O>9yCpD4Mzf{!1Q zap&C@6I)GuYQoRDmDM*Ylw-kiHM1)iI|DFvUq{P zy%+ZygY%lUT&!#pDH8=Lq)lW@WKHChyl}?3V=}LWf)jb0iS6uPz8;_$=;w12JK1O^ zzBjSU#BO=`O8A9|FGbkS>}6idv61(f*lXfz6Z@ED;#(8@O?+eGpfnHG^L@l8pRW{A%J46MxG5H+97C;v6kpCD;+COq@3Hmx;e6cUzL*`(+E%ZsS}f z7HR4`qpW|0{|OiHjr4lHA{JobatoDt{cqtS3l%MA!7pavVhiOgl($gaLJ13{EtIiP zQn{ssRGTo{x3hxpx~GaTn6eUHVmap#9xRs^wA_We)ItSMpEItqp88#8p_27~`wX0D zRityRh3hO_;ptx~a+QUvMXnLLZB^AmH4B|AbhdE4g&Qn9Y~c|LH(I#KLQM;ITe#W6 zEf#LKaEFCkE!-ya>caEwe7@!Hv{1vsUDp4dIP`Wb!`g|u}NF_xR}(joUK~Uacpk6UPJp{|8`a@g2HeG3gN zG_=sj0tf$w+C`2&RD|P!L3V8GJg;F>H<2>0U_aq!U@bJa(8@w<30nwTTIWWQdp*;} zLR$;%Ep$*WukhPh;CNsd92o2c_D)9&yd2^X^;2k}i-o}!p107|LN^ONxV zp}RP1#5(d|NKdPdB)u&3w(u;yS?FV-uZ4aVo>5D>S1)cA+}i<0GQh%f76!>-@e)4H z(82Y511)^4*mw&=pFCc$FxSPv1lflPtU}g#$gE69LS;@a6&~)c?f7W(z3`Y2|LQU{S%sRtuk6@Jkr9 zU|0xvUC&OWt?Bt;lBH7;wh)s(c|`3Ql@4>`48uZFxwg*+w{Vh(Df4maO>F_@bXSv{qP&5Red{SN{^nWWJ zlRPd`RxwXb3EdVCp+pEJLnswOxe&^SP&$M%A(Rc_66w1EyB^N-OGBvO<+?&5k4hn2 z9zvZE9uA>$2vtJ3J%l?#xFUorL%1P?8$-A%gsVfiHiYXgh~yfNR}DE6r&qGmPI;-oT<)*-a<9JEj0oXH@gX6+Br-IFVInkPU_4m#$Ph+JxIKi?A&e2<8p7BR z#)a@+2=9k5Uc#wd(nFXaPTPqgOcH-tI9WJF=$;Fx^NN!5g|CJ%J%kw{%v5rYkUFzO zUJGHi2v0N=@|dgS>mj@$GEaE7o=3bXPMxy`xYCoa65-7?bykb75v~;uREg`v*N3n{WTSAC@Dm|z zH;Zf$a)q{AUpc{;AA0$ZCo+V-%5n=nKVBSVP^=t#HqPEgfBGe$iI~E zJ0bmiC9+4jH-xV}`MwbLi+>|LAUsIq`Y%_9Bw-(MD!H@iuq59L>G_Dr47?9p~{Q@8p3ZO{4RYK^oPiwA)FF99YV1%E)L_b z5dIF~pAgQ302%%(1$sLh!hhndIFml*k`xI$X8{r(MZ>sAa#vDZyp*tnu;c}~rNwDg zCXBKkza)%u7wB9XMujjcdbxCaSs0bVxLlH3!?-Ps%HmbRxFU=z!?-Gps$owIbYA=2ehe1&+PzC1eaYhH-<(S;|cwzd4LsJWj*v;x&Y~hjB;v+&c;MaAz32 zz~(`IR~R+JxLa!X2=5Q0Rv7n&ai5aZ;S6q@#EzA#*!>SzScBdh%`}PqKm{-97o!Vf65LPZ7H99Y!DVzQSR` zeqlT#!cv|U=`S1*#&cl|3}cX&`$8ClJ^s81gMTrMA>uEEG1SX-E9K(wFh+ziQdy(I zm?$z@I7T>DI8MkI#*0i4x*jHpzbu>_#uSmMLh4TwVeO`eF@rpgZ{wI5#;hp6 zuSwyd2n_;{a#@pi5SuC<3jCaC# zSA1a@?}hQc_#z=kwflJb10~(Dw?uqt7|TSK3s(w16s`!Ld#`Vmk}T^ZPqLPS-<$jE z!dM^1(J+1tV?!7l!^nk^4`Y*OWpj3fv02G2VVGf9;#gqoR(T9jI0RdoP&ihwuSL^ z82cpL9>z{DcSjhXdHi#cCx-ZTiR>1B5yqDyUxl$pgcF%Na(l(yHE@3z--PjP7>6W0 z5XM0fo|qWG|HK?l&mRaZgr8{Be+B4PETG#qpQaf<6)Sji6x!jUs3h zLE8u#N6;jK$5|;_)%EddFOT`-oaYG5WY{VK^5zkIfA(yP2wF<$)Ju=5TPw-E-*yqS zkDyxwPe#xof{qb%QC6o2I!Bzd!xJo>p)PW^9O-bQ_J_Mhz>Q))H6v2z1Kt8e&^>~u zDUTq>9oh(bN~agwc9?IKG^tMy&v$g5nD>i-0Y4wX3lTgM!Lt$ck6-{t3%}Z-n4eP^ z1I68#SgJ}Xpe`xWy z!gqxWBUmJIel2~UBQ1i(5-y22JFax-UbHNa;6uqj7OoJk7OoVoir^y=n(*Bi;u3D1xxEwnPy0bhe6o8iC)F1UPi%+>pfdwLD zbGSxvTNGbJ@TKH8MV)i>SK^hU*dwx6cr$l_MD}TY+aJL<5gdr%Acc}}srfd7LlO9* zC=$hY5gd--w+MdcsE*)B1jiycF3le_x_%TtDrBX85@G4&KSyvPf?p!|HG-3pvvm6B zLBfMN?#lK@1b;^GUj%0(I2FO^2>y=XAH_+Xzr4s@QUSt#Vb*~8pRz^+!;mNDB49)Lpt|Hai7RtQPdQJKmhk*c zykE(N!Uv*wP^7l-p(yG^@vyjC_eaDZjpDH=>WbGF*1JH5b!^}z8;LZIqDd5wi!-;i zNYf~qi8L3s5Vnk>m0Fc*JlsOtc#`%}bdcJ}C^|;bN&H!1XJOAMo`|AL6kU~kTG&na zq>w(JilV!?>%51@-DEE%dq>enq_2=x{Y0J-x|;pP2So8)6a%9eB~Fjx%_!bd)(qiH;Vj{6QOp*ZBb+Ow=hvfnLwufaz9&Dxubo7(Ad0)=xF?Qx zqIfroQ8A2;VPO=DIND>lE{6A_ct46GQT!0a2T?5M+7-o@Q7nmKX%xXIj3|~xu{??m zQEb!{`!I@CQG67|iYQh}!uVMWPOH^QeykYQM6p)HtsryPDY;%q6CM<9l1U(nPomfy z#g-_xM)7GBezgo0Tum3>7f&RLXcVz1;!)UMZX$}L$6Y5h z;gQn7aCtV09Z`H1MNXReC<-FmqS!7%Lu$JCc@#UN*cHX@3!-Ig>=!DyMSR6&UxtUI zvzOIZk~&{Uu`i1KQG64{fhZ12e!h<93;I?q<`(*$bPfwC`Q9t{XcRw2aW)EH3_mIN zWE8)M9E;+($j`zPLfW1$=+`KIi{f|5&qVQW6n{kVr;?|l_$!LPqd5KlTm7S?>w);6 zmvo0ZofnA#F;tA35D-T%dfFvaa?tuMuGwRb!|YL%SH- z$8dcNH^lHj3=hU|V+=RNaCZ#%P}8%zErweZ(yg9^VN@5tJ%&4CxHE9K$1?rt7V)LTVL5y%_4p z&>)6}F+3ha(-<1X&{)b%q~kW4YsILV#n3#47BRF`DU`S!N;T>bd9;>!8?Qt+i<%u` z=orIuF$|2MQw*JBcvd=3#Lz{gr?6`bJygMNF+3T=Q!#Xp;c3sCTgv%(=$xK=DYthF zePZY<-Y%q)St$#9?0b zhbwD@aHJ<36T{dTK8xY=7{L0rlVma_hN&^UEIwJtBG{zU zVt6Hnw>*ch#xPsC(_@$s!^{|F#qgS!>sF0XxnxcZb7OcthBsn(Q&#gl&G{a2OQ8u{ zlK6HE3u1UDhIge;$wDs}*X{c;d=SIR7*@rwIEE$4{ZJ!hsc@MZ&Gok2D}}Zzr0L2( zieaskDPJx58n3A-`8bAkF|3bagR&^uc;0rR6XfO?w!{#NAs)ll7(P{QKo0%ltQ6IV z!5EAf%owZ~!cqu%u9#bFg!3IF9+4QL7aGQpj3FIECI(woa2=*x4|1N3A?KOoCEuYW zyQ~nyHu3GMlshlncy`9Hiwj*GmEzbP!xu3eh~Z!iU&ioN40~k7CSq}JL+zD^uO;6n z+#ka?7pT$g|6=$yhO;sF;y4t;cQO1atHUvTAH%U2j>m8$h99`vE6$@br{RwxZqwjKC>6&gag>XrbR1>kC@U)}xQDAuEFZ_E zaa2$)ou8MJoKIdJN98zfh~vgMs>E?c9M{HiolLHbL4Nd9|XtM(CPX^*mFp zn)vmegpu4tu4IikZc#;UjpH^++yJV})tzzN9>*P$yYbUG3GproNosmlwPf;09FN9v zulRk!`-N<@2jY0ps2j(yIEG7JFOK$cbcmyV91Y@VsNx=v zqiGzCycinC(IoDiP|k+&Zbe@W%dmLTj=qhj2?-s|C%3`y)0X(f_pE&x)(IbwYarE;1_x7x)$(r_4 z49~>ztS5KlcUzeJIT=1L94H(V$6(JJ)n16>MJ0#CF;w1Y_0s=e(-CoujAK$tB`T<5(8Qa#fa%zaowgJx;@wsvYIztK(S1WE{yj*2eL19ELos z^L%cMV|^SOE@)?3(RNcDpTw~_jxC<1KaQ<&eER=u2I2@xfw8$Iveu>~7V8y9IF3jh z(Kupp#J!qQhx!+y9Y-pTujAM!+jJbC#qoI@nK-hNUEcN||x@?{)*M5yys9FNR)hWcL535EN`4+y^zx}I6PgI?Va#qnJn`xE#k zfx~L~|Kd0+@_igf;`kwsqe`9;{uswkaU7F3`uRPMXEL zA94IC$tmG!A+7!r`8$q(JPBV5WIOz;B!l-QP$YqC6Syt`Bv3Sgs}frI6DXEIX>s~- z`~Bhsic3<$la~}Jm2keHG+>a^%ViSI`J!wBmv}nm5-9KSOGPROD+(_YRuW#GK;;Cg zBydH-`Cq3iC3JtSx;}wd5_mP?oXBpF@Wupga&r^7 zC4pNLxGjOF6X=mZb;%z~pl$-Ui{FvJoe9)P;I0H7l!Rr~OyEB8yA!x4fm#XY75#g? zTy9#r@88~^zylJxKa=5GwY3v?D1ka`TfStgtcS(vlW!M4Dhadr>O#E)>MQwV0u2&q zm_WM(+9%K`fyN0mPoPBtO%l#m*?BZg;BoPm&3#NZli{S-oW|$TGJ)0!v`L`V1v+kS zTWRvmQf`P*vqJ*iBnlR{$f##|mjRQe;#DqZ1e-e!k-45*VMrgoN|I2F{VdMDa<&Wfgs{ ze6o^Lgj0pngznE#rzfynZf6K*CNL|3*Tm;1@MZ$D6PTmq+{FJqO?X|BH-z&vQ{2{j zOOp2!cw1zF@SOzS6Rr zC}LbNqAXTi!f*m{k%*9fqEd@_ktaNPG6DMn4{6CWUT!vloOoVXNMM`DcFr0-eW2$Z zk`!&?`#gc2;=6=ylkQI7GQO#vz?TVpmB5|^_9pOk0{ar^*T>h21Fw&-Zy(=be)M~Z z&y^fV;2`H(5^a+BUjpAI@J9lF%I6{B&kFcE@xuvxFLFe}AB0DRKMFa&eoEk&_;F9d z{yiZp#(y$_U&Md)B)^ILuD+ncDJB0&;7kIi#s3oiE#yytsl(%6C2vYPWAeWQ&L-eX zqDazNFiR$#j{{H#Nfc$Jc>OOdCcIc!T*#~vB6LzJiPA}wNuq2LRg$gY)J<1O|=#z|BCb8x0 z*{hPcI*CF2jgJmKe`Ju?BynvL*Cm}VQdUi(S`ybQ9y+O4*LOn_H_9ii*sVP1^JXdB zBD__|0B%d7y7=u$+>ykcNz_Q9aS~0ExGRa8Nj%JtHZ$@h?n&alB<`1Ttt9Rh;ZNk) z0(?M8R}UodU=p>Hct}~CAeGyk`(Y7vs8A<~Z}mqEk4m9_5)G1gEQz{G)=N51#OQDV z7eMtwL&+Nn`RyZmaQ!@#z!R}MCtFU_#-9(-gJ|#TA7CoIr4@r7nAn%<-pQLjo&^L)^ zl6Y2G{Vq`GpTuA#S>gbZ=Y#{<*COmnX7PAFi5Db!QAo)U5w^y#B!(w(O%B)QFd~VO zNi4|VoeV}LF`BhVqe~iNk{FxBtQ1~LVO$d9lXxkGp(#vAVqy}(B#a~`$)P`qKoTz} zF*%7Tl6)YXn#44bSA_GEcvXavOiyBl$7hPnO5(L7W+yR6E&RHdJ6Em2S;pgyB<4v@ z&RV=F{+94^snPv0HMp$lS&BoR#_mPDLO6DPintu~TL*qnMcYS~C7kxt@b8^vv8lE@}; zD2eZq$R&}N+XG1ylGv8S7fF06$@V06B=K3&d8W*GK2Kt261$SvorL=n*XsOek0vh_ z_*)XbV)RuKdy?3%zT3s$Y$ow_68pRwu`X;D_o?4E5;Dn?;6ZW@ay90+l2envV?CV2 z_euPf#NSCAN#chjeoNx_B#tKWV-m-c_?au1r+9bM9 zb{1rQ!HfuTR-gPL8^x4#YhA)dNgEYxRJ2h_a_W?^QQG4SwXFChHpt$xXQ-WHWC^_ynb7lcUqesIDW3PQPswc zHg2*}&BpaMZtzN()WTT?sm7y(`j=6W-)uYAE&O%itu}76QQgMvHfq?oONMuFXjSpu zDLzOKAov1jP0#1u9CbW<-t25w()qnM?z1t&#!MUc+jzi6R~y}IJZPh~jpjC5*my{` zkJxzBMjg-3!)g--^O%jgHX7P!q^RoIsBfczjjz=ORM5? z7{jry&WPoxXeRUSe8)-kZE2&8jkYSTm5qITQY_Ax+lh3t(b-0O8y#%tMy8|foccMg zIPeyc*l1#l8u*b zOtbNdjme(=R2x&oIT74Z$HBuNhQDfKx~Ib`xc_-H%f@RqK9YR4jX5@!h|gtr+jz&u zyEfjiG0(QL_|!_%Az-Mj*YPGywAy|p!2AN zF&lBtdhw(UTV(3TK30|;!8&GaWNjR^@uQ8LjXcM>jr}$XHny>jHg?+B&dI2nekSuB zil6Q2E(QGA<1QOt*!YsA+s;q0nYDbV?<*U7Z0zMUv~j4C6A}-%;?D5X*UY}LalpoR zHV(`4L86Usy>@fo_oLMzuf^){$*(kjuyMq8zGJ{I4DiOEk?<=7KiN2D<1ZV3+c++@ z-)#JD<7XQuY@C$j7aPCIKkLpodAL#ipqJ^iyH{|VXhz7&e2&b>dzFCDR_7o|`vg%T;}q`>3i6pD+V{|*u(p}b_u8NDQB zQYf23+Z5WRa7hZ~Qn)9DS}BxI;nEbYPvM3XDx^>`g(@jrk-}x3=gU*5B+i-T&a%pi zg#NEg;i?p_P2oBzT&=RMNu3*qZn-SFY6{g-&QeD13VXNk-I&5nvbrmUn^U+Yh1*i7 zE{S`ZzBL8+7pAwTa7PMvrcgtkSuW>V`8K}DY#-kcc6+m?4D0bmAO(&?7Ibe4_et0^ zh5J)@fU%`eFNFtFsGY*2%6ce;Iw?Gy!Xqgx)%Ql|khW~_CEiC29+M^qHW%UgDKt>B zaS9DZ8VPB_5y(#A(Ikb(Q_gpa=8Sh<+@-u(3eBa~Lf9$=UX8R&Irn!QC#_RxlX6y3 zwv0P$+NaPVg+3|tl}^VLy2!9o3Y|rsNWuNKkGtE`HHB^|Jek5%DfCF8XA0e=#?qfo zoqJo){qkWi$$JagjP3|wg#A)@CWYrct7lVqE`@ zg2;<0=SLYs#QAQv+vCGhm?#P387?wHI5LG%BBO<4gky!&9GAj)@d-kA@u7T@k}nG< zr!Ylis*t(UQh3GVuZm0;&PZXV$YCvFvs0LpLhH0McjmH*Qb?tcmckn;7%7-3%u8W@ z3U8+H7AvK!w}tPg@PWvJ6y6beSGZ6}hl^5pPu%UD#o{Z3OFW&WDJ=8&a*+>H=XUB= zrm#wqkAxqmuv%n|aIKr=?dh#cVSNf4xHyz?#_dMsl57%jxBfPZZ%JXR$fur;UnG!1 z(34Q#(i96xGF2A|^cGGbB1x1}m0tl8#)V8KQb>y1p2S^^Gcx&Hm`x$4+`OlA)S;b_X)h*-@3|K&P! z+_ztb-=uJWbB#QO!zp~9!nY|LO5r=@vR=G_br0@@kZ`Ah!XwJ%4hAJZrtnh=XFdI6 zDg2VcuSy;l{+z;z6i%}Jbuau=YsbTH%KDR&I)&fG{}9eq?rHIVQaF>sUn%^pBqs|E z>x}pPt0ehziJwnr%^eLDrsDi#xO#sg_Qm`3e1 z9+TuD;Uj71%MW$Zcvwldtz7d*B_XeyM!huZt2%D*Zf`bBqmgtPr=6WHmdoSQ$9<1W zNZvG!X5!6-Ej)S4G+K$flZBdXlx&+uJ5Q&*NQX2!dXi2eorQdU(KU^33@MF2(|9tC zrzHO2oLO-f8qnW7OHReTDsm&j=}eHjVz`sd_#p zY5Sa<@U%rfIE@$5crlIVFAxq9pDKJwI8-=HNUPx@BhnZtGAfPH-2X{C|6s*qVj5$` z#|g&^CkXiwEmvofk}nG<3#SPAk51F%^OZDSWrwCQBaOLfyq?C)G-jpIg8#=VWcQI1 zubqe4Y0UBZl)^XCm?tM6q%mJ)flS^Mz9mhL=eO0@B=4m0ZW;@vxk%`)8^rgd{J!P| zE6%a8IE^J~EKOrs8q3*Vyuwf8Ls?N_MH-BUgvUx*(d7JyTAjw4G}fl^vGlj5@o5_C z#McWqcz!mDY!ZHw#%7T%Licn)|Nb<7ktC2tFbyLOlgTu`O~Xn%D?E=cMM7zW(}<)I zO(T{@A&qTm#M4NmkxC;?;`1fbu<4|wvuN{6NAyq3q>)V{mquO%QH`6Nyi_}~(z!;W z4u?I}wx{t~8lR`JLuy>Rn7cELU1@xw09W{%ERY3$+pFP(4FIFQEI zUgZ1I*za+c!hb@c`9VosPM?R;IHD5Czf0pVE6!U0Pcm+_?}s#wD*0m?$36K^BFBWh zcKX?qpAb2zBHY^jn#OMu{_ZKWpi^m_W-n)OT?T)p@i&+849aAjPX8y3|D<^)jekY> z&vCA+vuXIGQzV08A`li8()J<|e(&XCk>bJsmt>s2 zE+;H6Wb#sx3Q}{Irb=>hO~(0&(B&Ca_Iy?mxk7lQ@G9Ze8En;-4vXW*rK@I8ErYho zx;}#&L>dTh%%G;oO+xD5EOLwR)(mbFsV=-dgF7;~Q~WMr4IzW%ZoJ!8cS~}QuvP~5 zW^i8y_bd5m1`mkT7P71dMQHetNFCwBUhX5AbBp9-lGGK}6V?~Hjnh!Pk+89lo|}j~ zE^L}XvkaPN(89}YEz(lhDuYV8J8R?Rx)-|bGH5SJ2VutyI%Uu~gC{bW=xKHl=_Bl# zK{t^ng-;2)XYh0eJu=RnS1(C=in9nxdQ0No0`$$GpOVjHFern;;?D~E3kPKIoX9|V zU>)h?c}a$5FihkH;fomz(cq!ZOKL+7D)QkOjFG|!b~?9%grkI`g2*e8;25pEW`@~z^mR3L+( z_`VDb5!$9RFf*`RoeWZ*Je)zqYo%xgG4Z%3No0`pxUERoV(#q7WRR7Uobc-m@);Dw zw`H)?^S?cV9paw}KNs>P4TiK!o_7ns@JjhoiTO2zh&@m2LG{xiuiudIKSEaL(1+C`Txw|R0gLd`AhhZ@Nc18;!2hfmXb+HPocC3)p(^;Hj7J?ESE*aEH2BU zypop+E4W$u56w#AR|+rBqH@;x#xj3WNC6Kc)Vj4 zoy0o}pAfPxRAZ$WPdC|;KbhsfA)|X1PiN61i%b^TEP7_qD~tECct4BYS@g+bY8KP7 z=$l2qEQV$=EQ@F4p??+wM4lDW^K)4YRBW?i%HlO8=cphm%$8?H$U^5Ti?>vizmdhfEarQDW^U%+zB{vhQo=+(~1!py>= zi6m}cxGf*aBAP`^CW$PPB5^sVf~{m)m~wSAGTpY#Ws%R~mn?qGqL9V5EcR#dO%~gw zxigDhB0IA9%&W`ilF*!??w0V&EWY3nRh23KDvLeR*_*{ak*|ero49x&i-TO%J^BAc zzEf*|D?Ft5seD*j-wWMZ6Mx9!Xcj+8_)``qqQYU9Zpq;u&-1M!x8+b>61hL;oB|$T ziM;q1lGGNVex0227jF+s^N}1L&7mwG0q2~*7%NrJ$A>|FJNJPA3d4FQ#t3q8fns&R}Q_U(8qJg0Q!kPlf$#B7Y$hikLPk2n8UCfhD%|Pa-Wx< z!8!1rnmRA!@L~=_a(F4{e3^NuG)Y_!?*F%r$YEp-V{;g%+)?sVo}W?5VNA~XA_ot~ z$wG%;=HxIphv_-Y$YHixhH5iq zGAjr76W_00;Em3Cu!UdG;msW0;t0=So)lO$+Rj%Sk}%1G%5QU2cpg~6g*hzBVQmf{ z=kQ(*@8_^YgNj+~jt^8#nlF|Kg-eyYEQjSee3-)u$yevFGKW>-A9*FxifuyVTwbFr z_xUEHU6;eA96ph&^*Lzp=*+gGE%RuVM{7^sHjg&q?#oy0#LxFp2PHcS zI|(}rpU9(&$jyV#mGz{Oz4CZUq`UBGVGm(X;rV^w-b(h#qi^2%40}H%pAkMQWc=Lc zc`lEEc`VCgc^-rE7@WtnJYLD;`8;08W1=))%wtF%qs3qHY)8=W?Af784$EV>Cts`w zVI!3sC1fdMyxg&Qj1wQ9#{?0#DYynsQu1ZtWZ@Jc!3E$0QMjkWs zn48DzlFZ6uj>v1C)$F`;wxSgeHa??$BagSd+=mh>cP5j&5Rh})`}JhDpW^4ONg_B`@R7KAL3ed^AX9eI3~ z$LF4Wr-<7`EQOl8^Y}u-FNI&_u_uqcd3>G6p*+6JV_)7mkMLcu2IYMF^Y|u@18RBN z{x6S%%5`0R%h4{M?2g0o_M?!R-{)~e{0HGtSy4{?pYk}y?#SckJbumNw>(aGxxYyH zr014rSVqF*_dNd0$tkQNa)t0p;Z?$`3%EvvI@gL^CuB9NiCka64F%j-z)c0* zQ$Q`cmFGKzjQZ zpthI$kXo2d&U=2ifJc=3sHgK-0d>V)odyLoEZ|fDrweFQK;r_QDxkZn)}(+o1+*>T zaV47yY1OQN=He}cEepk{(a>o))HY#_M(9PXkz?K5G7Vs(8gq)+v zQi!}g=UW*;g>-^D{{U&5JX*ky;y($Gd2;vf$#^G4os$Lp%2ra=FGBasMYKxz zerM4V{^{9r(Ee4x-vyM~j?&xlkK{wP;iYXjQ^3Dm{|h)<0Jfp%Hu$!kTl0%-`@bD* zdcMe$zqk#>#4p~4;@ePS8%l1&W!v!ox_S?=CyMWTd~-zUysyAZlMd1Zq$9m3AflqE zh@vP`1VKPRML-n0B8a^!_JRd_#YU5sw%JWKWs?YqVgUhBZ2ZrhxPCvsf1Z8LbLP&S zJMGTw>}*Lz7}dh&rtQ3Wq3U7tZdbc=EFLw&s2N5rNy@@FR)jj`0jVugM_5W#FO2$O zj1S|YFdBr>FpR-r3<;xA7{@V-Fis4kaTra)I6jOvVKfb+Sr{z?3(do55g2Cym>12q z3Zr!x43d{}X)B%fVRR5_7sQ^RV8<{zmE?hiQmQT#hS4jG-iqxOMvtJ@-2?re0b!Dp z!sru5|1btf*f)%RA|-33vJDI*gV-taLOfVbw&YM*K0S;x!Z2lCXwrfOTxH82PRn$u1gTi~mxG#+R!+1bJ-VvZ#CgkyuBn&oPM6Jb0VNVvj$ zT6~qT^ibJzVLTtk&tdEh24L!hwz} z;)KmVhcXFYx=FHZdd{CgFN|~;nJ}^?{UB8?3|~AiECh1Sz2AhfBaEG4?2_;Y;kR_r zKxemzHQf3>j6KXNc%h75{bQi>lL#gIME(lozl5=0{6HW%7{;&Shr;+xnL|^(hz;+RIkDx~c?IY+Q zg%ct;QH1t8M$jpO&XNCn-jWHs1hHKs<_pQ)6yy~ypR4CPQ#}>z6#eh0~-nUA$DUD*KIdn7exe?5ZV7`jVVw4Ul@VF*0c&*3+>0c*YC|o35ETsMoQd<$hJrUd(!BPe3 zqBliwa|E|UaBBp2NB(^y{}NDx||53R*5_# zd{!Az$m4lQUWnjDk&+#j@MV>XH!N01@EZL;jV@`t9>E*T!p2iJ-i%;P#B6#zY~!s6 z-sX6W;kcODZh9wz;Zcl;8vbqs??v!_1Rq53A!{8)D2k6F_&9>?5rjF+`JA3`eFUG1 ztQCGH{9H(#FCzFd;9rTX6JAhm{s?A61RE9H6zF^{vN?h+B3lFbHWs^sNfL=58o_rF zd>=t9g18ilLOX(Vpq~(NB5(sqQY0nxgrzcM#Iq6PM3{vyl8>MeNP3o;tiMrkhj6EG zm+)KR?g)OVX4H7>iQsn$e-Qo{!A}wVEPg;poxKt46aPiHKaej`%N(Rz29iS}zeVsu zYh(Ygf`0_De@5_^_}{{Rghzyb*7~dQ=pZqBvT-rjQ1Y5vd$Sl|WK8ifZE3 z14)hOzwKWukd#GH9`IvDY76T`QCEb^7#gn^Mg1rmNYXrt7Ev@5ZzMcU*jPyACQ&pM zZzha2`?vfpqZlAbD`D#>ju&YYMVBbLM$tBkc9OJ@;)EzVM$tjRl7;VESe>Hi9L0%I zl$w`$QAj+m-0BuZcPdN2hmi7KB0Ytzs$0E9sLZH7QS^7^G00R{qBpfUp zA{-jU$x)mVHBK^2l9DwVq~z2nMn#q%c8hEifK$+ZcS3*Ki6M)PmW@W zYB5z<>g(xIToJ{G{0>rcYlaFrH;Q>t%oJytuVf*`X9towQCt=9nr*E4QCuCx<54^j z#Whh}8^vu=+%AO$Q7n$)dhzR`W&&R*TtwgIE;R4|D!7#H&A%=czfrimw$-!Tx=H-z zC~k>@%J=m&Nt2nbh~l0o)-Ser ztdu4RE%YciHv)KcFSn}m;ZK&9C(|e%Qoc<1aA1M_(I_4Zd)FJ!TKFyV^|PUjX)6faBd72&Hm|!j5<2d3a3_Fxx0TO<|o)!5>__6R4A$2|#IVWPA>a!?5msgN~5yh7Q z|4L*XJyYYFj<+!i&QW}Gc{E?$;?7SLTcS9~5=OB#ifvK2Q6!_-9z{5cNEFd1zO82c z*3DWLw;Jvv76`6KBPrlRnoNJo)jWAZFnC&WS5{7=(y zf3~o)QRJ9}Cpd2Av+x>F`6voe6r=biDF3b~c8Ko`B>OetbADiw-BElO#rIL{kp)Wj zM)8CAkAdVTk)MSv>stE)`7a{-qc|Y)XDegyP!zw>nPWI6hTo$&%(jZ+FBY|xRjgzE zK?hrH`sisc`=fY{SArGRw$0W*D%%ltJ!@yh%v=$Q0U}2UD+zhmgHe@Zs1ie+80yCO zoUO4;dDR#m;Qikis>e`6$_F@C@I`_A#`M;rJNZ#LzZ|C1uvw>ee#8^;T|e_}Svw{EIf${cndl#Bf3ky<+Gc z!`7}=#~7Y&W1U)ICb~{BbdKRf6}3wYJ!59lV_~{V(k+JWlJpRA5@T!$Pl_4eSkugE zsM)no3=_+(zN||O{bTU>giN_LAcleBgJL*^1<*f44`%JehYC*)!(td7!w4lQ z@|~|3PK}w1YhKxL-abuoUfPU`;dJpc0!`|i6~oyv%#7j67{X~~z|E((+oT{kHh0}zzIbGz6m>Jy+GIzG*tQfj%vS!CHCkDTI=(vd0 zPRpvRVwf8P_m=0yaGg5h4&MKbfq1p>ni#H)VL=Rs*IN{pupa0C7#78_IEL$EVDM() z5+Q>(h}p8|4EL$EALLW<9E0_&UDeENb3X?T-H%(=d}*C$0qVr?a14*c@F@L|b0fQ; zk@Z*%Zz}kB3{S-Hr1*0&JRieT;!g`#37-)@D`Z+4c_C&_f3HgNB1^@|U-+`{72z`r zjeNCqUK749d_!2WvnGbOVt8AU57qMTh`%d*Px!v@17RuEN7DRQ_=)gS;aXwoY{+@w z^BBI6idJC5CtmHb*W8JDV|v!cyyPeISul-X23( z)*?bmq9QTs*R;6#pNPSUf#3fbTF*?ORoKyd5J=sc6sClpFfGgov%;Lv7v|afd<9I% zhoE-Eurr3naWsizR}A0A&?t`M;^6dyh@22d=ODJD zNGBoJhbM}334%1(EpGg+FV}Bz^oXNp9OS)(eT2Q^I7#HIlPpH{jiX;2{o@!A$3V#` zY-5FD%|d)v;`Z91-A9F3?7yp7KX0%iJ*<=CI3TK?V?-RM#&LEW zW8xSY$7yklisSS+E=*aRT{|DKrtmZ!$K{$TZ%tTrc>gz!(Q&gdJ4;xJbKPd^oH)*n zVSS#W6|bV&McKl`o0o(tuBl zn^nYRaqz6osL7I-_*C)Bh0_B4>C9AohLCAz25DI;UU{)Py?CaJV=lWOj%VZerp%fb z$NV_1X1?;eYq%t+u&#|`0X>$Jv+h4$7dKA_-5JNiI2OghyO4|HSfb*QUoY}m)ev*M zA&wgrTq?Xtcyk=L#BpmJx6z*^q2?&tx?P-Wo>Gu_R~*aYW}3Y_j{DIv-i%{S z9Pb61Z^iMh_}g*36UT{VX3#P1p>7sANeQ`%X1{a)ffL=waeNZToi^^W@o5}umXlv`Y z#Jl#CY>tDtMYuJNZE6{!*aqQ$2VdHokyW;pZjz8k~Gj6UpcE|Bk96!hLor08nAIBbc zbfeH9?j>@3@%=BhZAY_0*eji1;@Dj`v`@Sw-yg?;I1aMM`AY9c{2k zehH!@(cDH0$xEgf+fu1o$r^*DViVigXlvsl+q7gm8|`iMW|3_3 z`QHvUI@;(Yeu9lUjY1T5mW6IMy4yI>Mi(V4wQ$$};XQ2A+C7D|+{^yIzUX74uZ__* z&a%W_Yz$XB46rfC#$X$~BphhthYC~29x-c(jiFMYH#{sl9i{}j1Rc)N`|L|$rRF>0BOyKUTO<9-{no|aAcdw1Iu*KYW$lwDu9<I?|CNkEy#KXA6k1>uXkop0=^d#wSU9n#40Uo>h-Oo5XWAp0}|qfx8oU!N!X= z{^F3g@sf>~ZG30rdmFFVc-2P4M%2b?8?V`T$Hu!hUS~(Mv*>snBYad(`x|RmL7ng3 zQWkFu=~vvGSzl(o$BJ*aK9lf$HOmLW4}~Au_*jGu^@+%*!nG`qTJLk)EGfUR@um9f zD;r;ntP`>a*Nbehu`!Tr65;&6Igo6zu~mFqAlYssEdJyUvxg9~5x0@Hk>ONOX4y8_ z(VT1(92b1}(}rs!X(MHumAuDE=1!|@wfX*D3HjgRJd70gNI8XjI9hG|X5)7oKic@o#?LnP+W57uN%awX zxubEIeYRP`@zUlO4s#m^)HUp#UqucI=|7Yl5?|iNI&9+)8-KF9%giPi3(tW-Q%iY| zyN>mbjU$|15*U_%l|U$gwh6RL00|tGz_AI`PM}f(yfV6eo%JkV{z{mkbWFlb<2))S zP$hw?3RX*?Rv@pQKn?Ml!jsEFCH*o5%Z1D6>LQ<2SVx+fmaLmVMFRB_sGmTC1X?7} zQVIfi{njFt{tg{4(nk2ucGI@) z6X=k@$*g#pbwUEGbh~6|!aSzlF@a7AbWWIkh7%L$Bhn>-t|HwM=#@b41iB~CLz0ur zENb>lm^ar*c#K_XR+T3uFtfr)`bv$YUjqFTXjNtnPxVBIhP>ULbk7!dzaR&;Bj9#<5ePCU{}OoNK5*K7oq@O`cOON#N21 z?nvOy1fKoQnwY@h-qvLaa3#Y_k4XtkPGCv`QxlkQ-d!_U}4bm zixXHR{y}%sBiH{Azd^O5@Wuof`*CgS<^*m@fP@F-w@UdoNf^AH&B7P=%1uO- zrM>qz#n%Ym622{bNBC~SY|)pF4>X#1_vbSe{zKtMY_}5O{GY(5;%gJ;R#cz$#&18D zXi`c@1keW^cZorcw{E#MB7io?%_HP22gt;!x3UfkV zm=`jtAW~YB>_}j5Am5q5t^~eSaJTRW;dcq}lHvOV_9)1e0FChYQNf?&bw4Nmy^h`| z;V;7d!UMvC!e50qa^?*tk-IL^U8%$hU5gOGz8 znuq9wE!&2kFSFp7jr~i@EzTiFIjH2|Xvb^_*KknN!7&ahJE$T_bs?jwI%b}%CVZu> z#e>0G4$2(VmQHz~c_3vSD^49ItRr66L4`;?VFO`(VWy8!YZ&mx4w^V<=AgNQ!7o|7 zwb9fuW8`$*gyIA>qPaDpuGK;%Y3ZPqgVqj?chJVcfFuSc(bhpb$DG3canasE2R4O^ z#x729(9yxu4puqnaSP=)OI2h(&h=ZZ5DT`g* z;xuwzxpiNexxKIk>{X3gDV}(buiDtEC;h4%yDp)V@^FZUMf6GNFzKYmDjW8 zJGk1xH4d(I;8pxvc&>BUdTd*I4!dTdgGKak2RAxcEK}DzSmKxyB@NCgH-%??yHr?9 z9o*#LW(T)8xNL*WgU1{^ z?%)ae7)?=!)u$J+2g%v;Pf3$})k)Sf4xV+8cTjNfoP*~beCgmT2QN5y(ZM?o-gWSj zgO?q=?%)lU!NIEzRy%l2MoK4?>r{B2iP*o)@l6M79K7Y=ZRv1gX8~CF*Eg8;Bpq+O zW4-6#eFvX7_|(A%4nE|NbnvnCsWV$erQ5T$OWw8C!DkLWckqQq#D8^RFR(k>RhWyQ zbq>}$h&hNm*x+EJgRPvG9Bgv%wS&zLws5S?3bDm#lNRb-6{35u>0oa1Zg&uN5OENd zmo_c8O2ds^%=v`<{!=5%c95XYI7mBi*kulq4pQ=pQeV)2*dUWMT3OkQgRFy`1D`#( z-B@7Nc*-l~&YQw4NzuVK4*urU>R^Y1oeuVKv^v=3;9CbjIQY@QZU^5n7YBPZkoUE> zc!kKhns$D#WBQbqe{%4%gS~1%mYH+%dyPz#@ul|Geg_8}{N~_y2M49|tAj)G5bChC z=}{cHoFWc8_=7Fr;4iwXWxSoalx9@67@dcbBMvMVwOo|B2)TfZDlV$JILbvO7e~7| z#x>8tuy!0x_iZ#y&1R|Wf`pPvoc3K*cTvMdP50j?no2IszPP&FqC1V>WtF=))~ky!ZW`GtX)DOdv+4P7%!H*(GHB?;$Ms?jp5(8NVk7mvGm z!bLL|&0SpN;$jyqT(opC(8VAZtz5Kr(bYva7stD3!x`R1M;C2fwByY0qJ!+y8q4{Q zR=mwNT9ayrc(vZiMQ0Z$y6ED94bB3vRD4N|bzxs{(p$gH>h7Y4i#{&;y6EYmmy6ys z=wkFsrjS)^(_*yDwqkWSM%dK-T=aJ_zy-5l>#tO&iWHvv{Up32Bqru?4Ph zF~h}77gx%uCYOci^QEys9r_rnJjcaVF0OHLt&6!X=DC>f;%fCEHQ7Pa*I68ur6%P} zyTHYDE*832M1R)Fj!~Rjm?I~1_9Lh0B`$7oakq=*E^c(O)WvNsZg+8$i<@2C;^J01 zK!s^@>eCHqf#;q5dySDhT->SBE>peka?ROrcW%J?4^#vdMX@vw_WT|DOE5!Y-C(&uUFQQggC?o(@oSZpSL z(#2CQ5-uDUPrF#<;$s(|xOj%fUA*q%4SIr$=Uu$);uW>h3oc%C@sevczE~ZWmS^G8 zdFoXS@YOC}Q`z{y3{Qw`QVvPB)tfHXxOmUS`!3#c@wSV1T)gZ4`%DfShX8xmfSw3m0Fy_)0~k8f`Ln&Nij7 zzrn>u7n@vsEd{QHXpIfRW@KwnhxszN)kWAv#Kkrj+tu%Fq(*B|7T87Hh0W@8Fa>5p zItDwGC(}}Pu8Sl`gtADv@LYWBVz-O5i;Rnci=vCHi<}GJMP9XILROq>o>EQeU<`i4 zMs~5&#V*c5Qeg3@z=Ph-MGJ-Bx%l42PcD9Tv4=z3#gBnOdII&SQ?f}U-^+=}1=BLf zVw)%z2V5L<@vDo&F8)yRLoR-E@w+(d#Wta-eHDiM>EbUJf2(#3@(fFwqIwcFlBk?Sl_aVrQ7viaXSO7V9*acelB|nP zuQijXl|)$*4wb8Okx;#DnAaD0%XP7-yKXqZH!Br1}qmqh&}8YInWWp~1on_Lo_KP);3=M~)E&d3I=#M9U;jOrlE?t&(V+MEfK< zByoHaZMgDJqFoZ3|1r(WS%vfDWSuMN3C!h$BswP1DT&TWvofS{uCD2XRAwxvT#lEn z%sPqQtauXLljxB|&m?*!u}*t699CT9G;0*1gRwytR}J+^qHhxYlIYKiFHJr)MQ?1juDW(vn8aX}InCNVyVX_C;? zMM+$i#H1uHPGW+Dmn3m%5);{d+I*u9N$DV;oWxYAO%XCL3VB=}1gDEoazzp|0wIG} zCNV3C*^*o*oRh>=Nz6@RUJ@+uwMooR;_4)>QIJV!ykwuTe1?C4Lr^+;`ka;+`Z{Dz8<-dy{xPi6@e{Pr>_z4g;d{dOg&zn%6n>P%$0F3{ zA8K$rdTkQBQ{aU8SrVV~&IRR3B$9BF_%eyF)T--*+lA|s*pS3V@lC=l!ml}^Mc4~} zY`3-sd>cpHHnX$DBb-DekVn~)0goqP2Ygi>GkD!3zDZ(75=nMF|NK`-;)$e%8DTbw zoQN-^PF|!ymlIik$Qaz2#4b);DKtr$+45V?t0`1UVRsVWsX@L^;#ZM9!XJWG`cdSk zBz{g}ZxZ{G_(hVEOY9dv5O~Nzj(2T>(M1m_>bE3*PvWrnKSJjIM-qRE|0Voe$jORP zN5m}^G9;uBssDTW{pb{`r%*#t#|SH@P$kf;nnE@4lC_%R6+vvR6v|R4SCA`wT0S;~ z+6vYY)(tf2QT4>@|0fY?m_j3w`Z!6L+WoCOu@i-xcUMcjJyrZyF3Y}9pQM`+=M+#j|1(nHH8q82rEqo%uH<7BQn(<6 z2`OBX;*&+Di7r;!@xqG&v+QnegY&#Ya%l>eE0*Whi78x`!lV=?r!XajsjP^e>SURJ zsbRC!Vn{$Q8RVmD8nai!YDa;dL?U;lKuU4>R zfeEioVSy}=UnjCq$fo9%4#(z_6mCf2xfGsH;YQY)JLk$`X$m(<^Jd|lDcmA*YYMle zaJ%>&LJr2#xFfkMg=G@nox%zcMlGj({WBo>Jt?gGpH%myaKAErAcZGH9!%k(6dq3D zkrW=2ghk@wg!pL6Ts4q9{y*|3Q+P_jr&D-FWK|H$)rCpR5h}v=c_D?*QusWD7gKmC zg_l!!C4~=D<}SvoDXdQ6%@o!s_?qx_Asyolku@F6mf%|{yshB-DZG=yyD7YI*~6^;L9CswDl=$NFkzB8(B?0 z>XX8j6gG)7__YX^KwCw&OLJQgOF55lpu;warVx`(TxbguLPuCy4JK1arQoH&WoW~`nH>vSO9!ma5;ZKg`x>l%-+0OclQye$vJ^Y=*KPenZ!SZm7XYRg*Jbc;L z;z2%zed^&T$t!s{T2U01Vk=8tMOf8CH4nUJSKTvz*Iv^@4arNIL;IUXEAxz}l?#s* z))v+g*7Z;!QqM!965%TVA`OHMJu^qq0*~V)X)J8wnWs!CZ0@0jhf_U_^vtt=-2Q6m znY$RRJhb+3yoWX(26-6lp{<8@9!~Vo#Y1}!9XxdQkeB5SJOxl9-qAxR5A|6L1(^kP zcy#s9)5F7j{!<0uBgEZ3^zcAJO=2&}dwV#^Lmv-)Jq+aLByamNU*3x1e-L}^UkJEX3OSueDS}G6sFx11z%IFjizbJNCKuW<8QofNNY2@u@54`&LrotMJQjJWBqHr9C_#(H?b!-F2q_b|@G1P_;Z#?$CR7kDV`*j(tD zn_uHST;$_-@o=q& z8$8_TVF4S&!y*rhIjpo#yHIIaBc7eF7he)s2eCkuJ3ZXxVYxJy3GWv2daz_|OkHb*B=>k`0smreYbBdV+q_ihci6gLv8A*B zL+ox3k9c_0GxIiEl?AKWEcBRXUR@bk*IN6vG5ffOCzOi(Ns*_7PkUGu$hl+ioQLN< zI38RNFL-#-L&QVW!%H4s_V9{_SLtAUnxY#2lgMn3vub?$_vpr<)gE5+@VbXL=)HUa zft~K*O%H24yyf9-4_kX#AA5L5vF{71_O8f#!Ua3b1J56L_%Mk5NaU#wM*fM1PXqZ{ z_LP*rkYuCqOW{|-b;9*RrrqFiy=RPUlH_X-n>}n1-yY~}717b4?lR=<>6ZoyFGm8;d^P)fw}WPwaoZ74-#&^ zu~T^b=;0@I5N|y+Ew}bcpCgES9s9-ki3xi00neNh4@&Z@kd->5nc+9#??UdnaLeUS z&iNkx@$i?%DHGC9xX?P{p>o=+f2_0_;5vVil9Nu6WUs4YpIKwejbvGvnvkVdC8I;YKh84c4I#up@8TaD5< zj+}Q+(`JfmlSUH-o2JoBq`9zl8ZAVq*;1rc+B{?Cbv0M+$BUD+m63KrT5Hd|#7_`* zOoKOcDCdypcFG0~=kc4Yu4!~j!_Og~L-#a#q>;%Wn?cVsdZlq|8n>mE&k>#*$Xk_}4Z8EwSgej7$5Qd*Z;HK8 zI6jSw(zsasa^VEwC23rm#zb*?CbQsiS=xMmV^SKEC7+Tun>IYAio7!1nkM=5G_DYt zk;YYN%w@6DI8zp`lzf(Ows4M+vGYW(6*8~+B3BEqNu$qd93u-0B)LwwP`F5#=JP*l zpCxjV8`8KjZMGw5iv7Mcjhoa0H>Yun^jWE1-<$ukygiLO*uNQ!&EU>7?qV-zaC`>K z(zu)6#i5bL@-$YY@kAO=rg2XiE7Q0yjiGt#UiwunYj1_Myv&-##Vz0eN}H4H1ImK= zJ}CElNcgbuku)9^VeDgRJRWfFB0iPI(`h`P#tY2%?$D|<`0gQ3CC|{`jvRTGGnkeQ z&#^bZF)I+R4{LP}y_m+~h8DBFg3{cYOl#FLs4h|?g9e#@FMDfdP%DG749YV&HiLRn zsGUKb4C-c3kpXYsG3}ZP^Nci?uRHr#GbV@HO$*hRX6YKRVa81OjWRe+q;UpKGiWB> zM9AA@%`<3`LCXwUaW*b9cMt!6HXGPhn+)1!&?kew8MMoweFoh#=#fDORwRS28Fb5_ zW5!%Y@c{sK2dmsEgU%UqhUIZ$23-Qq8)v)=Od$s^uY7xE&?|%9EKJ5cjrq^bLyJZj!TR+tZoyp3sw-#z`JUWB3 zq;@ttRHU?WK1ZBy44o@ww)6QJjLTqY1~+AJLB>3?J}ZOS8C=McaPcp^NO-YuLI#(J zTq?X=I8k_+a8d@7MWzU+3TdkJ;PYaAUxGmRmQ|Pjm)(G-JL{aZ3ib zW^h{uw`Xui1`kT}PT@Tn^O1qO#Fq*07P5rPMOLuWgPo$48QdGh-j~7s;tvE8o_`+_ z=aTPXkw;{lrXI^+5EuU$JdweZ89bH2h72}l@N@>NGI%qCHFVAlp3UIp3|>*UK9|As z8N8su$f5LOE$c2*0GyH@Bwn{a*#w3rjc7sJSVFEg5Xh;A_b#*(|~mZp&bM2JsB+48j>iI2JO9 zDVBSfrKf0KeG9yA$g4s=JCVr1$-vDZDIH#RvE*zk+T{JdR0dwg>_o97X(`aV*mSuJ ze6`YhTnc7T$l%f}CT3C0fKRhm;&y8m-(;{OgPj@d%HU5a)8@A_@`G@<@H^r6!aeF2 zs`2s?&BR*j!@#S864uosBKlYKmCn8@_Pn{ zl{LHO4?3X=PyN3*%VqEnOUs!jixac3vIu3-Ad7}sAd922sGCJa7L~F%I*XcFjA>&X zlQr`^5Aw=cRLP<$l_jZ>MYSNdx`dNE7zZQPlDtenrbb6)p}#Ut@sH- z+HWV)Uf3avQn5QK*hyHbZ0QYVpbNjvzU{`kyardudWMS#Wv?Praoix4qqE7x8^hVy5^0otFz#n zN_;2xnk=r(nh%ojSRis;77GK(B9V!kO=B*};)X14WFgDU8Gk9=zMi$HgL%BPe^OzrR0>Ct`1(#;*~63&0=*HuVwLpEWDn@8(F-a z#XDKNDao2F-jcOa@{&z*l6SLsFN^o3R+7*-36Bq@Ktc(ZRi9+BHEZ6rVN-va#o8=B zqZ@GM7p}|Vi!8nrf3u$TRo1Nfczjc^)@QMSGit%2G9?=owMqDO7Mn#FyG7(N{`U=E zB;jq}EFxLlox}1RqFKbUXpuw99O7BnSv1dqtxdN{WKlnd201ucxLG8#NM-SB7Kdcb z%finhFP;`=gjsb{j_n-m^%b)CUQtCBRb)pNyR!H;i=7H`Gr{9qx>$@|(pb23vqd4lX3&iF5+U;A2~686 zht@fqox_-%*+HrwwvNxCO%82y;Ah4=sHW|5W?=GYFG6QHA%~7RbjqP~4yWcYGH32+ zoXFjt9D0a%5q1@J6Pndg4!v?1svz}y=g>EYeypG*eT1b|ME@KH0 zC-Pu&9z$~ft~ySZ&MCrSISdyWk;8wQC9|jHaJr&K3As|Dku$_e&dgzSz|YEI)jAV< zPR@ALoE)yo;oKa~%VDf~6w<-qidJtFezu|z{xpGXJ@ehIZVx&jh)MLm_~g)#W)8EYKpj4H z!>gw&bD#o)JZ9(6>{g594X*riSi)IOZ8c9-o1eqgIb0)tZ4NhzEXd(Hk%c*2FT#p1 zlBX>evh|kaaD$@Qq@~7On!`PhIoy%MEjiqp!)+3lbV}`iXAXA-b|_&d@>nJb zgDY~lCx^##cp`_DIozAWeL38p!}>Do(>ftuo93BdM^5GmF z3HYNVb<7sMqb#1x;VDjQW!B3%^D;i|Je>odtXP#ZZ|gsk!?PTul;rS24li;{>C122 z$>GO#$cZmWIETK?U7#FZW#8#D4y$u`Er-|D%Wn$b5VBi&MX*NvExMn`JHpZ}l6S>R zPd>b#!v_j}DEuggk2&bXX=j7Tr#Y+@`Aqn^@C)IWLTY{`vW_hlNVtyOn8T(VzRqE@ zgh}BR&hUZGR*`MO?ZR*l5s{YKwlZ~5FfO!nNQgK>#=0VW2O$+mJT@ucI#Dnq%;t~_ z)R?4@Ly=9F$Lo1~lfw@7bsqQUu``EVbZovXpU1a!<{UCUvc6ebe3t`!9OdKt9QNdl zw~O7AGMs{5$n zqo$8qK1TRB)khhXeRT58r%~u*TnQZOqqc8e?yJLC&b>bB`l#?x&qsY9Eq%1|(ZEMT zAB}x9@iB3+)yN0`3F0^z+4G)RGw=@Vm5t0t0Gdk3ZzneM(cCw;N?QmiA#d&Dcqz1% z9hRYu4_aVsbrwcZd$q~Qs1B^PkB&ZQnL!@Z?CkShFzZAgU3_%)(apyI9|L`KSK5<& z^zqTdM^7J5wF)swFW(qvnS1--XILod>!Y8P`wLl-r#X4s~lT;tx7X)oG-p55g zE|$UspZ{WJ>he>i5YxuDn%h_teaunpWj-ePnCxSUkLf`^j{&y zej{s!kD1KH$1KIN3uqj3tx|n=*0g5RJyiIsq%haVJRkGLuNKk{8@$x!3w&HhpYhG2 zf-bkv$L&7u@Ue)!I^>?}O?!HgDMh{wJ?RLd&=MxJ?SB z@|5sS-`w|K?&Cy$|3{p`Wj^i}ry>qQ?g`TUj$)^N^gVZH2|#SfoWeTD77T_E4A7*`8PUK4rU#~UJ? z{V05k?N-;?Q_GC{aa^(Zc*n=PKHl@qi9RKK-^T|&KBRFU>wK*D@v-Eeb0*=eZ-}?$;a0|w)xo3LE&SI^tVc% zM*cgPFs!JkkC;e=LpZQWQnGIcxhH%$;;e}4BdH`M9Z&MKkRN-eLXMs2qeUJq^T_)s z&@=OBkVnzSH=F?TsF_EbTA@{StsOpESGRWh*yZC}AG>`V^6{JIz3Ygol0n!M@QaHxn|CQ2yUCRLbM%JgP~4jF3jEid4>{iU?oWDWzh*jIEvr&GO*W4qG=` zyr8Z{wY(XL#hF1 zLrwDkuHKvG&Dpb=u(^=mGjEkg>pa@$(IJoH*&TVb&7)o3Jf6)0@CA7mjPH1I2=Fx= zere}~JUZqvJdY81bH47BH@AQ}E;{FNVjf-c<}n^EljH}cpB%je{9v=p=ABlXN$0vd0(>&ISbFZUh{|f~-=JBP-SHg9| z^}-E8Dsv-cQ^3C#*(}^5+$v;`Y|kSs9?2ss!n9G5m@uA)Es_Xg9T7K=q(~}|dwHbA zGl7KmbK<@*FD&pB!1aHivqxlyaHnvW@LP@@5tiq>JiZTj>GJu9JbujMr#ybnV{ab6 zD|VmoK%n`H$o~AlZ-pGp<5x)zG2g}>FVro9)ECp(R58oDfS;aPaYErxTFB9 zfKUPb3m8x^e=!eXph-2WQUSAhE-v6&zUopymXAO2d1k&1DtXlcs!6}PuwMZ+ z3YfqL3k!I;zEz9Hc}^*yyntg1s9iv3N$M0(w}55^G%ui{fO-WqD&RP(ap%8)1_d-M zfLSnK9xdw{IjUKWS)Kx#7R=wTFpC3chU!(Za{WUuvUoE>EedE^K$`;EN}*K&tqVB5 zfJ4t%)2|3!z?*c{tX1QzIM;*)v@f7T0Vfp9ALKO~5Tbo5bS!{2J1IGB-oRI=geS6U z1#~T-TLCAj{M`%aQ9#cEdKGYx`z?J#la94geM2mmRp08(V$`>2^HrYp_>q$W`YP25 z{--M6lH>ZVs+Fm44J_c?0?t#D4pL(dE?`IjLkl>WCFFPh)sk%OQ`9oUq%&OYJfeW% z4XlxaLTrbT1)L_$QNq)OX9yX4rpV|5&I%-F7cfTr93lVbh-xg=*aBFp@dcc(jK&pk zK>-)4csC6&)p?Xp2}<*#0xnkCPwHDeE$h+(CKj-znzgim%anGOaFTGcaEg$)Rf*evr@hWQ0ttu|pvzTlgE zm8}IT^TGlaiCm}H@B11*SzG{Xabp437qGlfXo(t@rfw+UHC|O!F&;vNn+mvD1?X*A zY?)gMxK;ko;lSV>1>8x0E~0i3cNMU#fX@r~Li%?X@IV0%N_lw!E9k}rtW?y*Y8G3M z)w#ET`_$Cr_p1OWTGm4_?-lUAM#q~4ydAXC z8rAD9W~XL(r+~W~Snn#fa~(*UtuG7ss(>`BS-`rWoSO?+FHTb%WO-u&n?$}AQqD$WEw)H)YXRGo-FC%> z3y2gDEg)8aTR>868!sTiYN`x&0h0!Y=r$~;QveIYT5!}~H!zfvLCU>S0qAlCjmSl~?xlzMrGa^Ix}+$r9wZ-`UPw*~Aj;5&LtHR}gvR{-<+UZ(aa zmm^iJpG4>?KP&da0`|%ROR`T*{R`WTGZkl^0)FKzT{P3j*cnOwcMKR0L#=!jb~9k|ZQYi*S^&Y?X_sQZy%v9t}+6R}-%;q_Boa zO<^rznXtTQ9EJ*Yil|#e?;=hrqN0d;MKmd*DJAkND%3BU(@g_m!y+0Lah!PPDputx zR^uXK1410I&5CF)%k6|MifARmBDE}n<9%Z_tF^c_FsffpZ5zbko)y4ny#dUUPW_?{Hsr>kMg~w zh)av;8`$qxME@cNs2HmnS_6w1RK(ySh7@r@(VUEUdKy~9X+?}G;^ZPuDVlj{n6ew8 zG7m4B(_brow40BBvc8rzvS{YCJF8izE0;5i7+u5}D#p?wAaeFoEA{F)Gq8UUJ zWMM;NOf2Fu7NCd)MNCrNXG(3dN-{;s**;S#R5_;!rwgx8gUpbFaZ{c; literal 0 HcmV?d00001 diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo new file mode 100644 index 0000000000..26f3845796 --- /dev/null +++ b/docs/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 613316d300d09679d4b613ea92bf496e +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/docs/html/_sources/admin_login.txt b/docs/html/_sources/admin_login.txt new file mode 100644 index 0000000000..6d209e940d --- /dev/null +++ b/docs/html/_sources/admin_login.txt @@ -0,0 +1,10 @@ +Administrator Login +=================== + +An application is built via the browser front end. To have the right access to build applications, you must +login as an Administrator. + +If you are in a new system that does not have any application, your first login as "Administrator" is the +Administrator login. + + diff --git a/docs/html/_sources/apps_intro.txt b/docs/html/_sources/apps_intro.txt new file mode 100644 index 0000000000..a4fc06a6bb --- /dev/null +++ b/docs/html/_sources/apps_intro.txt @@ -0,0 +1,98 @@ +Using the Administrator Interface +================================= + +Applications are built using the web based administrator interface of the framework. + +Let us start discuss how to build applications using the basic building blocks + +What is an Application? +----------------------- + +Let us define a typical web application as being a set of: + + #. Users - who use the application + #. Roles - roles assigned to users for various functions + #. Pages - where users navigate and see relevant information + #. Forms - where users enter new data + #. Reports - where users get a tabulated view of their data + #. Permission Rules - that define what each role is allowed to do or not do + #. Logic - Automatic actions that are performed at various events + #. Validations - Checks that ensure the data entered by the users is valid + #. Print Formats - Printable documents based on the data users have entered + #. UI Widgets - Menus, Lists, Dialogs that are used for navigating, entering or displaying information + #. Module - So that you can group Roles, Forms, Pages, Reports for more complex applications + +Let us now start building these entities in the wnframework + +Administrator Login +------------------- + +An application is built via the browser front end. To have the right access to build applications, you must +login as an Administrator. + +If you are in a new system that does not have any application, your first login as "Administrator" is the +Administrator login. + +Creating Entities +----------------- + +To create any entity, you must have the relevant permission. Once you have the relevant permission, you can +create new entities from the top toolbar. + +Look out for the "New" button on the top left of the page. Via the "New" dialog box, you can create any +entity you have rights to create. + +.. note:: + + * Entities in wnframework are known by their "name". Name has the same concept as id - its a unique key + for that entity (same as a Primary Key). + * Every entity also has an "owner" - By default this is the user who creates that entity. + +Managing Roles +--------------- + +Roles are assigned to users so that you can define a group of users and set permission (or other) rules. + + #. To create a new role, click "New" on the top toolbar and select "Role" + #. Give the Role name, use descriptive names here like - "Contact Manager" + #. Set the module, (use the standard; if you want create a new module, go ahead!) + #. Click on the green "Save" button + +Your new Roles is created! To check, click on the "Search" button on the top toolbar and select "Role" +Click on "Search" and see that your new Role is added to the list of already existing roles: + +.. note:: + + Pre-defined roles. There are 3 basic roles that are pre-defined in the system. It is suggested, + you leave them as it is! + + #. Administrator: Role given to the application builder / maintainer + #. All: All logged in users have the role "All" + #. Guest: Users who are not yet logged in. + +Creating Users (Profile) +------------------------ + +A Profile (=user) has a unique identity in the system and can be tagged as an "onwer" to a data record. +Profiles can also be assigned Roles that restrict what they can do. You can also define custom logic +for a Profile + +To create a new Profile: + + #. Create a new Profile via "New" on the top toolbar + #. Enter the mandatory "First Name" and "Email" values + #. "Save" the profile via the "Save" button + #. The user will be sent an email with her random-genereated password. You can also set a custom password + by clicking on the "Password" tab and setting the password. + #. *To assign a role, click on the "Roles" tab and add a "Role" in the table.* + +Once a Profile is created, the user can login with the login id (email) and password. + +.. note:: + + Profiles are given an id that is the same as their email id. Why did we do this? + + * Email Ids are good unique identifiers. Your users may have the same first and last names, + but they would have separate Email Ids + * People usually remember their email ids + * Email Ids are these days the de-facto way to define login-ids diff --git a/docs/html/_sources/auth.txt b/docs/html/_sources/auth.txt new file mode 100644 index 0000000000..c5df2fec59 --- /dev/null +++ b/docs/html/_sources/auth.txt @@ -0,0 +1,104 @@ +:mod:`auth` --- Authentication +============================== + +.. module:: auth + :synopsis: Authentication module + +Authentication object +--------------------- + +.. class:: Authentication(self, form, in_cookies, out_cookies, out) + + A new Authenticate object is created at the beginning of any request. It will manage login, session and + cookies. :method:`update` must be called at the end of the request to update cookies and + session. + + The constructor will also set the global `webnotes.conn`, `webnotes.session` and `webnotes.user` + + To enable a login, the :object:form must have a cmd = "login" (see request handling for more details) + + .. attribute:: conn + + `webnotes.db.Database` object created after authentication + + .. attribute:: session + + session dictionary of the current session + + .. attribute:: cookies + + session dictionary of incoming cookies + + .. attribute:: domain + + domain name of the request + + .. attribute:: remote_ip + + IP address of the reqeust + + .. method:: update() + + **Must be called at the end of the request, to update the session and clear expired sessions** + + .. method:: set_env() + + Sets the properties `domain` and `remote_ip` from the environmental variables + + .. method:: set_db() + + In case of a multi-database system, this methods sets the correct database connection. + + * It will first search for cookie `account_id` + * It will next search for cookies or form variable `__account` + * It will try and search from the domain mapping table `Account Domain` in the `accounts` database + * It will try and use the default + + .. method:: check_ip() + + If the current request is from a separate IP than the one which was used to create the session, then + this throws an Exception + + .. method:: load_session(sid) + + Load session from the given session id `sid` + + .. method:: login(as_guest = 0) + + Will login user from `self.form`. If as_guest is true, it will check if Guest profile is enabled + + It will also: + + * validate if approved ips are set in `Profile` + * start the session + * set "remember me" + * return out.message as "Logged In" + + .. method:: check_password(user, pwd) + + Checks if the user has the pwd and is enabled + + .. method:: validate_ip(user) + + Validates IP address from the ip_address value in the user's `Profile` + + .. method:: start_session() + + Starts a session, and updates last login details in the users's `Profile` + + .. method:: clear_expired() + + Removes old sessions from `tabSessions` that are older than `session_expiry` in `Control Panel` or 24:00 hrs + + .. method:: set_cookies() + + Sets outgoing cookies + + .. method:: set_remember_me() + + Checks if there is a 'remember_me' property in `form` with a value and if true, its sets the + expiry of each cookie for `remember_for_days` in `Control Panel` or 7 days + + .. method:: get_cookies() + + Loads incoming cookies in `cookies` diff --git a/docs/html/_sources/autosuggest.txt b/docs/html/_sources/autosuggest.txt new file mode 100644 index 0000000000..dff5a7af44 --- /dev/null +++ b/docs/html/_sources/autosuggest.txt @@ -0,0 +1,62 @@ +Autosuggest +=========== + +Adapted from: Timothy Groves - http://www.brandspankingnew.net + +.. data:: cur_autosug + + Live Autosuggest object + +.. function:: hide_autosuggest() + + Hide the Live Autosuggest (if exists) + +.. class:: AutoSuggest(id, param) + + Create a new autosuggest object + +Overriding the default call +--------------------------- + +* To override the default server call, override the method `doAjaxRequest` +* To override updation in the INPUT element, override the method `custom_select` + +Example +------- + +Example where email id is to be retrieved:: + + // ---- add auto suggest ---- + var opts = { script: '', json: true, maxresults: 10 }; + + var as = new AutoSuggest(d.widgets['To'], opts); + as.custom_select = function(txt, sel) { + // ---- add to the last comma ---- + var r = ''; + var tl = txt.split(','); + for(var i=0;i\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlight'); + }); + }, 10); + $('

  2. ') + .appendTo($('.sidebar .this-page-menu')); + } + }, + + /** + * init the modindex toggle buttons + */ + initModIndex : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + console.log($('tr.cg-' + idnum).toggle()); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); + $('span.highlight').removeClass('highlight'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/_static/file.png b/docs/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..d18082e397e7e54f20721af768c4c2983258f1b4 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN literal 0 HcmV?d00001 diff --git a/docs/html/_static/jquery.js b/docs/html/_static/jquery.js new file mode 100644 index 0000000000..82b98e1d76 --- /dev/null +++ b/docs/html/_static/jquery.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ + */ +(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else +while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file diff --git a/docs/html/_static/minus.png b/docs/html/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknKU}oXkrghqJ&VvY3H^ zTNs2H8D`Cq01C2~c>21s-(chw7$R|bZ|_0D0|q>YSbqDzW^|HYIk%*-&O)*< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF literal 0 HcmV?d00001 diff --git a/docs/html/_static/pygments.css b/docs/html/_static/pygments.css new file mode 100644 index 0000000000..1f2d2b6187 --- /dev/null +++ b/docs/html/_static/pygments.css @@ -0,0 +1,61 @@ +.hll { background-color: #ffffcc } +.c { color: #408090; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #007020; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.cp { color: #007020 } /* Comment.Preproc */ +.c1 { color: #408090; font-style: italic } /* Comment.Single */ +.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #FF0000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #00A000 } /* Generic.Inserted */ +.go { color: #303030 } /* Generic.Output */ +.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0040D0 } /* Generic.Traceback */ +.kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #007020 } /* Keyword.Pseudo */ +.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #902000 } /* Keyword.Type */ +.m { color: #208050 } /* Literal.Number */ +.s { color: #4070a0 } /* Literal.String */ +.na { color: #4070a0 } /* Name.Attribute */ +.nb { color: #007020 } /* Name.Builtin */ +.nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.no { color: #60add5 } /* Name.Constant */ +.nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.ne { color: #007020 } /* Name.Exception */ +.nf { color: #06287e } /* Name.Function */ +.nl { color: #002070; font-weight: bold } /* Name.Label */ +.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.nt { color: #062873; font-weight: bold } /* Name.Tag */ +.nv { color: #bb60d5 } /* Name.Variable */ +.ow { color: #007020; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mf { color: #208050 } /* Literal.Number.Float */ +.mh { color: #208050 } /* Literal.Number.Hex */ +.mi { color: #208050 } /* Literal.Number.Integer */ +.mo { color: #208050 } /* Literal.Number.Oct */ +.sb { color: #4070a0 } /* Literal.String.Backtick */ +.sc { color: #4070a0 } /* Literal.String.Char */ +.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #4070a0 } /* Literal.String.Double */ +.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #4070a0 } /* Literal.String.Heredoc */ +.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.sx { color: #c65d09 } /* Literal.String.Other */ +.sr { color: #235388 } /* Literal.String.Regex */ +.s1 { color: #4070a0 } /* Literal.String.Single */ +.ss { color: #517918 } /* Literal.String.Symbol */ +.bp { color: #007020 } /* Name.Builtin.Pseudo */ +.vc { color: #bb60d5 } /* Name.Variable.Class */ +.vg { color: #bb60d5 } /* Name.Variable.Global */ +.vi { color: #bb60d5 } /* Name.Variable.Instance */ +.il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/html/_static/searchtools.js b/docs/html/_static/searchtools.js new file mode 100644 index 0000000000..e0226258a5 --- /dev/null +++ b/docs/html/_static/searchtools.js @@ -0,0 +1,467 @@ +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
    ').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlight'); + }); + return rv; +} + +/** + * Porter Stemmer + */ +var PorterStemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + /** + * Sets the index + */ + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

    ' + _('Searching') + '

    ').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

    ').appendTo(this.out); + this.output = $('
    ';c.cur_label=label;break;}}} +_f.FormGrid.prototype.refresh=function(){var docset=getchildren(this.doctype,this.field.frm.docname,this.field.df.fieldname,this.field.frm.doctype);var data=[];for(var i=0;i*';r.is_newrow=true;} +_f.FormGrid.prototype.check_selected=function(){if(!_f.cur_grid_cell){show_alert('Select a cell first');return false;} +if(_f.cur_grid_cell.grid!=this){show_alert('Select a cell first');return false;} +return true;} +_f.FormGrid.prototype.delete_row=function(dt,dn){if(dt&&dn){LocalDB.delete_record(dt,dn);this.refresh();}else{if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;var ci=_f.cur_grid_cell.cellIndex;var ri=_f.cur_grid_cell.row.rowIndex;LocalDB.delete_record(this.doctype,r.docname);this.refresh();if(ri<(this.tab.rows.length-2)) +this.cell_select(null,ri,ci);else _f.cur_grid_cell=null;} +this.set_unsaved();} +_f.FormGrid.prototype.move_row=function(up){if(!this.check_selected())return;var r=_f.cur_grid_cell.row;if(r.is_newrow)return;if(up&&r.rowIndex>0){var swap_row=this.tab.rows[r.rowIndex-1];}else if(!up){var len=this.tab.rows.length;if(this.tab.rows[len-1].is_newrow) +len=len-1;if(r.rowIndex<(len-1)) +var swap_row=this.tab.rows[r.rowIndex+1];} +if(swap_row){var cidx=_f.cur_grid_cell.cellIndex;this.cell_deselect();var aidx=locals[this.doctype][r.docname].idx;locals[this.doctype][r.docname].idx=locals[this.doctype][swap_row.docname].idx;locals[this.doctype][swap_row.docname].idx=aidx;var adocname=swap_row.docname;this.refresh_row(swap_row.rowIndex,r.docname);this.refresh_row(r.rowIndex,adocname);this.cell_select(this.tab.rows[swap_row.rowIndex].cells[cidx]);this.set_unsaved();}} +_p.show_dialog=function(){if(!_p.dialog){_p.make_dialog();} +_p.dialog.show();} +_p.make_dialog=function(){var d=new Dialog(360,140,"Print Formats");d.make_body([['HTML','Select'],['Check','No Letterhead','Will ignore letterhead if it can be set. May not work for all formats'],['HTML','Buttons']]);d.widgets['No Letterhead'].checked=1;$btn(d.widgets.Buttons,'Print',function(){_p.build(sel_val(cur_frm.print_sel),_p.go,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px',marginLeft:'7px'},'green');$btn(d.widgets.Buttons,'Preview',function(){_p.build(sel_val(cur_frm.print_sel),_p.preview,d.widgets['No Letterhead'].checked);},{cssFloat:'right',marginBottom:'16px'},'');_p.dialog=d;d.onshow=function(){var c=d.widgets['Select'];if(c.cur_sel&&c.cur_sel.parentNode==c) +c.removeChild(c.cur_sel);c.appendChild(cur_frm.print_sel);c.cur_sel=cur_frm.print_sel;}} +_p.field_tab=function(layout_cell){var t=$a(layout_cell,'table','',{width:'100%'});var r=t.insertRow(0);this.r=r;r.insertCell(0);r.insertCell(1);r.cells[0].className='datalabelcell';r.cells[1].className='datainputcell';return r} +_p.print_std_add_table=function(t,layout,pf_list,dt,no_letterhead){if(t.appendChild){layout.cur_cell.appendChild(t);}else{for(var ti=0;ti';layout=_p.add_layout(dt,no_letterhead);pf_list[pf_list.length]=layout;layout.addrow();layout.addcell();var div=$a(layout.cur_cell,'div');div.innerHTML='Continued from previous page...';div.style.padding='4px';} +layout.cur_cell.appendChild(t[t.length-1]);} +return layout;} +_p.print_std_add_field=function(dt,dn,f,layout){var v=_f.get_value(dt,dn,f.fieldname);if(f.fieldtype!="Button"){if(!v&&!in_list(['Float','Int','Currency'],f.fieldtype)){}else{r=_p.field_tab(layout.cur_cell) +r.cells[0].innerHTML=f.label?f.label:f.fieldname;$s(r.cells[1],v,f.fieldtype);if(f.fieldtype=='Currency') +$y(r.cells[1],{textAlign:'left'});}}} +_p.get_letter_head=function(){var cp=locals['Control Panel']['Control Panel'];if(cur_frm.doc.letter_head) +var lh=cstr(_p.letter_heads[cur_frm.doc.letter_head]);else if(cp.letter_head) +var lh=cp.letter_head;else +var lh='';return lh;} +_p.add_layout=function(dt,no_letterhead){var l=new Layout();l.addrow();if(locals['DocType'][dt].print_outline=='Yes')l.with_border=1;return l;} +_p.print_std=function(no_letterhead){var dn=cur_frm.docname;var dt=cur_frm.doctype;var pf_list=[];var layout=_p.add_layout(dt,no_letterhead);pf_list[pf_list.length]=layout;var h1=$a(layout.cur_row.header,'h1','',{fontSize:'22px',marginBottom:'8px'});h1.innerHTML=cur_frm.pformat[dn]?cur_frm.pformat[dn]:get_doctype_label(dt);var h2=$a(layout.cur_row.header,'div','',{fontSize:'16px',color:'#888',marginBottom:'8px',paddingBottom:'8px',borderBottom:(layout.with_border?'0px':'1px solid #000')});h2.innerHTML=dn;var fl=getchildren('DocField',dt,'fields','DocType');if(fl[0]&&fl[0].fieldtype!="Section Break"){layout.addrow();if(fl[0].fieldtype!="Column Break") +layout.addcell();} +for(var i=0;i'+f.label+': '+'
    '+(v?v:'')+'
    ';break;case'Text Editor':var tmp=$a(layout.cur_cell,'div');var v=_f.get_value(dt,dn,f.fieldname);tmp.innerHTML=v?v:'';break;default:_p.print_std_add_field(dt,dn,f,layout);}}}} +layout.close_borders();var html='';for(var i=0;i0){for(var i=0;i'+block.innerHTML;} +if(only_body){return tmp_html+block.innerHTML.replace(/\n' ++'' ++''+title+'' ++'' ++'' ++tmp_html ++block.innerHTML.replace(/';}} +print_table=function(dt,dn,fieldname,tabletype,cols,head_labels,widths,condition,cssClass){var fl=fields_list[tabletype];var ds=getchildren(tabletype,dn,fieldname,dt);var tl=[];var cell_style={border:'1px solid #000',padding:'2px',verticalAlign:'top'};var head_cell_style={border:'1px solid #000',padding:'2px',verticalAlign:'top',backgroundColor:'#ddd'};var make_table=function(fl){var w=document.createElement('div');var t=$a(w,'table','',{width:'100%',borderCollapse:'collapse',marginBottom:'10px'});t.wrapper=w;t.insertRow(0);var c_start=0;if(fl[0]=='SR'){var cell=t.rows[0].insertCell(0) +cell.innerHTML=head_labels?head_labels[0]:'Sr';$y(cell,{width:'30px'});$y(cell,head_cell_style) +c_start=1;} +for(var c=c_start;c1)return tl;else return tl[0];} +_e.email_as_field='email_id';_e.email_as_dt='Contact';_e.email_as_in='email_id,contact_name';sendmail=function(emailto,emailfrom,cc,subject,message,fmt,with_attachments){var fn=function(html){$c('webnotes.utils.email_lib.send_form',{'sendto':emailto,'sendfrom':emailfrom?emailfrom:'','cc':cc?cc:'','subject':subject,'message':replace_newlines(message),'body':html,'full_domain':wn.urllib.get_base_url(),'with_attachments':with_attachments?1:0,'dt':cur_frm.doctype,'dn':cur_frm.docname},function(r,rtxt){});} +_p.build(fmt,fn);} +_e.make=function(){var d=new Dialog(440,440,"Send Email");var email_go=function(){var emailfrom=d.widgets['From'].value;var emailto=d.widgets['To'].value;if(!emailfrom) +emailfrom=user_email;var email_list=emailto.split(/[,|;]/);var valid=1;for(var i=0;i12){time=(parseInt(hr)-12)+':'+min+' PM'} +else{time=hr+':'+min+' AM'}} +this.cmt_dtl.innerHTML='On '+d[ri][10].substring(0,3)+' '+d[ri][9]+', '+d[ri][11]+' at '+time;this.cmt.innerHTML=replace_newlines(d[ri][1]);} +CommentItem.prototype.cmt_delete=function(cell,ri,ci,d){var me=this;if(d[ri][2]==user||d[ri][3]==user){del=$a(cell,'div','wn-icon ic-trash',{cursor:'pointer'});del.cmt_id=d[ri][0];del.onclick=function(){wn.widgets.form.comments.remove(cur_frm.doctype,cur_frm.docname,this.cmt_id,function(){me.comment.lst.run();})}}} +wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'ic-doc_new',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'Refresh',icon:'ic-playback_reload',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!me.form.doc.__islocal},icon:'ic-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!me.form.doc.__islocal},icon:'ic-mail',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'ic-clipboard_copy',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return me.form.meta.allow_trash&&cint(me.form.doc.docstatus)!=2&&(!me.form.doc.__islocal)&&me.form.perm[0][CANCEL]},icon:'ic-trash',onclick:function(){me.form.savetrash()}}]},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}}]} +this.refresh=function(){var parent=this.form.page_layout.sidebar_area;if(!this.sidebar){$y(parent,{paddingTop:'37px'}) +this.sidebar=new wn.widgets.PageSidebar(parent,this.opts);}else{this.sidebar.refresh();}}}} +wn.widgets.form.sidebar.Comments=function(parent,sidebar,doctype,docname){var me=this;this.sidebar=sidebar;this.doctype=doctype;this.docname=docname;this.refresh=function(){$c('webnotes.widgets.form.get_comments',{dt:me.doctype,dn:me.docname,limit:5},function(r,rt){wn.widgets.form.comments.sync(me.doctype,me.docname,r);me.make_body();});} +this.make_body=function(){if(this.wrapper)this.wrapper.innerHTML='';else this.wrapper=$a(parent,'div','sidebar-comment-wrapper');this.input=$a_input(this.wrapper,'text');this.btn=$btn(this.wrapper,'Post',function(){me.add_comment()},{marginLeft:'8px'});this.render_comments()} +this.render_comments=function(){var f=wn.widgets.form.comments;var cl=f.comment_list[me.docname] +this.msg=$a(this.wrapper,'div','sidebar-comment-message');if(cl){this.msg.innerHTML=cl.length+' out of '+f.n_comments[me.docname]+' comments';if(f.n_comments[me.docname]>cl.length){this.msg.innerHTML+=' Show all'} +for(var i=0;i1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}function F(j){var ae,Z=1;j=String(j);if(j.charAt(0)=="#"){ae=j}else{if(/^rgb/.test(j)){var p=M(j);var ae="#",af;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){af=Math.floor(c(p[m])*255)}else{af=Number(p[m])}ae+=n[u(af,0,255)]}Z=p[3]}else{if(/^hsl/.test(j)){var p=M(j);ae=I(p);Z=p[3]}else{ae=b[j]||j}}}return{color:ae,alpha:Z}}var r={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||r.style,variant:m.fontVariant||r.variant,weight:m.fontWeight||r.weight,size:m.fontSize||r.size,family:m.fontFamily||r.family}}function w(m,j){var i={};for(var af in m){i[af]=m[af]}var ae=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ae*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ae/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=ae*(4/3)*Z}else{i.size=ae}}}}}i.size*=0.981;return i}function aa(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}function S(i){switch(i){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function D(j){this.m_=C();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=j;var i=j.ownerDocument.createElement("div");i.style.width=j.clientWidth+"px";i.style.height=j.clientHeight+"px";i.style.overflow="hidden";i.style.position="absolute";j.appendChild(i);this.element_=i;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var t=D.prototype;t.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};t.beginPath=function(){this.currentPath_=[]};t.moveTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};t.lineTo=function(j,i){var m=this.getCoords_(j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};t.bezierCurveTo=function(m,j,ai,ah,ag,ae){var i=this.getCoords_(ag,ae);var af=this.getCoords_(m,j);var Z=this.getCoords_(ai,ah);K(this,af,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}t.quadraticCurveTo=function(ag,m,j,i){var af=this.getCoords_(ag,m);var ae=this.getCoords_(j,i);var ah={x:this.currentX_+2/3*(af.x-this.currentX_),y:this.currentY_+2/3*(af.y-this.currentY_)};var Z={x:ah.x+(ae.x-this.currentX_)/3,y:ah.y+(ae.y-this.currentY_)/3};K(this,ah,Z,ae)};t.arc=function(aj,ah,ai,ae,j,m){ai*=d;var an=m?"at":"wa";var ak=aj+B(ae)*ai-f;var am=ah+o(ae)*ai-f;var i=aj+B(j)*ai-f;var al=ah+o(j)*ai-f;if(ak==i&&!m){ak+=0.125}var Z=this.getCoords_(aj,ah);var ag=this.getCoords_(ak,am);var af=this.getCoords_(i,al);this.currentPath_.push({type:an,x:Z.x,y:Z.y,radius:ai,xStart:ag.x,yStart:ag.y,xEnd:af.x,yEnd:af.y})};t.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};t.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};t.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};t.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};t.createRadialGradient=function(p,ae,m,j,Z,i){var af=new U("gradientradial");af.x0_=p;af.y0_=ae;af.r0_=m;af.x1_=j;af.y1_=Z;af.r1_=i;return af};t.drawImage=function(ao,m){var ah,af,aj,aw,am,ak,aq,ay;var ai=ao.runtimeStyle.width;var an=ao.runtimeStyle.height;ao.runtimeStyle.width="auto";ao.runtimeStyle.height="auto";var ag=ao.width;var au=ao.height;ao.runtimeStyle.width=ai;ao.runtimeStyle.height=an;if(arguments.length==3){ah=arguments[1];af=arguments[2];am=ak=0;aq=aj=ag;ay=aw=au}else{if(arguments.length==5){ah=arguments[1];af=arguments[2];aj=arguments[3];aw=arguments[4];am=ak=0;aq=ag;ay=au}else{if(arguments.length==9){am=arguments[1];ak=arguments[2];aq=arguments[3];ay=arguments[4];ah=arguments[5];af=arguments[6];aj=arguments[7];aw=arguments[8]}else{throw Error("Invalid number of arguments")}}}var ax=this.getCoords_(ah,af);var p=aq/2;var j=ay/2;var av=[];var i=10;var ae=10;av.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",av.join(""))};t.stroke=function(aj){var ah=[];var Z=false;var m=10;var ak=10;ah.push("ai.x){ai.x=j.x}if(ae.y==null||j.yai.y){ai.y=j.y}}}ah.push(' ">');if(!aj){y(this,ah)}else{G(this,ah,ae,ai)}ah.push("");this.element_.insertAdjacentHTML("beforeEnd",ah.join(""))};function y(m,ae){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ae.push("')}function G(ao,ag,aI,ap){var ah=ao.fillStyle;var az=ao.arcScaleX_;var ay=ao.arcScaleY_;var j=ap.x-aI.x;var p=ap.y-aI.y;if(ah instanceof U){var al=0;var aD={x:0,y:0};var av=0;var ak=1;if(ah.type_=="gradient"){var aj=ah.x0_/az;var m=ah.y0_/ay;var ai=ah.x1_/az;var aK=ah.y1_/ay;var aH=ao.getCoords_(aj,m);var aG=ao.getCoords_(ai,aK);var ae=aG.x-aH.x;var Z=aG.y-aH.y;al=Math.atan2(ae,Z)*180/Math.PI;if(al<0){al+=360}if(al<0.000001){al=0}}else{var aH=ao.getCoords_(ah.x0_,ah.y0_);aD={x:(aH.x-aI.x)/j,y:(aH.y-aI.y)/p};j/=az*d;p/=ay*d;var aB=Y.max(j,p);av=2*ah.r0_/aB;ak=2*ah.r1_/aB-av}var at=ah.colors_;at.sort(function(aL,i){return aL.offset-i.offset});var an=at.length;var ar=at[0].color;var aq=at[an-1].color;var ax=at[0].alpha*ao.globalAlpha;var aw=at[an-1].alpha*ao.globalAlpha;var aC=[];for(var aF=0;aF')}else{if(ah instanceof T){if(j&&p){var af=-aI.x;var aA=-aI.y;ag.push("')}}else{var aJ=F(ao.fillStyle);var au=aJ.color;var aE=aJ.alpha*ao.globalAlpha;ag.push('')}}}t.fill=function(){this.stroke(true)};t.closePath=function(){this.currentPath_.push({type:"close"})};t.getCoords_=function(p,j){var i=this.m_;return{x:d*(p*i[0][0]+j*i[1][0]+i[2][0])-f,y:d*(p*i[0][1]+j*i[1][1]+i[2][1])-f}};t.save=function(){var i={};x(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(C(),this.m_)};t.restore=function(){if(this.aStack_.length){x(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function k(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function X(j,i,p){if(!k(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}t.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];X(this,J(i,this.m_),false)};t.rotate=function(j){var p=B(j);var m=o(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];X(this,J(i,this.m_),false)};t.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];X(this,J(i,this.m_),true)};t.transform=function(Z,p,af,ae,j,i){var m=[[Z,p,0],[af,ae,0],[j,i,1]];X(this,J(m,this.m_),true)};t.setTransform=function(ae,Z,ag,af,p,j){var i=[[ae,Z,0],[ag,af,0],[p,j,1]];X(this,i,true)};t.drawText_=function(ak,ai,ah,an,ag){var am=this.m_,aq=1000,j=0,ap=aq,af={x:0,y:0},ae=[];var i=w(E(this.font),this.element_);var p=aa(i);var ar=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=ar.direction=="ltr"?"right":"left";break;case"start":Z=ar.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":af.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":af.y=-i.size/2.25;break}switch(Z){case"right":j=aq;ap=0.05;break;case"center":j=ap=aq/2;break}var ao=this.getCoords_(ai+af.x,ah+af.y);ae.push('');if(ag){y(this,ae)}else{G(this,ae,{x:-j,y:0},{x:ap,y:i.size})}var al=am[0][0].toFixed(3)+","+am[1][0].toFixed(3)+","+am[0][1].toFixed(3)+","+am[1][1].toFixed(3)+",0,0";var aj=q(ao.x/d)+","+q(ao.y/d);ae.push('','','');this.element_.insertAdjacentHTML("beforeEnd",ae.join(""))};t.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};t.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};t.measureText=function(m){if(!this.textMeasureEl_){var i='';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};t.clip=function(){};t.arcTo=function(){};t.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var W=P.prototype=new Error;W.INDEX_SIZE_ERR=1;W.DOMSTRING_SIZE_ERR=2;W.HIERARCHY_REQUEST_ERR=3;W.WRONG_DOCUMENT_ERR=4;W.INVALID_CHARACTER_ERR=5;W.NO_DATA_ALLOWED_ERR=6;W.NO_MODIFICATION_ALLOWED_ERR=7;W.NOT_FOUND_ERR=8;W.NOT_SUPPORTED_ERR=9;W.INUSE_ATTRIBUTE_ERR=10;W.INVALID_STATE_ERR=11;W.SYNTAX_ERR=12;W.INVALID_MODIFICATION_ERR=13;W.NAMESPACE_ERR=14;W.INVALID_ACCESS_ERR=15;W.VALIDATION_ERR=16;W.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P})()}; \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.barRenderer.js b/js/jquery/jqplot-plugins/jqplot.barRenderer.js new file mode 100644 index 0000000000..4feb37b799 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.barRenderer.js @@ -0,0 +1,404 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + + // Class: $.jqplot.BarRenderer + // A plugin renderer for jqPlot to draw a bar plot. + // Draws series as a line. + + $.jqplot.BarRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; + + // called with scope of series. + $.jqplot.BarRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: barPadding + // Number of pixels between adjacent bars at the same axis value. + this.barPadding = 8; + // prop: barMargin + // Number of pixels between groups of bars at adjacent axis values. + this.barMargin = 10; + // prop: barDirection + // 'vertical' = up and down bars, 'horizontal' = side to side bars + this.barDirection = 'vertical'; + // prop: barWidth + // Width of the bar in pixels (auto by devaul). null = calculated automatically. + this.barWidth = null; + // prop: shadowOffset + // offset of the shadow from the slice and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.08; + // prop: waterfall + // true to enable waterfall plot. + this.waterfall = false; + // prop: varyBarColor + // true to color each bar separately. + this.varyBarColor = false; + $.extend(true, this, options); + // fill is still needed to properly draw the legend. + // bars have to be filled. + this.fill = true; + + if (this.waterfall) { + this.fillToZero = false; + this.disableStack = true; + } + + if (this.barDirection == 'vertical' ) { + this._primaryAxis = '_xaxis'; + this._stackAxis = 'y'; + this.fillAxis = 'y'; + } + else { + this._primaryAxis = '_yaxis'; + this._stackAxis = 'x'; + this.fillAxis = 'x'; + } + // set the shape renderer options + var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; + this.renderer.shapeRenderer.init(opts); + // set the shadow renderer options + var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; + this.renderer.shadowRenderer.init(sopts); + }; + + // called with scope of series + function barPreInit(target, data, seriesDefaults, options) { + if (this.rendererOptions.barDirection == 'horizontal') { + this._stackAxis = 'x'; + this._primaryAxis = '_yaxis'; + } + if (this.rendererOptions.waterfall == true) { + this._data = $.extend(true, [], this.data); + var sum = 0; + var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection == 'vertical') ? 1 : 0; + for(var i=0; i0) { + this.data[i][pos] += this.data[i-1][pos]; + } + } + this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; + this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; + } + } + + $.jqplot.preSeriesInitHooks.push(barPreInit); + + // needs to be called with scope of series, not renderer. + $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + // loop through all series on this axis + for (var i=0; i < paxis._series.length; i++) { + series = paxis._series[i]; + if (series === this) { + pos = i; + } + // is the series rendered as a bar? + if (series.renderer.constructor == $.jqplot.BarRenderer) { + // gridData may not be computed yet, use data length insted + nvals += series.data.length; + nseries += 1; + } + } + return [nvals, nseries, pos]; + }; + + $.jqplot.BarRenderer.prototype.setBarWidth = function() { + // need to know how many data values we have on the approprate axis and figure it out. + var i; + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + var nticks = paxis.numberTicks; + var nbins = (nticks-1)/2; + // so, now we have total number of axis values. + if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { + if (this._stack) { + this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; + } + } + else { + if (this._stack) { + this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; + } + } + return [nvals, nseries]; + }; + + $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) { + var i; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy, nvals, nseries, pos; + + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + pos = temp[2]; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); + var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); + var negativeColor = negativeColors.get(this.index); + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var positiveColor = opts.fillStyle; + + if (this.barDirection == 'vertical') { + for (var i=0; i 0 && i < this.gridData.length-1) { + ystart = this.gridData[i-1][1]; + } + else { + ystart = ctx.canvas.height; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + else { + opts.fillStyle = negativeColor; + } + } + else { + if (this.varyBarColor) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + points.push([base-this.barWidth/2, ystart]); + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, ystart]); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + + else if (this.barDirection == 'horizontal'){ + for (var i=0; i 0 && i < this.gridData.length-1) { + xstart = this.gridData[i-1][1]; + } + else { + xstart = 0; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + } + else { + if (this.varyBarColor) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + points.push([xstart, base+this.barWidth/2]); + points.push([gridData[i][0], base+this.barWidth/2]); + points.push([gridData[i][0], base-this.barWidth/2]); + points.push([xstart, base-this.barWidth/2]); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + } + + }; + + + // for stacked plots, shadows will be pre drawn by drawShadow. + $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options) { + var i; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy, nvals, nseries, pos; + + if (this._stack && this.shadow) { + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + pos = temp[2]; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + + if (this.barDirection == 'vertical') { + for (var i=0; i0){this.data[d][j]+=this.data[d-1][j]}}this.data[this.data.length]=(j==1)?[this.data.length+1,e]:[e,this.data.length+1];this._data[this._data.length]=(j==1)?[this._data.length+1,e]:[e,this._data.length+1]}}b.jqplot.preSeriesInitHooks.push(a);b.jqplot.BarRenderer.prototype.calcSeriesNumbers=function(){var g=0;var h=0;var f=this[this._primaryAxis];var e,d,j;for(var c=0;c0&&u0&&u 528 || (p[0] == 528 && p[1] >= 16)) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + } + else if ($.browser.mozilla) { + var p = $.browser.version.split("."); + if (p[0] > 1 || (p[0] == 1 && p[1] >= 9 && p[2] > 0) ) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + + // TODO: test and enable this + // else if ($.browser.msie) { + // this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + // } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisLabelRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisLabelRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx) { + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + var domelem = document.createElement('canvas'); + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + domelem.width = w; + domelem.height = h; + domelem.style.width = w; + domelem.style.height = h; + // domelem.style.textAlign = 'center'; + domelem.style.position = 'absolute'; + this._domelem = domelem; + this._elem = $(domelem); + this._elem.addClass('jqplot-'+this.axis+'-label'); + + return this._elem; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() { + if ($.browser.msie) { + window.G_vmlCanvasManager.init_(document); + this._domelem = window.G_vmlCanvasManager.initElement(this._domelem); + } + var ctx = this._elem.get(0).getContext("2d"); + this._textRenderer.draw(ctx, this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js new file mode 100644 index 0000000000..95ecfdd758 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisLabelRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=false;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var e={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){e.pt2px=this.pt2px}if(this.enableFontSupport){if(a.browser.safari){var d=a.browser.version.split(".");for(var c=0;c528||(d[0]==528&&d[1]>=16)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}}else{if(a.browser.mozilla){var d=a.browser.version.split(".");if(d[0]>1||(d[0]==1&&d[1]>=9&&d[2]>0)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c){var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.addClass("jqplot-"+this.axis+"-label");return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){if(a.browser.msie){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js new file mode 100644 index 0000000000..77d97f8c01 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.js @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + /** + * Class: $.jqplot.CanvasAxisTickRenderer + * Renderer to draw axis ticks with a canvas element to support advanced + * featrues such as rotated text. This renderer uses a separate rendering engine + * to draw the text on the canvas. Two modes of rendering the text are available. + * If the browser has native font support for canvas fonts (currently Mozila 3.5 + * and Safari 4), you can enable text rendering with the canvas fillText method. + * You do so by setting the "enableFontSupport" option to true. + * + * Browsers lacking native font support will have the text drawn on the canvas + * using the Hershey font metrics. Even if the "enableFontSupport" option is true + * non-supporting browsers will still render with the Hershey font. + */ + $.jqplot.CanvasAxisTickRenderer = function(options) { + // Group: Properties + + // prop: mark + // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. + this.mark = 'outside'; + // prop: showMark + // wether or not to show the mark on the axis. + this.showMark = true; + // prop: showGridline + // wether or not to draw the gridline on the grid at this tick. + this.showGridline = true; + // prop: isMinorTick + // if this is a minor tick. + this.isMinorTick = false; + // prop: angle + // angle of text, measured clockwise from x axis. + this.angle = 0; + // prop: markSize + // Length of the tick marks in pixels. For 'cross' style, length + // will be stoked above and below axis, so total length will be twice this. + this.markSize = 4; + // prop: show + // wether or not to show the tick (mark and label). + this.show = true; + // prop: showLabel + // wether or not to show the label. + this.showLabel = true; + // prop: labelPosition + // 'auto', 'start', 'middle' or 'end'. + // Whether tick label should be positioned so the start, middle, or end + // of the tick mark. + this.labelPosition = 'auto'; + this.label = ''; + this.value = null; + this._styles = {}; + // prop: formatter + // A class of a formatter for the tick text. + // The default $.jqplot.DefaultTickFormatter uses sprintf. + this.formatter = $.jqplot.DefaultTickFormatter; + // prop: formatString + // string passed to the formatter. + this.formatString = ''; + // prop: fontFamily + // css spec for the font-family css attribute. + this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; + // prop: fontSize + // CSS spec for font size. + this.fontSize = '11px'; + // prop: fontWeight + // CSS spec for fontWeight + this.fontWeight = 'normal'; + // prop: fontStretch + // Multiplier to condense or expand font width. + // Applies only to browsers which don't support canvas native font rendering. + this.fontStretch = 1.0; + // prop: textColor + // css spec for the color attribute. + this.textColor = '#666666'; + // prop: enableFontSupport + // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. + // If true, tick label will be drawn with canvas tag native support for fonts. + // If false, tick label will be drawn with Hershey font metrics. + this.enableFontSupport = false; + // prop: pt2px + // Point to pixel scaling factor, used for computing height of bounding box + // around a label. The labels text renderer has a default setting of 1.4, which + // should be suitable for most fonts. Leave as null to use default. If tops of + // letters appear clipped, increase this. If bounding box seems too big, decrease. + // This is an issue only with the native font renderering capabilities of Mozilla + // 3.5 and Safari 4 since they do not provide a method to determine the font height. + this.pt2px = null; + + this._elem; + this._ctx; + this._plotWidth; + this._plotHeight; + this._plotDimensions = {height:null, width:null}; + + $.extend(true, this, options); + + var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; + if (this.pt2px) { + ropts.pt2px = this.pt2px; + } + + if (this.enableFontSupport) { + if ($.browser.safari) { + var p = $.browser.version.split('.'); + for (var i=0; i 528 || (p[0] == 528 && p[1] >= 16)) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + } + else if ($.browser.mozilla) { + var p = $.browser.version.split("."); + if (p[0] > 1 || (p[0] == 1 && p[1] >= 9 && p[2] > 0) ) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + + // TODO: test and enable this + // else if ($.browser.msie) { + // this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + // } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + + $.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { + this.value = value; + if (isMinor) { + this.isMinorTick = true; + } + return this; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx) { + if (!this.label) { + this.label = this.formatter(this.formatString, this.value); + } + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + var domelem = document.createElement('canvas'); + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + domelem.width = w; + domelem.height = h; + domelem.style.width = w; + domelem.style.height = h; + domelem.style.textAlign = 'left'; + domelem.style.position = 'absolute'; + this._domelem = domelem; + this._elem = $(domelem); + this._elem.css(this._styles); + this._elem.addClass('jqplot-'+this.axis+'-tick'); + + return this._elem; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.pack = function() { + if ($.browser.msie) { + window.G_vmlCanvasManager.init_(document); + this._domelem = window.G_vmlCanvasManager.initElement(this._domelem); + } + var ctx = this._elem.get(0).getContext("2d"); + this._textRenderer.draw(ctx, this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js new file mode 100644 index 0000000000..941fed2557 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasAxisTickRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11px";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=false;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var e={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){e.pt2px=this.pt2px}if(this.enableFontSupport){if(a.browser.safari){var d=a.browser.version.split(".");for(var c=0;c528||(d[0]==528&&d[1]>=16)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}}else{if(a.browser.mozilla){var d=a.browser.version.split(".");if(d[0]>1||(d[0]==1&&d[1]>=9&&d[2]>0)){this._textRenderer=new a.jqplot.CanvasFontRenderer(e)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(e)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c){if(!this.label){this.label=this.formatter(this.formatString,this.value)}var e=document.createElement("canvas");this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";this._domelem=e;this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){if(a.browser.msie){window.G_vmlCanvasManager.init_(document);this._domelem=window.G_vmlCanvasManager.initElement(this._domelem)}var b=this._elem.get(0).getContext("2d");this._textRenderer.draw(b,this.label)}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js new file mode 100644 index 0000000000..8536efb2b3 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.js @@ -0,0 +1,408 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + // This code is a modified version of the canvastext.js code, copyright below: + // + // This code is released to the public domain by Jim Studt, 2007. + // He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ + // + $.jqplot.CanvasTextRenderer = function(options){ + this.fontStyle = 'normal'; // normal, italic, oblique [not implemented] + this.fontVariant = 'normal'; // normal, small caps [not implemented] + this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900 + this.fontSize = '10px'; + this.fontFamily = 'sans-serif'; + this.fontStretch = 1.0; + this.fillStyle = '#666666'; + this.angle = 0; + this.textAlign = 'start'; + this.textBaseline = 'alphabetic'; + this.text; + this.width; + this.height; + this.pt2px = 1.28; + + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + $.jqplot.CanvasTextRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + // convert css spec into point size + // returns float + $.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) { + sz = String(sz); + n = parseFloat(sz); + if (sz.indexOf('px') > -1) { + return n/this.pt2px; + } + else if (sz.indexOf('pt') > -1) { + return n; + } + else if (sz.indexOf('em') > -1) { + return n*12; + } + else if (sz.indexOf('%') > -1) { + return n*12/100; + } + // default to pixels; + else { + return n/this.pt2px; + } + }; + + + $.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) { + // w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 + // return values adjusted for Hershey font. + if (Number(w)) { + return w/400; + } + else { + switch (w) { + case 'normal': + return 1; + break; + case 'bold': + return 1.75; + break; + case 'bolder': + return 2.25; + break; + case 'lighter': + return 0.75; + break; + default: + return 1; + break; + } + } + }; + + $.jqplot.CanvasTextRenderer.prototype.getText = function() { + return this.text; + }; + + $.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) { + this.text = t; + this.setWidth(ctx); + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) { + return this.width; + }; + + $.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) { + if (!w) { + this.width = this.measure(ctx, this.text); + } + else { + this.width = w; + } + return this; + }; + + // return height in pixels. + $.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) { + return this.height; + }; + + // w - height in pt + // set heigh in px + $.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) { + if (!w) { + //height = this.fontSize /0.75; + this.height = this.normalizedFontSize * this.pt2px; + } + else { + this.height = w; + } + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.letter = function (ch) + { + return this.letters[ch]; + }; + + $.jqplot.CanvasTextRenderer.prototype.ascent = function() + { + return this.normalizedFontSize; + }; + + $.jqplot.CanvasTextRenderer.prototype.descent = function() + { + return 7.0*this.normalizedFontSize/25.0; + }; + + $.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str) + { + var total = 0; + var len = str.length; + + for ( i = 0; i < len; i++) { + var c = this.letter(str.charAt(i)); + if (c) { + total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch; + } + } + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + var total = 0; + var len = str.length; + var mag = this.normalizedFontSize / 25.0; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.lineCap = "round"; + // multiplier was 2.0 + var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20; + ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight); + + for ( var i = 0; i < len; i++) { + var c = this.letter( str.charAt(i)); + if ( !c) { + continue; + } + + ctx.beginPath(); + + var penUp = 1; + var needStroke = 0; + for ( var j = 0; j < c.points.length; j++) { + var a = c.points[j]; + if ( a[0] == -1 && a[1] == -1) { + penUp = 1; + continue; + } + if ( penUp) { + ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + penUp = false; + } else { + ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + } + } + ctx.stroke(); + x += c.width*mag*this.fontStretch; + } + ctx.restore(); + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.letters = { + ' ': { width: 16, points: [] }, + '!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] }, + '#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] }, + '$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + '%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, + '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, + '\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, + '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, + ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, + '*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] }, + '+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] }, + ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '-': { width: 18, points: [[6,9],[12,9]] }, + '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '/': { width: 22, points: [[20,25],[2,-7]] }, + '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, + '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, + '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, + '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] }, + '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, + '7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] }, + '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, + '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, + ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, + '=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] }, + '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, + '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] }, + '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] }, + 'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] }, + 'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, + 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, + 'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, + 'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] }, + 'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] }, + 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] }, + 'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] }, + 'I': { width: 8, points: [[4,21],[4,0]] }, + 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, + 'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] }, + 'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] }, + 'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] }, + 'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] }, + 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, + 'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, + 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] }, + 'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] }, + 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + 'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] }, + 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, + 'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] }, + 'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] }, + 'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] }, + 'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] }, + 'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] }, + '[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] }, + '\\': { width: 14, points: [[0,21],[14,-3]] }, + ']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] }, + '^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] }, + '_': { width: 16, points: [[0,-2],[16,-2]] }, + '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, + 'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] }, + 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] }, + 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, + 'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] }, + 'l': { width: 8, points: [[4,21],[4,0]] }, + 'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, + 'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, + 'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] }, + 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, + 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] }, + 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] }, + 'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] }, + 'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] }, + 'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] }, + 'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, + 'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] }, + '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, + '|': { width: 8, points: [[4,25],[4,-7]] }, + '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, + '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] } + }; + + $.jqplot.CanvasFontRenderer = function(options) { + options = options || {}; + if (!options.pt2px) { + options.pt2px = 1.5; + } + $.jqplot.CanvasTextRenderer.call(this, options); + }; + + $.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({}); + $.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer; + + $.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str) + { + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.save(); + ctx.font = fstyle; + var w = ctx.measureText(str).width; + ctx.restore(); + return w; + }; + + $.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + //var y = 12; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.font = fstyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.fillText(str, x, y); + // ctx.strokeText(str, x, y); + + ctx.restore(); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js new file mode 100644 index 0000000000..0dbb8a61ac --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.canvasTextRenderer.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);n=parseFloat(b);if(b.indexOf("px")>-1){return n/this.pt2px}else{if(b.indexOf("pt")>-1){return n}else{if(b.indexOf("em")>-1){return n*12}else{if(b.indexOf("%")>-1){return n*12/100}else{return n/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,f){var e=0;var b=f.length;for(i=0;i30)?2:2+(30-this.normalizedFontSize)/20;t.lineWidth=u*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0 class. + * + * To use this renderer, include the plugin in your source + * > + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}} + **/ + $.jqplot.CategoryAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer; + + $.jqplot.CategoryAxisRenderer.prototype.init = function(options){ + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + $.extend(true, this, {tickOptions:{formatString:'%d'}}, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + }; + + + $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var tt, i; + + // if we already have ticks, use them. + if (userTicks.length) { + this.min = 0.5; + this.max = userTicks.length + 0.5; + var range = this.max - this.min; + this.numberTicks = 2*userTicks.length + 1; + for (i=0; i0 && trackb.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]b.max||b.max==null){b.max=h[c][1]}}}}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var y=this._ticks;var v=this.ticks;var B=this.name;var x=this._dataBounds;var p,w;var n,q;var d,c;var b,r;if(v.length){this.min=0.5;this.max=v.length+0.5;var h=this.max-this.min;this.numberTicks=2*v.length+1;for(r=0;r0&&l= 1 or will often miss point intersections. + this.intersectionThreshold = 2; + // prop: showCursorLegend + // Replace the plot legend with an enhanced legend displaying intersection information. + this.showCursorLegend = false; + // prop: cursorLegendFormatString + // Format string used in the cursor legend. If showTooltipDataPosition is true, + // this will also be the default format string used by tooltipFormatString. + this.cursorLegendFormatString = $.jqplot.Cursor.cursorLegendFormatString; + $.extend(true, this, options); + }; + + $.jqplot.Cursor.cursorLegendFormatString = '%s x:%s, y:%s'; + + // called with scope of plot + $.jqplot.Cursor.init = function (target, data, opts){ + // add a cursor attribute to the plot + var options = opts || {}; + this.plugins.cursor = new $.jqplot.Cursor(options.cursor); + var c = this.plugins.cursor; + + if (c.show) { + $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter]); + $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave]); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove]); + + if (c.showCursorLegend) { + opts.legend = opts.legend || {}; + opts.legend.renderer = $.jqplot.CursorLegendRenderer; + opts.legend.formatString = this.plugins.cursor.cursorLegendFormatString; + opts.legend.show = true; + } + + if (c.zoom) { + $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown]); + $.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleMouseUp]); + + if (c.clickReset) { + $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick]); + } + + if (c.dblClickReset) { + $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick]); + } + } + + this.resetZoom = function() { + var axes = this.axes; + if (!c.zoomProxy) { + for (var ax in axes) { + axes[ax].reset(); + } + this.redraw(); + } + else { + var ctx = this.plugins.cursor.zoomCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + } + this.plugins.cursor._zoom.isZoomed = false; + this.target.trigger('jqplotResetZoom', [this, this.plugins.cursor]); + }; + + + if (c.showTooltipDataPosition) { + c.showTooltipUnitPosition = false; + c.showTooltipGridPosition = false; + if (options.cursor.tooltipFormatString == undefined) { + c.tooltipFormatString = $.jqplot.Cursor.cursorLegendFormatString; + } + } + } + }; + + // called with context of plot + $.jqplot.Cursor.postDraw = function() { + var c = this.plugins.cursor; + // if (c.zoom) { + c.zoomCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions)); + var zctx = c.zoomCanvas.setContext(); + // } + c._tooltipElem = $(''); + c.zoomCanvas._elem.before(c._tooltipElem); + if (c.showVerticalLine || c.showHorizontalLine) { + c.cursorCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions)); + var zctx = c.cursorCanvas.setContext(); + } + + // if we are showing the positions in unit coordinates, and no axes groups + // were specified, create a default set. + if (c.showTooltipUnitPosition){ + if (c.tooltipAxisGroups.length === 0) { + var series = this.series; + var s; + var temp = []; + for (var i=0; i 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) || (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) { + if (!plot.plugins.cursor.zoomProxy) { + for (var ax in datapos) { + // make a copy of the original axes to revert back. + if (c._zoom.axes[ax] == undefined) { + c._zoom.axes[ax] = {}; + c._zoom.axes[ax].numberTicks = axes[ax].numberTicks; + c._zoom.axes[ax].tickInterval = axes[ax].tickInterval; + // for date axes... + c._zoom.axes[ax].daTickInterval = axes[ax].daTickInterval; + c._zoom.axes[ax].min = axes[ax].min; + c._zoom.axes[ax].max = axes[ax].max; + } + if ((c.constrainZoomTo == 'none') || (c.constrainZoomTo == 'x' && ax.charAt(0) == 'x') || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'y')) { + dp = datapos[ax]; + if (dp != null) { + if (dp > start[ax]) { + axes[ax].min = start[ax]; + axes[ax].max = dp; + } + else { + span = start[ax] - dp; + axes[ax].max = start[ax]; + axes[ax].min = dp; + } + axes[ax].tickInterval = null; + // for date axes... + axes[ax].daTickInterval = null; + axes[ax]._ticks = []; + } + } + + // if ((c.constrainZoomTo == 'x' && ax.charAt(0) == 'y' && c.autoscaleConstraint) || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'x' && c.autoscaleConstraint)) { + // dp = datapos[ax]; + // if (dp != null) { + // axes[ax].max == null; + // axes[ax].min = null; + // } + // } + } + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + plot.redraw(); + c._zoom.isZoomed = true; + } + plot.target.trigger('jqplotZoom', [gridpos, datapos, plot, cursor]); + } + }; + + $.jqplot.preInitHooks.push($.jqplot.Cursor.init); + $.jqplot.postDrawHooks.push($.jqplot.Cursor.postDraw); + + function updateTooltip(gridpos, datapos, plot) { + var c = plot.plugins.cursor; + var s = ''; + var addbr = false; + if (c.showTooltipGridPosition) { + s = gridpos.x+', '+gridpos.y; + addbr = true; + } + if (c.showTooltipUnitPosition) { + var g; + for (var i=0; i start[0]) { + l = start[0]; + w = end[0] - start[0]; + } + else { + l = end[0]; + w = start[0] - end[0]; + } + if (end[1] > start[1]) { + t = start[1]; + h = end[1] - start[1]; + } + else { + t = end[1]; + h = start[1] - end[1]; + } + ctx.fillStyle = 'rgba(0,0,0,0.2)'; + ctx.strokeStyle = '#999999'; + ctx.lineWidth = 1.0; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.clearRect(l, t, w, h); + // IE won't show transparent fill rect, so stroke a rect also. + ctx.strokeRect(l,t,w,h); + } + + $.jqplot.CursorLegendRenderer = function(options) { + $.jqplot.TableLegendRenderer.call(this, options); + this.formatString = '%s'; + }; + + $.jqplot.CursorLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.CursorLegendRenderer.prototype.constructor = $.jqplot.CursorLegendRenderer; + + // called in context of a Legend + $.jqplot.CursorLegendRenderer.prototype.draw = function() { + if (this.show) { + var series = this._series; + // make a table. one line label per row. + this._elem = $('
    '); + + var pad = false; + for (var i = 0; i< series.length; i++) { + s = series[i]; + if (s.show) { + var lt = $.jqplot.sprintf(this.formatString, s.label.toString()); + if (lt) { + var color = s.color; + if (s._stack && !s.fill) { + color = ''; + } + addrow.call(this, lt, color, pad, i); + pad = true; + } + // let plugins add more rows to legend. Used by trend line plugin. + for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { + var item = $.jqplot.addLegendRowHooks[j].call(this, s); + if (item) { + addrow.call(this, item.label, item.color, pad); + pad = true; + } + } + } + } + } + + function addrow(label, color, pad, idx) { + var rs = (pad) ? this.rowSpacing : '0'; + var tr = $('').appendTo(this._elem); + tr.data('seriesIndex', idx); + $(''+ + '
    '+ + '
    '+ + '
    ').appendTo(tr); + var td = $(''); + td.appendTo(tr); + td.data('seriesIndex', idx); + if (this.escapeHtml) { + td.text(label); + } + else { + td.html(label); + } + } + return this._elem; + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.cursor.min.js b/js/jquery/jqplot-plugins/jqplot.cursor.min.js new file mode 100644 index 0000000000..3ce2ea5466 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.cursor.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(i){i.jqplot.Cursor=function(o){this.style="crosshair";this.previousCursor="auto";this.show=i.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.clickReset=false;this.dblClickReset=true;this.showVerticalLine=false;this.showHorizontalLine=false;this.constrainZoomTo="none";this.shapeRenderer=new i.jqplot.ShapeRenderer();this._zoom={start:[],end:[],started:false,zooming:false,isZoomed:false,axes:{start:{},end:{}}};this._tooltipElem;this.zoomCanvas;this.cursorCanvas;this.intersectionThreshold=2;this.showCursorLegend=false;this.cursorLegendFormatString=i.jqplot.Cursor.cursorLegendFormatString;i.extend(true,this,o)};i.jqplot.Cursor.cursorLegendFormatString="%s x:%s, y:%s";i.jqplot.Cursor.init=function(t,r,q){var o=q||{};this.plugins.cursor=new i.jqplot.Cursor(o.cursor);var u=this.plugins.cursor;if(u.show){i.jqplot.eventListenerHooks.push(["jqplotMouseEnter",b]);i.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);i.jqplot.eventListenerHooks.push(["jqplotMouseMove",h]);if(u.showCursorLegend){q.legend=q.legend||{};q.legend.renderer=i.jqplot.CursorLegendRenderer;q.legend.formatString=this.plugins.cursor.cursorLegendFormatString;q.legend.show=true}if(u.zoom){i.jqplot.eventListenerHooks.push(["jqplotMouseDown",a]);i.jqplot.eventListenerHooks.push(["jqplotMouseUp",n]);if(u.clickReset){i.jqplot.eventListenerHooks.push(["jqplotClick",j])}if(u.dblClickReset){i.jqplot.eventListenerHooks.push(["jqplotDblClick",c])}}this.resetZoom=function(){var x=this.axes;if(!u.zoomProxy){for(var w in x){x[w].reset()}this.redraw()}else{var v=this.plugins.cursor.zoomCanvas._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height)}this.plugins.cursor._zoom.isZoomed=false;this.target.trigger("jqplotResetZoom",[this,this.plugins.cursor])};if(u.showTooltipDataPosition){u.showTooltipUnitPosition=false;u.showTooltipGridPosition=false;if(o.cursor.tooltipFormatString==undefined){u.tooltipFormatString=i.jqplot.Cursor.cursorLegendFormatString}}}};i.jqplot.Cursor.postDraw=function(){var w=this.plugins.cursor;w.zoomCanvas=new i.jqplot.GenericCanvas();this.eventCanvas._elem.before(w.zoomCanvas.createElement(this._gridPadding,"jqplot-zoom-canvas",this._plotDimensions));var v=w.zoomCanvas.setContext();w._tooltipElem=i('');w.zoomCanvas._elem.before(w._tooltipElem);if(w.showVerticalLine||w.showHorizontalLine){w.cursorCanvas=new i.jqplot.GenericCanvas();this.eventCanvas._elem.before(w.cursorCanvas.createElement(this._gridPadding,"jqplot-cursor-canvas",this._plotDimensions));var v=w.cursorCanvas.setContext()}if(w.showTooltipUnitPosition){if(w.tooltipAxisGroups.length===0){var r=this.series;var t;var o=[];for(var q=0;q6&&Math.abs(w.y-z._zoom.start[1])>6)||(z.constrainZoomTo=="x"&&Math.abs(w.x-z._zoom.start[0])>6)||(z.constrainZoomTo=="y"&&Math.abs(w.y-z._zoom.start[1])>6)){if(!x.plugins.cursor.zoomProxy){for(var o in t){if(z._zoom.axes[o]==undefined){z._zoom.axes[o]={};z._zoom.axes[o].numberTicks=y[o].numberTicks;z._zoom.axes[o].tickInterval=y[o].tickInterval;z._zoom.axes[o].daTickInterval=y[o].daTickInterval;z._zoom.axes[o].min=y[o].min;z._zoom.axes[o].max=y[o].max}if((z.constrainZoomTo=="none")||(z.constrainZoomTo=="x"&&o.charAt(0)=="x")||(z.constrainZoomTo=="y"&&o.charAt(0)=="y")){dp=t[o];if(dp!=null){if(dp>r[o]){y[o].min=r[o];y[o].max=dp}else{span=r[o]-dp;y[o].max=r[o];y[o].min=dp}y[o].tickInterval=null;y[o].daTickInterval=null;y[o]._ticks=[]}}}C.clearRect(0,0,C.canvas.width,C.canvas.height);x.redraw();z._zoom.isZoomed=true}x.target.trigger("jqplotZoom",[w,t,x,B])}};i.jqplot.preInitHooks.push(i.jqplot.Cursor.init);i.jqplot.postDrawHooks.push(i.jqplot.Cursor.postDraw);function e(D,q,A){var F=A.plugins.cursor;var v="";var J=false;if(F.showTooltipGridPosition){v=D.x+", "+D.y;J=true}if(F.showTooltipUnitPosition){var C;for(var B=0;B"}if(F.useAxesFormatters){var z=A.axes[C[0]]._ticks[0].formatter;var o=A.axes[C[1]]._ticks[0].formatter;var G=A.axes[C[0]]._ticks[0].formatString;var u=A.axes[C[1]]._ticks[0].formatString;v+=z(G,q[C[0]])+", "+o(u,q[C[1]])}else{v+=i.jqplot.sprintf(F.tooltipFormatString,q[C[0]],q[C[1]])}J=true}}if(F.showTooltipDataPosition){var t=A.series;var I=d(A,D.x,D.y);var J=false;for(var B=0;B"}v+=i.jqplot.sprintf(F.tooltipFormatString,r,y,w);J=true}}}}F._tooltipElem.html(v)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var q=i(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;By[0]){q=y[0];o=u[0]-y[0]}else{q=u[0];o=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}r.fillStyle="rgba(0,0,0,0.2)";r.strokeStyle="#999999";r.lineWidth=1;r.clearRect(0,0,r.canvas.width,r.canvas.height);r.fillRect(0,0,r.canvas.width,r.canvas.height);r.clearRect(q,v,o,x);r.strokeRect(q,v,o,x)}i.jqplot.CursorLegendRenderer=function(o){i.jqplot.TableLegendRenderer.call(this,o);this.formatString="%s"};i.jqplot.CursorLegendRenderer.prototype=new i.jqplot.TableLegendRenderer();i.jqplot.CursorLegendRenderer.prototype.constructor=i.jqplot.CursorLegendRenderer;i.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this.show){var u=this._series;this._elem=i('
    ');var x=false;for(var t=0;t').appendTo(this._elem);C.data("seriesIndex",y);i('
    ').appendTo(C);var E=i('');E.appendTo(C);E.data("seriesIndex",y);if(this.escapeHtml){E.text(B)}else{E.html(B)}}return this._elem}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js b/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js new file mode 100644 index 0000000000..e46bc5b76c --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.dateAxisRenderer.js @@ -0,0 +1,313 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + /** + * Class: $.jqplot.DateAxisRenderer + * A plugin for a jqPlot to render an axis as a series of date values. + * This renderer has no options beyond those supplied by the class. + * It supplies it's own tick formatter, so the tickOptions.formatter option + * should not be overridden. + * + * Thanks to Ken Synder for his enhanced Date instance methods which are + * included with this code . + * + * To use this renderer, include the plugin in your source + * > + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}} + * + * Dates can be passed into the axis in almost any recognizable value and + * will be parsed. They will be rendered on the axis in the format + * specified by tickOptions.formatString. e.g. tickOptions.formatString = '%Y-%m-%d'. + * + * Accecptable format codes + * are: + * + * > Code Result Description + * > == Years == + * > %Y 2008 Four-digit year + * > %y 08 Two-digit year + * > == Months == + * > %m 09 Two-digit month + * > %#m 9 One or two-digit month + * > %B September Full month name + * > %b Sep Abbreviated month name + * > == Days == + * > %d 05 Two-digit day of month + * > %#d 5 One or two-digit day of month + * > %e 5 One or two-digit day of month + * > %A Sunday Full name of the day of the week + * > %a Sun Abbreviated name of the day of the week + * > %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) + * > %o th The ordinal suffix string following the day of the month + * > == Hours == + * > %H 23 Hours in 24-hour format (two digits) + * > %#H 3 Hours in 24-hour integer format (one or two digits) + * > %I 11 Hours in 12-hour format (two digits) + * > %#I 3 Hours in 12-hour integer format (one or two digits) + * > %p PM AM or PM + * > == Minutes == + * > %M 09 Minutes (two digits) + * > %#M 9 Minutes (one or two digits) + * > == Seconds == + * > %S 02 Seconds (two digits) + * > %#S 2 Seconds (one or two digits) + * > %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) + * > == Milliseconds == + * > %N 008 Milliseconds (three digits) + * > %#N 8 Milliseconds (one to three digits) + * > == Timezone == + * > %O 360 difference in minutes between local time and GMT + * > %Z Mountain Standard Time Name of timezone as reported by browser + * > %G -06:00 Hours and minutes between GMT + * > == Shortcuts == + * > %F 2008-03-26 %Y-%m-%d + * > %T 05:06:30 %H:%M:%S + * > %X 05:06:30 %H:%M:%S + * > %x 03/26/08 %m/%d/%y + * > %D 03/26/08 %m/%d/%y + * > %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y + * > %v 3-Sep-2008 %e-%b-%Y + * > %R 15:31 %H:%M + * > %r 3:31:00 PM %I:%M:%S %p + * > == Characters == + * > %n \n Newline + * > %t \t Tab + * > %% % Percent Symbol + */ + $.jqplot.DateAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.DateAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.DateAxisRenderer.prototype.constructor = $.jqplot.DateAxisRenderer; + + $.jqplot.DateTickFormatter = function(format, val) { + if (!format) { + format = '%Y/%m/%d'; + } + return Date.create(val).strftime(format); + }; + + $.jqplot.DateAxisRenderer.prototype.init = function(options){ + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + this.tickOptions.formatter = $.jqplot.DateTickFormatter; + this.daTickInterval = null; + this._daTickInterval = null; + $.extend(true, this, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + d[j][1] = Date.create(d[j][1]).getTime(); + pd[j][1] = Date.create(d[j][1]).getTime(); + sd[j][1] = Date.create(d[j][1]).getTime(); + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + }; + + // called with scope of an axis + $.jqplot.DateAxisRenderer.prototype.reset = function() { + this.min = this._min; + this.max = this._max; + this.tickInterval = this._tickInterval; + this.numberTicks = this._numberTicks; + this.daTickInterval = this._daTickInterval; + // this._ticks = this.__ticks; + }; + + $.jqplot.DateAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var tt, i; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i 200) { + this.numberTicks = parseInt(3+(dim-200)/100, 10); + } + else { + this.numberTicks = 2; + } + } + + if (this.daTickInterval == null) { + this.daTickInterval = [range / (this.numberTicks-1)/1000, 'seconds']; + } + for (var i=0; ic.max||c.max==null){c.max=l[e][0]}}else{l[e][1]=Date.create(l[e][1]).getTime();b[e][1]=Date.create(l[e][1]).getTime();k[e][1]=Date.create(l[e][1]).getTime();if(l[e][1]c.max||c.max==null){c.max=l[e][1]}}}}};a.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks;this.daTickInterval=this._daTickInterval};a.jqplot.DateAxisRenderer.prototype.createTicks=function(){var v=this._ticks;var r=this.ticks;var w=this.name;var u=this._dataBounds;var o,s;var m,p;var d,c;var b,q;if(r.length){for(q=0;q200){this.numberTicks=parseInt(3+(o-200)/100,10)}else{this.numberTicks=2}}}if(this.daTickInterval==null){this.daTickInterval=[j/(this.numberTicks-1)/1000,"seconds"]}for(var q=0;q= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + drag.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + } + mr.color = drag.color; + mr.init(); + + var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0; + var end = neighbor.pointIndex+2; + drag._gridData = s.gridData.slice(start, end); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + var gd = s.gridData; + + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x; + var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y; + + // compute data values for any listeners. + var xu = s._xaxis.series_p2u(x); + var yu = s._yaxis.series_p2u(y); + + // clear the canvas then redraw effect at new position. + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + + // adjust our gridData for the new mouse position + if (dp.pointIndex > 0) { + drag._gridData[1] = [x, y]; + } + else { + drag._gridData[0] = [x, y]; + } + plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color, markerOptions:{color:drag.color, shadow:false}, trendline:{show:false}}); + plot.target.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]); + } + else if (neighbor != null) { + var series = plot.series[neighbor.seriesIndex]; + if (series.isDragable) { + var dc = plot.plugins.dragable.dragCanvas; + if (!dc.isOver) { + dc._cursors.push(ev.target.style.cursor); + ev.target.style.cursor = "pointer"; + } + dc.isOver = true; + } + } + else if (neighbor == null) { + var dc = plot.plugins.dragable.dragCanvas; + if (dc.isOver) { + ev.target.style.cursor = dc._cursors.pop(); + dc.isOver = false; + } + } + } + + function handleDown(ev, gridpos, datapos, neighbor, plot) { + var dc = plot.plugins.dragable.dragCanvas; + dc._cursors.push(ev.target.style.cursor); + if (neighbor != null) { + var s = plot.series[neighbor.seriesIndex]; + var drag = s.plugins.dragable; + if (s.isDragable && !dc.isDragging) { + dc._neighbor = neighbor; + dc.isDragging = true; + initDragPoint(plot, neighbor); + drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx); + ev.target.style.cursor = "move"; + } + } + // Just in case of a hickup, we'll clear the drag canvas and reset. + else { + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + } + } + + function handleUp(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + // clear the canvas + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + // redraw the series canvas at the new point. + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis]; + var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis]; + // var x = datapos[s.xaxis]; + // var y = datapos[s.yaxis]; + s.data[dp.pointIndex] = [x,y]; + plot.drawSeries({preventJqPlotSeriesDrawTrigger:true}, dp.seriesIndex); + dc._neighbor = null; + ev.target.style.cursor = dc._cursors.pop(); + } + } +})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.dragable.min.js b/js/jquery/jqplot-plugins/jqplot.dragable.min.js new file mode 100644 index 0000000000..dd13ec3af5 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.dragable.min.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + */ +(function(d){d.jqplot.Dragable=function(g){this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.shapeRenderer=new d.jqplot.ShapeRenderer();this.isDragging=false;this.isOver=false;this._ctx;this._elem;this._point;this._gridData;this.color;this.constrainTo="none";d.extend(true,this,g)};function b(){d.jqplot.GenericCanvas.call(this);this.isDragging=false;this.isOver=false;this._neighbor;this._cursors=[]}b.prototype=new d.jqplot.GenericCanvas();b.prototype.constructor=b;d.jqplot.Dragable.parseOptions=function(i,h){var g=h||{};this.plugins.dragable=new d.jqplot.Dragable(g.dragable);this.isDragable=d.jqplot.config.enablePlugins};d.jqplot.Dragable.postPlotDraw=function(){this.plugins.dragable={previousCursor:"auto",isOver:false};this.plugins.dragable.dragCanvas=new b();this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding,"jqplot-dragable-canvas",this._plotDimensions));var g=this.plugins.dragable.dragCanvas.setContext()};d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Dragable.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Dragable.postPlotDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",e]);d.jqplot.eventListenerHooks.push(["jqplotMouseDown",c]);d.jqplot.eventListenerHooks.push(["jqplotMouseUp",a]);function f(n,p){var q=n.series[p.seriesIndex];var m=q.plugins.dragable;var h=q.markerRenderer;var i=m.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+2.5;i.size=h.size+5;if(!m.color){var l=d.jqplot.getColorComponents(h.color);var o=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);m.color="rgba("+o[0]+","+o[1]+","+o[2]+","+k+")"}i.color=m.color;i.init();var g=(p.pointIndex>0)?p.pointIndex-1:0;var j=p.pointIndex+2;m._gridData=q.gridData.slice(g,j)}function e(o,l,h,t,m){if(m.plugins.dragable.dragCanvas.isDragging){var u=m.plugins.dragable.dragCanvas;var i=u._neighbor;var w=m.series[i.seriesIndex];var k=w.plugins.dragable;var r=w.gridData;var p=(k.constrainTo=="y")?i.gridData[0]:l.x;var n=(k.constrainTo=="x")?i.gridData[1]:l.y;var g=w._xaxis.series_p2u(p);var q=w._yaxis.series_p2u(n);var v=u._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);if(i.pointIndex>0){k._gridData[1]=[p,n]}else{k._gridData[0]=[p,n]}m.series[i.seriesIndex].draw(u._ctx,{gridData:k._gridData,shadow:false,preventJqPlotSeriesDrawTrigger:true,color:k.color,markerOptions:{color:k.color,shadow:false},trendline:{show:false}});m.target.trigger("jqplotSeriesPointChange",[i.seriesIndex,i.pointIndex,[g,q],[p,n]])}else{if(t!=null){var j=m.series[t.seriesIndex];if(j.isDragable){var u=m.plugins.dragable.dragCanvas;if(!u.isOver){u._cursors.push(o.target.style.cursor);o.target.style.cursor="pointer"}u.isOver=true}}else{if(t==null){var u=m.plugins.dragable.dragCanvas;if(u.isOver){o.target.style.cursor=u._cursors.pop();u.isOver=false}}}}}function c(k,i,g,l,j){var m=j.plugins.dragable.dragCanvas;m._cursors.push(k.target.style.cursor);if(l!=null){var o=j.series[l.seriesIndex];var h=o.plugins.dragable;if(o.isDragable&&!m.isDragging){m._neighbor=l;m.isDragging=true;f(j,l);h.markerRenderer.draw(o.gridData[l.pointIndex][0],o.gridData[l.pointIndex][1],m._ctx);k.target.style.cursor="move"}}else{var n=m._ctx;n.clearRect(0,0,n.canvas.width,n.canvas.height);m.isDragging=false}}function a(m,j,g,o,k){if(k.plugins.dragable.dragCanvas.isDragging){var p=k.plugins.dragable.dragCanvas;var q=p._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);p.isDragging=false;var h=p._neighbor;var r=k.series[h.seriesIndex];var i=r.plugins.dragable;var n=(i.constrainTo=="y")?h.data[0]:g[r.xaxis];var l=(i.constrainTo=="x")?h.data[1]:g[r.yaxis];r.data[h.pointIndex]=[n,l];k.drawSeries({preventJqPlotSeriesDrawTrigger:true},h.seriesIndex);p._neighbor=null;m.target.style.cursor=p._cursors.pop()}}})(jQuery); \ No newline at end of file diff --git a/js/jquery/jqplot-plugins/jqplot.highlighter.js b/js/jquery/jqplot-plugins/jqplot.highlighter.js new file mode 100644 index 0000000000..4e7dca7d72 --- /dev/null +++ b/js/jquery/jqplot-plugins/jqplot.highlighter.js @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2009 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris dot leonello at gmail + * dot com or see http://www.jqplot.com/info.php . This is, of course, + * not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * Thanks for using jqPlot! + * + */ +(function($) { + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + + /** + * Class: $.jqplot.Highlighter + * Plugin which will highlight data points when they are moused over. + * + * To use this plugin, include the js + * file in your source: + * + * > + * + * A tooltip providing information about the data point is enabled by default. + * To disable the tooltip, set "showTooltip" to false. + * + * You can control what data is displayed in the tooltip with various + * options. The "tooltipAxes" option controls wether the x, y or both + * data values are displayed. + * + * Some chart types (e.g. hi-low-close) have more than one y value per + * data point. To display the additional values in the tooltip, set the + * "yvalues" option to the desired number of y values present (3 for a hlc chart). + * + * By default, data values will be formatted with the same formatting + * specifiers as used to format the axis ticks. A custom format code + * can be supplied with the tooltipFormatString option. This will apply + * to all values in the tooltip. + * + * For more complete control, the "formatString" option can be set. This + * Allows conplete control over tooltip formatting. Values are passed to + * the format string in an order determined by the "tooltipAxes" and "yvalues" + * options. So, if you have a hi-low-close chart and you just want to display + * the hi-low-close values in the tooltip, you could set a formatString like: + * + * > highlighter: { + * > tooltipAxes: 'y', + * > yvalues: 3, + * > formatString:' + * > + * > + * >
    hi:%s
    low:%s
    close:%s
    ' + * > } + * + */ + $.jqplot.Highlighter = function(options) { + // Group: Properties + // + //prop: show + // true to show the highlight. + this.show = $.jqplot.config.enablePlugins; + // prop: markerRenderer + // Renderer used to draw the marker of the highlighted point. + // Renderer will assimilate attributes from the data point being highlighted, + // so no attributes need set on the renderer directly. + // Default is to turn off shadow drawing on the highlighted point. + this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false}); + // prop: showMarker + // true to show the marker + this.showMarker = true; + // prop: lineWidthAdjust + // Pixels to add to the lineWidth of the highlight. + this.lineWidthAdjust = 2.5; + // prop: sizeAdjust + // Pixels to add to the overall size of the highlight. + this.sizeAdjust = 5; + // prop: showTooltip + // Show a tooltip with data point values. + this.showTooltip = true; + // prop: tooltipLocation + // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + this.tooltipLocation = 'nw'; + // prop: tooltipFade + // true = fade in/out tooltip, flase = show/hide tooltip + this.fadeTooltip = true; + // prop: tooltipFadeSpeed + // 'slow', 'def', 'fast', or number of milliseconds. + this.tooltipFadeSpeed = "fast"; + // prop: tooltipOffset + // Pixel offset of tooltip from the highlight. + this.tooltipOffset = 2; + // prop: tooltipAxes + // Which axes to display in tooltip, 'x', 'y' or 'both', 'xy' or 'yx' + // 'both' and 'xy' are equivalent, 'yx' reverses order of labels. + this.tooltipAxes = 'both'; + // prop; tooltipSeparator + // String to use to separate x and y axes in tooltip. + this.tooltipSeparator = ', '; + // prop: useAxesFormatters + // Use the x and y axes formatters to format the text in the tooltip. + this.useAxesFormatters = true; + // prop: tooltipFormatString + // sprintf format string for the tooltip. + // Uses Ash Searle's javascript sprintf implementation + // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ + // See http://perldoc.perl.org/functions/sprintf.html for reference. + // Additional "p" and "P" format specifiers added by Chris Leonello. + this.tooltipFormatString = '%.5P'; + // prop: formatString + // alternative to tooltipFormatString + // will format the whole tooltip text, populating with x, y values as + // indicated by tooltipAxes option. So, you could have a tooltip like: + // 'Date: %s, number of cats: %d' to format the whole tooltip at one go. + // If useAxesFormatters is true, values will be formatted according to + // Axes formatters and you can populate your tooltip string with + // %s placeholders. + this.formatString = null; + // prop: yvalues + // Number of y values to expect in the data point array. + // Typically this is 1. Certain plots, like OHLC, will + // have more y values in each data point array. + this.yvalues = 1; + this._tooltipElem; + this.isHighlighting = false; + + $.extend(true, this, options); + }; + + // axis.renderer.tickrenderer.formatter + + // called with scope of plot + $.jqplot.Highlighter.init = function (target, data, opts){ + var options = opts || {}; + // add a highlighter attribute to the plot + this.plugins.highlighter = new $.jqplot.Highlighter(options.highlighter); + }; + + // called within scope of series + $.jqplot.Highlighter.parseOptions = function (defaults, options) { + this.showHighlight = true; + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + $.jqplot.Highlighter.postPlotDraw = function() { + this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions)); + var hctx = this.plugins.highlighter.highlightCanvas.setContext(); + + var p = this.plugins.highlighter; + p._tooltipElem = $(''); + this.target.append(p._tooltipElem); + }; + + $.jqplot.preInitHooks.push($.jqplot.Highlighter.init); + $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Highlighter.parseOptions); + $.jqplot.postDrawHooks.push($.jqplot.Highlighter.postPlotDraw); + + function draw(plot, neighbor) { + var hl = plot.plugins.highlighter; + var s = plot.series[neighbor.seriesIndex]; + var smr = s.markerRenderer; + var mr = hl.markerRenderer; + mr.style = smr.style; + mr.lineWidth = smr.lineWidth + hl.lineWidthAdjust; + mr.size = smr.size + hl.sizeAdjust; + var rgba = $.jqplot.getColorComponents(smr.color); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + mr.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + mr.init(); + mr.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], hl.highlightCanvas._ctx); + } + + function showTooltip(plot, series, neighbor) { + // neighbor looks like: {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]} + // gridData should be x,y pixel coords on the grid. + // add the plot._gridPadding to that to get x,y in the target. + var hl = plot.plugins.highlighter; + var elem = hl._tooltipElem; + if (hl.useAxesFormatters) { + var xf = series._xaxis._ticks[0].formatter; + var yf = series._yaxis._ticks[0].formatter; + var xfstr = series._xaxis._ticks[0].formatString; + var yfstr = series._yaxis._ticks[0].formatString; + var str; + var xstr = xf(xfstr, neighbor.data[0]); + var ystrs = []; + for (var i=1; i